<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