首先改写一下 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>