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