官方解释 :

Apache Shiro(日语“堡垒(Castle)”的意思)是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可为任何应用提供安全保障 - 从命令行应用、移动应用到大型网络及企业应用。

Shiro为解决下列问题(我喜欢称它们为应用安全的四要素)提供了保护应用的API:

认证 - 用户身份识别,常被称为用户“登录”;

授权 -访问控制;

密码加密 - 保护或隐藏数据防止被偷窥;

会话管理- 每用户相关的时间敏感的状态。

Shiro还支持一些辅助特性,如Web应用安全、单元测试和多线程,它们的存在强化了上面提到的四个要素。

第一步:配置web.xml

<!--配置Shiro过滤器,先让Shiro过滤系统接收到的请求--><!--这里filter-name必须对应applicationContext.xml中定义的<beanid="shiroFilter"/>--><!--使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤--><!--通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的--><filter><filter-name>shiroFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class><init-param><!--该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理--><param-name>targetFilterLifecycle</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>shiroFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

第二步:配置spring-shiro.xml

<!--继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的ShiroDbRealm.java--><beanid="myRealm"class="com.tyzq.common.ShiroRealm"/><!--Shiro默认会使用Servlet容器的Session,可通过sessionMode属性来指定使用Shiro原生Session--><!--即<propertyname="sessionMode"value="native"/>,详细说明见官方文档--><!--这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替--><beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><propertyname="realm"ref="myRealm"/></bean><!--Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行--><!--Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持--><beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><!--Shiro的核心安全接口,这个属性是必须的--><propertyname="securityManager"ref="securityManager"/><!--要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面--><propertyname="loginUrl"value="/"/><!--登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里面控制跳转)--><!--<propertyname="successUrl"value="/system/main"/>--><!--用户访问未对其授权的资源时,所显示的连接--><propertyname="unauthorizedUrl"value="/noauthority.jsp"/><!--Shiro连接约束配置,即过滤链的定义--><!--anon:它对应的过滤器里面是空的,什么都没做,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种--><!--authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter--><propertyname="filterChainDefinitions"><value>/mydemo/login=anon/mydemo/getVerifyCodeImage=anon/main**=authc/user/info**=authc</value></property></bean><!--保证实现了Shiro内部lifecycle函数的bean执行--><beanid="lifecycleBeanPostProcessor"class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/><!--开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证--><beanclass="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"depends-on="lifecycleBeanPostProcessor"/><beanclass="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"><propertyname="securityManager"ref="securityManager"/></bean>

第三步:自定义的Realm类

publicclassShiroRealmextendsAuthorizingRealm{@AutowiredprivateUserInfoServiceuserInfoService;/***“授权”查询回调函数,进行鉴权但缓存中无用户的授权信息时调用.*@paramprincipals*@return*/@OverrideprotectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectioncollection){SimpleAuthorizationInfoinfo=null;/*Stringusername=(String)collection.fromRealm(getName()).iterator().next();/*UseruserInfo=userService.getById(username);Criteriacriteria=newCriteria();criteria.put("userId",userInfo.getId());if(userInfo!=null){//权限控制info=newSimpleAuthorizationInfo();List<MoKuai>moKuais=this.kuaiService.findListByUserId(criteria);Stringmethod=null;Stringpermissioin=null;for(MoKuaiitem:moKuais){permissioin=item.getPrivPermissioin();if(!StringHelper.isNullOrEmpty(permissioin)){permissioin=permissioin.trim();info.addStringPermission(permissioin);}}}*/returninfo;}/***“认证”回调函数,登录时调用.*/@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokentoken)throwsAuthenticationException{UsernamePasswordTokenusernamePasswordToken=(UsernamePasswordToken)token;UserInfouserInfo=userInfoService.getUserInfoByAccount(usernamePasswordToken.getUsername());SimpleAuthenticationInfoinfo=null;if(userInfo!=null){//其他验证info=newSimpleAuthenticationInfo(usernamePasswordToken.getUsername(),usernamePasswordToken.getPassword(),getName());}//身份认证验证成功,返回一个AuthenticationInfo实现;returninfo;}/***更新用户授权信息缓存.*/publicvoidclearCachedAuthorizationInfo(Stringprincipal){SimplePrincipalCollectionprincipals=newSimplePrincipalCollection(principal,getName());clearCachedAuthorizationInfo(principals);}/***清除所有用户授权信息缓存.*/publicvoidclearAllCachedAuthorizationInfo(){Cache<Object,AuthorizationInfo>cache=getAuthorizationCache();if(cache!=null){for(Objectkey:cache.keys()){cache.remove(key);}}}}