<div class="exp-content-block"><h2 class="exp-content-head"><a href="javascript:;" name="section-3"></a>方法/步驟<div class="audio-wp audio-wp-2" data-text="" data-for="" data-index="2" style="display: inline-block;"><span class="audio-inner"><span class="audio-icon"></span><span class="audio-icon-2"></span><span class="audio-icon-3"></span></span><span class="desc"></span></div></h2><div class="exp-content-body"><ol class="exp-conent-orderlist"><li class="exp-content-list list-item-1"><div class="list-icon" style="visibility: hidden;">1</div><div class="content-list-text"><p>web.xml添加配置</p><p><br><!-- shiro過濾器 --></p><p> <filter></p><p> <filter-name>shiroFilter</filter-name></p><p> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></p><p> <init-param></p><p> <param-name>targetFilterLifecycle</param-name></p><p> <param-value>true</param-value></p><p> </init-param></p><p> </filter></p><p> <filter-mapping></p><p> <filter-name>shiroFilter</filter-name></p><p> <url-pattern>/*</url-pattern></p><p> </filter-mapping><br></p></div></li><li class="exp-content-list list-item-2"><div class="list-icon" style="visibility: hidden;">2</div><div class="content-list-text"><p>shiro與spring整合配置</p><p><br><!-- 使用shiro安全檢查註解 --></p><p> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" /></p><p> </p><p> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"></p><p> <property name="securityManager" ref="securityManager" /></p><p> </bean><br></p><p><br></p><p><br> <!-- shiro的生命週期處理器 --></p><p> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /></p><p> </p><p> <!-- shiro自帶的密碼匹配器(用來校驗密碼足夠了) --></p><p> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.SimpleCredentialsMatcher"></bean> </p><p> <!-- security datasource: --></p><p> <bean id="myRealm" class="cc.eguid.service.shiro.MyRealm"></p><p> <property name="credentialsMatcher" ref="credentialsMatcher"/><!-- 密碼匹配器 --></p><p> <property name="cachingEnabled" value="false"/><!-- 禁止緩存 --></p><p> </bean></p><p> <!-- 安全管理器 --></p><p> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"></p><p> <property name="realm" ref="myRealm" /></p><p> </bean></p><p> <!-- shiro過濾器 --></p><p> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"></p><p> <!-- 配置安全管理器 --></p><p> <property name="securityManager" ref="securityManager" /></p><p> <!-- 身份認證失敗跳轉的地址 --></p><p> <property name="loginUrl" value="/login/" /></p><p> <!-- 身份認證成功跳轉的地址 --></p><p> <property name="successUrl" value="/" /></p><p> <!-- 權限認證失敗跳轉的地址 --></p><p> <property name="unauthorizedUrl" value="/login/unauthorized" /></p><p> <property name="filterChainDefinitions"></p><p> <!--anon 表示匿名訪問,不須要認證以及受權 --></p><p> <!--authc表示須要認證 沒有進行身份認證是不能進行訪問的 --></p><p> <!--authc,roles[admin]表示是admin角色的用戶才能訪問 --></p><p> <value></p><p> /static/** = anon</p><p> /login/** = anon</p><p> /common/** = anon</p><p> /admin/** = authc,roles[admin]</p><p> /* = authc</p><p> /** = authc</p><p> </value></p><p> </property></p><p> </bean></p><p> <br></p></div></li><li class="exp-content-list list-item-3"><div class="list-icon" style="visibility: hidden;">3</div><div class="content-list-text"><p>realm和自定義密碼校驗器實現</p><p><br>public class MyRealm extends AuthorizingRealm{</p><p> Logger log=Logger.getLogger(MyRealm.class);</p><p> </p><p> @Autowired</p><p> private UserService userService;//這是本身實現的用戶信息操做類,實現用戶信息,用戶角色信息、用戶權限信息查詢功能</p><p> </p><p> @Override</p><p> protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {</p><p> UserInfo user = (UserInfo) principals.getPrimaryPrincipal();</p><p> SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();</p><p> // 查詢角色信息</p><p> Collection<String> roles = userService.findRoles(user);</p><p> info.addRoles(roles);</p><p> log.info("shiro獲取用戶所屬角色列表:"+roles);</p><p> // 查詢權限信息</p><p> Collection<String> permissions = userService.findPermissions(user.getSystemuserid());</p><p> info.addStringPermissions(permissions);</p><p> log.info("shiro獲取用戶權限列表:"+permissions);</p><p> return info;</p><p> }</p><p> </p><p> @Override</p><p> protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)throws AuthenticationException{</p><p> //用戶輸入的用戶名密碼</p><p> String loginname= token.getPrincipal().toString();</p><p> Object password=token.getCredentials();</p><p> log.info("shiro正在處理嘗試登陸的用戶信息:"+loginname+",密碼:"+new String((char[])password));</p><p> //數據庫中的用戶信息</p><p> UserInfo user =userService.queryUserInfoByLoginName(loginname);</p><p> if(user==null||CommonUtil.isNull(user.getLoginusername(),user.getPassword(),user.getSystemuserid())){</p><p> return null;</p><p> }</p><p> log.info("shiro獲取到當前用戶嘗試登陸的真實數據:"+user.getLoginusername()+",密碼:"+user.getPassword());</p><p> //數據庫中的正確的帳戶信息</p><p> AuthenticationInfo accountInfo =new SimpleAuthenticationInfo(user, user.getPassword(),getName());</p><p> </p><p> //本身獲取密碼驗證器(因爲shiro實現的密碼校驗方法是密碼錯誤會直接拋異常,不採用,因此改爲直接手動校驗)</p><p> CredentialsMatcher matcher=getCredentialsMatcher();</p><p> if(matcher==null){</p><p> log.error("沒有配置密碼匹配器");</p><p> return null;</p><p> }</p><p> //校驗密碼</p><p> if(matcher.doCredentialsMatch(token,accountInfo)){</p><p> return accountInfo;//校驗經過,返回帳號信息</p><p> }</p><p> </p><p> return null;</p><p> }</p><p> </p><p> </p><p>}<br></p></div></li><li class="exp-content-list list-item-4"><div class="list-icon" style="visibility: hidden;">4</div><div class="content-list-text"><p>自定義密碼校驗器</p><p><br>/**</p><p> * 自定義shiro密碼匹配(密碼是在md5散列值的基礎上再次進行md5加鹽操做,加鹽值不保存在數據庫,而是放在配置文件中)</p><p> * @author eguid</p><p> *</p><p> */</p><p>public class MyCredentialsMatcher extends CodecSupport implements CredentialsMatcher {</p><p> private static final Logger log = LoggerFactory.getLogger(MyCredentialsMatcher.class);</p><p> </p><p> protected Object getCredentials(AuthenticationToken token) {</p><p> return token.getCredentials();</p><p> }</p><p> </p><p> protected Object getCredentials(AuthenticationInfo info) {</p><p> return info.getCredentials();</p><p> }</p><p> </p><p> @Autowired</p><p> private CommonConfigs commonConfigs;</p><p> /**</p><p> * 驗證密碼</p><p> *</p><p> * @param tokenCredentials</p><p> * @param accountCredentials</p><p> * @return</p><p> */</p><p> protected boolean equals(Object tokenCredentials, Object accountCredentials) {</p><p> if (log.isDebugEnabled()) {</p><p> log.debug("Performing credentials equality check for tokenCredentials of type ["</p><p> + tokenCredentials.getClass().getName() + " and accountCredentials of type ["</p><p> + accountCredentials.getClass().getName() + "]");</p><p> }</p><p> if (isByteSource(tokenCredentials) && isByteSource(accountCredentials)) {</p><p> if (log.isDebugEnabled()) {</p><p> log.debug("Both credentials arguments can be easily converted to byte arrays. Performing "</p><p> + "array equals comparison");</p><p> }</p><p> byte[] tokenBytes = toBytes(tokenCredentials);</p><p> byte[] accountBytes = toBytes(accountCredentials);</p><p> return MessageDigest.isEqual(tokenBytes, accountBytes);</p><p> } else {</p><p> return accountCredentials.equals(tokenCredentials);</p><p> }</p><p> }</p><p> </p><p> public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {</p><p> Object tokenCredentials = getCredentials(token);</p><p> Object accountCredentials = getCredentials(info);</p><p> String account=String.valueOf((char[])tokenCredentials);</p><p> if(commonConfigs.getMd5salt()==null){</p><p> if (log.isDebugEnabled()) {</p><p> log.debug("配置文件中的加鹽值爲空,沒法進行密碼匹配,請確認配置文件是否在指定位置或配置指定加鹽值");</p><p> }</p><p> return false;</p><p> }</p><p> String saltaccount=MD5Util.getMD5(account, commonConfigs.getMd5salt());</p><p> if (log.isDebugEnabled()) {</p><p> log.debug("加鹽後的密碼:"+saltaccount);</p><p> }</p><p> return equals(accountCredentials, saltaccount.toCharArray());</p><p> }</p><p> </p><p>}<br></p></div></li><li class="exp-content-list list-item-5"><div class="list-icon" style="visibility: hidden;">5</div><div class="content-list-text"><p>註解使用及模板標籤使用</p><p>一、註解使用<br>@RequiresPermissions({"user:update:view"})//檢查操做權限<br>@RequiresPermissions(value={"user:add","user:view"},logical=Logical.OR)//兩個操做權限其中一個知足條件便可經過檢查<br>@RequiresRoles({"admin"})//檢查角色<br>@RequiresRoles(value={"debug","admin"},logical=Logical.OR)//兩個角色其中一個角色知足條件便可</p><p>@RequiresAuthentication//檢查是否經過shiro認證<br>@RequiresGuest//不須要驗證<br>@RequiresUser//檢查用戶是不是當前系統中的用戶</p><p>二、標籤使用<br>使用標籤須要先導入shiro的標籤庫<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %><br>(1)顯示用戶身份信息<br><shiro: principal/><br>默認調用Subject.getPrincipal()獲取</p><p><shiro:principal property="username"/><br>至關於((User)Subject.getPrincipals()).getUsername()</p><p>(2)已登陸shiro用戶顯示</p><p> <shiro:user> <br>歡迎[<shiro:principal/>]登陸,<a href="logout">退出</a> <br><shiro:user></p><p>(3)匿名用戶訪問<br><shiro:guest>未通過shiro驗證的用戶(遊客,匿名用戶)</shiro:guest> </p><p>(4)已經在shiro登陸過的(已登陸用戶)</p><p> <shiro:authenticated> <br> 用戶[<shiro:principal/>]已身份驗證經過 <br><shiro:authenticated></p><p>(5)沒有在shiro登陸過的</p><p><br> <shiro:notAuthenticated><br> 未身份驗證(包括記住我)<br><shiro:notAuthenticated></p><p>(6)檢查角色</p><p> <shiro:hasRole name="admin"><br> 用戶[<shiro:principal/>]擁有角色admin<br/><br><shiro:hasRole></p><p>檢查任意角色(其中一個知足條件即經過,至關於OR)<br> <shiro:hasAnyRoles name="admin,user"><br> 用戶[<shiro:principal/>]擁有角色admin或user<br/><br><shiro:hasAnyRoles></p><p>不具備角色(反向判斷)<br> <shiro:lacksRole name="abc"><br> 用戶[<shiro:principal/>]不具備角色abc<br/><br><shiro:lacksRole></p><p>(7)操做權限判斷</p><p> <shiro:hasPermission name="user:create"> <br> 用戶[<shiro:principal/>]擁有權限user:create<br/> <br><shiro:hasPermission> </p><p>不具備操做權限(反向判斷)</p><p><br> <shiro:lacksPermission name="org:create"> <br> 用戶[<shiro:principal/>]沒有權限org:create<br/> <br><iro:lacksPermission> <br><br></p></div><div class="last-item"><span class="last-item-end">END</span></div></li></ol></div></div>javascript