shiro 前后台realm 写法,用于分辨realm

Posted 写代码隔扣邓肯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shiro 前后台realm 写法,用于分辨realm相关的知识,希望对你有一定的参考价值。

首先改写一下  UsernamePasswordToken 这个类

新建一个类,叫UsernamePasswordUsertypeToken,继承UsernamePasswordToken

package hstc.edu.cn.realm;

import org.apache.shiro.authc.UsernamePasswordToken;

/**
 * Created by win8 on 2017/5/29.
 */
public class UsernamePasswordUsertypeToken extends UsernamePasswordToken {

    private static final long serialVersionUID = 1L;
    private String usertype ;

    public String getUsertype() {
        return usertype;
    }
    public void setUsertype(String usertype) {
        this.usertype = usertype;
    }

    public UsernamePasswordUsertypeToken(String loginName, String password, String usertype) {

        super(loginName, password);

        this.usertype = usertype;

    }
}

 

接下来 编写自己的realm

前台是学生用户(studentRealm):

package hstc.edu.cn.realm;


import hstc.edu.cn.po.Student;
import hstc.edu.cn.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;


public class studentRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {

        String studentNum = (String) token.getPrincipal();
        Student student_1= new Student();
        student_1.setStudentNum(Integer.parseInt(studentNum));
        Student student = userService.getStudentByNum(student_1);

        if (student != null) {
            SecurityUtils.getSubject().getSession().setAttribute("student", student);
            AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(
                    student.getStudentNum(), student.getStudentName(), "MyRealm");
            return authcInfo;
        } else {
            return null;
        }

    }

}

后台管理员(dormAdminRealm):

package hstc.edu.cn.realm;

import hstc.edu.cn.po.DormAdmin;
import hstc.edu.cn.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Created by win8 on 2017/5/28.
 */
public class dormAdminRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String dormAdminNum = (String) token.getPrincipal();
        DormAdmin dormAdmin_1= new DormAdmin();
        dormAdmin_1.setDormadminNum(dormAdminNum);
        DormAdmin dormAdmin = userService.getDormAdminByNum(dormAdmin_1);

        if (dormAdmin != null) {
            SecurityUtils.getSubject().getSession().setAttribute("dormAdmin", dormAdmin);
            AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(
                    dormAdmin.getDormadminNum(), dormAdmin.getDormadminPassword(), "MyRealm");
            return authcInfo;
        } else {
            return null;
        }
    }
}

 

然后写总的realm:

package hstc.edu.cn.realm;

import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.util.CollectionUtils;

import java.util.Collection;
import java.util.Map;

/**
 * Created by win8 on 2017/5/29.
 */
public class DefaultModularRealm extends ModularRealmAuthenticator {
    private Map<String, Object> definedRealms;

    /**
     * 多个realm实现
     */
    @Override
    protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {
        return super.doMultiRealmAuthentication(realms, token);
    }
    /**
     * 调用单个realm执行操作
     */
    @Override
    protected AuthenticationInfo doSingleRealmAuthentication(Realm realm,AuthenticationToken token) {

        // 如果该realms不支持(不能验证)当前token
        if (!realm.supports(token)) {
            throw new ShiroException("token错误!");
        }
        AuthenticationInfo info = null;
        try {
            info = realm.getAuthenticationInfo(token);

            if (info == null) {
                throw new ShiroException("token不存在!");
            }
        } catch (Exception e) {
            throw new ShiroException("用户名或者密码错误!");
        }
        return info;
    }


    /**
     * 判断登录类型执行操作
     */
    @Override
    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)throws AuthenticationException {
        this.assertRealmsConfigured();
        Realm realm = null;
        UsernamePasswordUsertypeToken token = (UsernamePasswordUsertypeToken) authenticationToken;
        //判断是否是后台用户
        if (token.getUsertype().equals("student")) {
            realm = (Realm) this.definedRealms.get("studentRealm");
        }
        else{
            realm = (Realm) this.definedRealms.get("dormAdminRealm");
        }

        return this.doSingleRealmAuthentication(realm, authenticationToken);
    }

    /**
     * 判断realm是否为空
     */
    @Override
    protected void assertRealmsConfigured() throws IllegalStateException {
        this.definedRealms = this.getDefinedRealms();
        if (CollectionUtils.isEmpty(this.definedRealms)) {
            throw new ShiroException("值传递错误!");
        }
    }

    public Map<String, Object> getDefinedRealms() {
        return this.definedRealms;
    }

    public void setDefinedRealms(Map<String, Object> definedRealms) {
        this.definedRealms = definedRealms;
    }

}

 

最后,配置我的xml

<!-- 用户授权信息Cache 缓存在本机内存,不支持集群 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/>

    <!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的ShiroDbRealm.java -->
    <bean id="dormAdminRealm" class="hstc.edu.cn.realm.dormAdminRealm">
        <property name="cacheManager" ref="cacheManager"/>
    </bean>

    <!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证前台用户登录的类为自定义的ShiroDbRealm.java -->
    <bean id="studentRealm" class="hstc.edu.cn.realm.studentRealm">
        <property name="cacheManager" ref="cacheManager"/>
    </bean>

    <!--多个realm 的集中管理  -->
    <bean id="defineModularRealmAuthenticator" class="hstc.edu.cn.realm.DefaultModularRealm">
        <property name="definedRealms">
            <map>
                <entry key="studentRealm" value-ref="studentRealm" />
                <entry key="dormAdminRealm" value-ref="dormAdminRealm" />
            </map>
        </property>
        <property name="authenticationStrategy">
            <bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy" />
        </property>
    </bean>
    <!-- Shiro默认会使用Servlet容器的Session,可通过sessionMode属性来指定使用Shiro原生Session -->
    <!-- 即<property name="sessionMode" value="native"/>,详细说明见官方文档 -->
    <!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用‘realms‘属性代替 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="authenticator" ref="defineModularRealmAuthenticator" />
        <!--    <property name="realm" ref="loginRealm"/> -->
        <property name="realms"  >
            <list>
                <bean id="loginRealm" class="hstc.edu.cn.realm.dormAdminRealm" />
                <bean id="userloginRealm" class="hstc.edu.cn.realm.studentRealm" />
            </list>
        </property>
        <property name="cacheManager" ref="cacheManager"/>
    </bean>

    <!-- Shiro过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- Shiro的核心安全接口,这个属性是必须的 -->
        <property name="securityManager" ref="securityManager" />
        <!-- 身份认证失败,则跳转到登录页面的配置 -->
        <property name="loginUrl" value="/login.jsp" />
        <!-- <property name="unauthorizedUrl" value="/unauthorized.jsp" />  -->
        <!-- Shiro连接约束配置,即过滤链的定义 -->
        <property name="filterChainDefinitions">
            <value>
                /login=anon
                /user/**=authc
            </value>
        </property>
    </bean>

 

以上是关于shiro 前后台realm 写法,用于分辨realm的主要内容,如果未能解决你的问题,请参考以下文章

Shiro实现多realm方案

Apache Shiro 使用手册Realm 实现

shiro之Realm及相关对象AuthorizationInfo

shiro前后台的session会共用一个,怎么分开?

shiro框架学习-3- Shiro内置realm

shiro调用不到自定义realm