shiro配置及使用 整体流程

来源:互联网 发布:日本汽车出口数据 编辑:程序博客网 时间:2024/05/17 21:46

shiro的介绍网上很多,详细的有开涛的博客。因为开涛的博客文章较多,而项目又比较赶,所以博主是根据项目需要来搜资料的,当然了,获取资料最多的就是开涛的博客了。

当然了,使用一个东西最开始就应该就是导入它的包了,在官网上写了好多种包,但是shiro不是自己都说,好的项目不是什么都有,而是不能再少一点东西了,所以大家在导包 的时候尽量不要太贪心的全导入了,视项目的情况而定吧。

下面是maven的配置,当然,项目没有使用maven的朋友可以去maven仓库里下载对应的包导入项目,maven是个好东西,如果是用maven导入包的话,maven会帮忙把包的源码也管理起来:

<properties><shiro-version>1.3.2</shiro-version></properties><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>${shiro-version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>${shiro-version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-aspectj</artifactId><version>${shiro-version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>${shiro-version}</version></dependency><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>${shiro-version}</version></dependency>

然后是shiro的配置,具体的信息在配置文件里都写的很详细了,大家可以仔细的看看,了解shiro:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- Root Context: defines shared resources visible to all other web components --><bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean><!-- 缓存管理器 使用Ehcache实现 --><bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"><property name="cacheManagerConfigFile" value="classpath:ehcache.xml" /></bean><!-- 凭证匹配器 --><bean id="credentialsMatcher"class="com.xx.smarthome.shiro.RetryLimitHashedCredentialsMatcher"><constructor-arg ref="cacheManager" /><property name="hashAlgorithmName" value="md5" /><!-- md5盐值加密3次 --><property name="hashIterations" value="3" /><property name="storedCredentialsHexEncoded" value="true" /></bean><!-- 自定义的jdbcrealm --><bean id="jdbcRealmCustom" class="com.xx.smarthome.shiro.realm.JdbcRealmCustom"><!-- 凭证匹配器 --><property name="credentialsMatcher" ref="credentialsMatcher" /><property name="cachingEnabled" value="true" /><!-- 如需要自定义缓存时间放开以下.修改 ehcache.xml --><property name="authenticationCachingEnabled" value="true" /><property name="authenticationCacheName" value="authenticationCache" /><property name="authorizationCachingEnabled" value="true" /><property name="authorizationCacheName" value="authorizationCache" /></bean><!-- Shiro安全管理器 --><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><property name="realm" ref="jdbcRealmCustom"></property><property name="cacheManager" ref="cacheManager"></property></bean><!-- 登出过滤器 --><bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter"><property name="redirectUrl" value="/login.jsp" /></bean><!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、 自定义的过滤器的执行 Web应用中, Shiro可控制的Web请求必须经过Shiro主过滤器的拦截, Shiro对基于Spring的Web应用提供了完美的支持 --><bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><!-- Shiro的核心安全接口,这个属性是必须的 --><property name="securityManager" ref="securityManager"></property><!-- 要求登录时的链接(登录页面地址),非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面 --><!-- <property name="loginUrl" value="/security/login"></property> --><!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码) --><!-- <property name="successUrl" value="/" ></property> --><!-- 用户访问未对其授权的资源时,所显示的连接 --><property name="unauthorizedUrl" value="/"></property><!-- 访问权限配置,anon不需要权限可以访问,authc需要权限,如果没有登陆则跳回登陆界面 --><!-- 这些是对url进行匹配 --><property name="filterChainDefinitions"><value><!-- 静态资源允许访问 -->/resources/** = anon<!-- 登录注册允许访问 -->/login* = anon/register* = anon<!-- 登出 -->/logout = logout<!-- 其他资源需要认证 -->/** = authc<!-- perms[user:query]表示访问此连接需要权限为user:query的用户 --><!-- /user=perms[user:query] --><!-- roles[manager]表示访问此连接需要用户的角色为manager --><!-- /user/add=roles[manager] --></value></property></bean></beans>  

以上有jdbcrealm和凭证匹配器是自定义的,其中jdbcrealm是用来验证用户是否输入提交了正确的信息,并获取用户的角色和权限,以便后面对用户的角色和权限做相应的判断。凭证匹配器用的其实还是shiro的凭证匹配,只不过在其中增加了自己的一点小业务(账号登陆失败5次,锁定账号5分钟)

下面列出jdbcrealm的代码:

public class JdbcRealmCustom extends AuthorizingRealm {/** * 获取授权信息 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// TODO Auto-generated method stub// null usernames are invalidif (principals == null) {throw new AuthorizationException("PrincipalCollection method argument cannot be null.");}//这里获取用户的权限和角色,根据项目和数据库设计的不同获取的方式会不一样,所以这里博主就不列出来了,查询出来以后//其中roleNames和permissions都是set<String>类型SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);info.setStringPermissions(permissions);return info;}/** * 获取认证信息 */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {// TODO Auto-generated method stubUsernamePasswordToken upToken = (UsernamePasswordToken) token;String username = upToken.getUsername();// Null username is invalidif (username == null || username.equals("")) {throw new AccountException("Null usernames are not allowed by this realm.");}SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,password.toCharArray(), // 密码ByteSource.Util.bytes(salt), // 盐getName());return info;}}

其中在注册的时候生成盐和密码的方式为:

// 生成密码和盐String salt = new SecureRandomNumberGenerator().nextBytes().toHex();int hashIterations = 3;Md5Hash mh = new Md5Hash(enterpriseMemberCustom.getMemberpassword(), salt, hashIterations);// 这个为数据库要存下的密码member.setMemberpassword(mh.toString());// 密码member.setSalt(salt);// 盐

凭证匹配器,实现登陆超过5次不成功锁定账号:

import java.util.concurrent.atomic.AtomicInteger;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.ExcessiveAttemptsException;import org.apache.shiro.authc.credential.HashedCredentialsMatcher;import org.apache.shiro.cache.Cache;import org.apache.shiro.cache.CacheManager;public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {private Cache<String, AtomicInteger> passwordRetryCache;public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {passwordRetryCache = cacheManager.getCache("passwordRetryCache");}@Overridepublic boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {// TODO Auto-generated method stubString principal = (String) token.getPrincipal();AtomicInteger atomicInteger = passwordRetryCache.get(principal);if (atomicInteger == null) {atomicInteger = new AtomicInteger(0);passwordRetryCache.put(principal, atomicInteger);}// 如果重试次数超过5次则抛出异常if (atomicInteger.incrementAndGet() > 5) {throw new ExcessiveAttemptsException();}boolean doCredentialsMatch = super.doCredentialsMatch(token, info);// 调用父类的验证// 如果账号密码正确,清除重试次数if (doCredentialsMatch) {passwordRetryCache.remove(principal);}return doCredentialsMatch;}}

编写ehcache.xml,放在和shiro配置文件的同一目录下:

<?xml version="1.0" encoding="UTF-8"?><ehcache updateCheck="false"  name="shirocache">    <diskStore path="java.io.tmpdir"/>    <defaultCache       maxElementsInMemory="10000"       eternal="false"       timeToIdleSeconds="120"       timeToLiveSeconds="120"       overflowToDisk="false"       diskPersistent="false"       diskExpiryThreadIntervalSeconds="120"       />    <!-- 登录记录缓存 锁定5分钟 -->    <cache name="passwordRetryCache"           maxEntriesLocalHeap="2000"           eternal="false"           timeToIdleSeconds="300"           timeToLiveSeconds="0"           overflowToDisk="false"           statistics="true">    </cache>    <cache name="authorizationCache"           maxEntriesLocalHeap="2000"           eternal="false"           timeToIdleSeconds="3600"           timeToLiveSeconds="0"           overflowToDisk="false"           statistics="true">    </cache>    <cache name="authenticationCache"           maxEntriesLocalHeap="2000"           eternal="false"           timeToIdleSeconds="3600"           timeToLiveSeconds="0"           overflowToDisk="false"           statistics="true">    </cache>    <cache name="shiro-activeSessionCache"           maxEntriesLocalHeap="2000"           eternal="false"           timeToIdleSeconds="3600"           timeToLiveSeconds="0"           overflowToDisk="false"           statistics="true">    </cache>    <cache name="shiro_cache"       maxElementsInMemory="2000"           maxEntriesLocalHeap="2000"           eternal="false"           timeToIdleSeconds="0"           timeToLiveSeconds="0"           maxElementsOnDisk="0"           overflowToDisk="true"           memoryStoreEvictionPolicy="FIFO"           statistics="true">    </cache></ehcache>

配置完以后当然要加入到项目中去了,web.xml中加入:

<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext-shiro.xml</param-value></context-param>
大功告成,接下来咱们就可以开始使用了!

首先登陆一下吧:

@RequestMapping(value = "login", method = RequestMethod.POST)public String login(String userName, String password, Model model) throws CustomException {UsernamePasswordToken token = new UsernamePasswordToken(userName, password, false);Subject subject = SecurityUtils.getSubject();String msg;try {subject.login(token);// 用户登录if (subject.isAuthenticated()) {// 成功return "登陆成功后想要显示的界面";} elsemsg = "未知情况,请检查账号密码后重试";} catch (IncorrectCredentialsException | UnknownAccountException e) {msg = "账号或密码错误";} catch (ExcessiveAttemptsException e) {msg = "登录失败次数过多,账户锁定五分钟";} catch (LockedAccountException e) {msg = "帐号已被锁定";} catch (DisabledAccountException e) {msg = "帐号已被禁用";} catch (ExpiredCredentialsException e) {msg = "帐号已过期";} catch (UnauthorizedException e) {msg = "您没有得到相应的授权";} catch (AuthenticationException e) {// 其它异常// TODO: handle exceptionmsg = e.getMessage();}model.addAttribute("error_msg", msg);// 返回登陆页,在登陆错误信息上显示error_msgreturn "login";}

然后是jsp标签和springmvc标签的使用

jsp标签使用需要在jsp页面上导入shiro标签

<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> 

springmvc则需要在springmvc的配置文件中配置实用shiro标签:

<!-- 添加对shiro注解扫描的支持 --><beanclass="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"depends-on="lifecycleBeanPostProcessor"><property name="proxyTargetClass" value="true" /></bean><beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><property name="securityManager" ref="securityManager" /></bean>
<!-- shiro没有权限跳转界面 --><beanclass="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"><props><prop key="org.apache.shiro.authz.UnauthorizedException">error/unauthorized</prop></props></property></bean>

具体的jsp标签和springmvc怎么使用shiro注解这里就不再说了,相信这篇文章已经足够大粗长了,不能再吓着刚准备使用shiro的朋友们了

祝大家shiro旅途愉快!~



原创粉丝点击