这是我参与更文挑战的第4天,活动详情查看: 更文挑战html
本文正在参加「Java主题月 - Java 开发实战」,详情查看 活动连接java
Shiros是咱们开发中经常使用的用来实现权限控制的一种工具包ios
Shiros是咱们开发中经常使用的用来实现权限控制的一种工具包,它主要有认证、受权、加密、会话管理、与Web集成、缓存等功能。我是从事javaweb工做的,我就常常遇到须要实现权限控制的项目,以前咱们都是靠查询数据获取列表拼接展现的,还有的是及时的判断权限的问题的,如今有了Shiros了,咱们就能够统一的进行设置权限问题,Shrios的实现也是很简单的,下面让咱们来看看具体实现步骤web
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由servlet container管理 -->
<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
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 要求登陆时的连接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录下的"/login.html"页面 -->
<property name="loginUrl" value="/login.html"/>
<!-- 登陆成功后要跳转的链接 -->
<property name="successUrl" value="/index.html"/>
<!-- 用户访问未对其受权的资源时,所显示的链接 -->
<!-- 若想更明显的测试此属性能够修改它的值,如unauthor.jsp,而后用[玄玉]登陆后访问/admin/listUser.jsp就看见浏览器会显示unauthor.jsp -->
<property name="unauthorizedUrl" value="/login.html"
/>
<!-- Shiro链接约束配置,即过滤链的定义 -->
<!-- 此处可配合个人这篇文章来理解各个过滤连的做用http://blog.csdn.net/jadyer/article/details/12172839 -->
<!-- 下面value值的第一个'/'表明的路径是相对于HttpServletRequest.getContextPath()的值来的 -->
<!-- anon:它对应的过滤器里面是空的,什么都没作,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 -->
<!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->
<property name="filterChainDefinitions">
<value>
/statics/**=anon
/login.html=anon
/sys/schedule.html=perms[sys:schedule:save]
/sys/login=anon
/captcha.jpg=anon
/**=authc
</value>
</property>
</bean>
复制代码
/sys/schedule.html=perms[sys:schedule:save]
意思就是说访问schedule.html这个页面前提是你得有sys:schedule:save
这个权限。至于这个权限在哪里配置。在这里先透露一下。在Realm中获取数据库
<!-- 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="realm" ref="userRealm"/>
</bean>
复制代码
<bean id="userRealm" class="io.renren.shiro.UserRealm"/>
复制代码
首先来看看在认证登陆中咱们有哪些值得注意的地方apache
doGetAuthenticationInfo中实现登陆认证出现的几种异常浏览器
登陆认证就这几点注意,其次就是权限分配了,doGetAuthorizationInfo(受权),在doGetAuthorizationInfo里咱们经过PrincipalCollection这个身份集合,当咱们只配置了一个Reaml的时候咱们能够经过PrincipalCollection中的getPrimaryPrincipal方法得到刚刚传入的Reaml(用户名)就好了,可是当咱们配置了多个Reaml的时候能够经过PrincipalCollection中的getRealmNames获取全部的Reaml的用户名就好了。spring-mvc
而后经过用户名去数据库获取权限菜单。最后返回一个带有角色和权限的 SimpleAuthorization的信息,意思就是一下角色具备哪些权限。若是就一个角色的时候也能够不指定角色,分别经过setStringPermissions(指定权限)+setRoles(指定角色)缓存
到这里shiro的配置就完成了。
另外还有一点shiro的配置是处理shiro的生命周期和shiro的注解的启用的,这里就不解释了,直接上代码
<!-- Shiro生命周期处理器 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- AOP式方法级权限检查 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<!-- 开启shiro注解 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
<!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登陆的类为自定义的UserRealm.java -->
<bean id="userRealm" class="io.renren.shiro.UserRealm"/>
<!-- 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="realm" ref="userRealm"/>
</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"/>
<!-- 要求登陆时的连接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录下的"/login.html"页面 -->
<property name="loginUrl" value="/login.html"/>
<!-- 登陆成功后要跳转的链接 -->
<property name="successUrl" value="/index.html"/>
<!-- 用户访问未对其受权的资源时,所显示的链接 -->
<!-- 若想更明显的测试此属性能够修改它的值,如unauthor.jsp,而后用[玄玉]登陆后访问/admin/listUser.jsp就看见浏览器会显示unauthor.jsp -->
<property name="unauthorizedUrl" value="/login.html"
/>
<!-- Shiro链接约束配置,即过滤链的定义 -->
<!-- 此处可配合个人这篇文章来理解各个过滤连的做用http://blog.csdn.net/jadyer/article/details/12172839 -->
<!-- 下面value值的第一个'/'表明的路径是相对于HttpServletRequest.getContextPath()的值来的 -->
<!-- anon:它对应的过滤器里面是空的,什么都没作,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 -->
<!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->
<property name="filterChainDefinitions">
<value>
/statics/**=anon
/login.html=anon
/sys/schedule.html=perms[sys:schedule:save]
/sys/login=anon
/captcha.jpg=anon
/**=authc
</value>
</property>
</bean>
<!-- Shiro生命周期处理器 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- AOP式方法级权限检查 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<!-- 开启shiro注解 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
</beans>
复制代码
/statics/**=anon :以statics开头的请求能够随便访问,没有权限
/**=authc :表示全部的请求都须要进行验证权限且权限经过才能放行
authcBasic:org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
/admins/user/**=authcBasic :表示没有经过httpbasic认证的
perms:org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
/admins/user/**=perms[user:add:*] :上面已经解释过了,表示访问./admins/user/..
的请求必须是由use:add:*权限的才能够访问,不然重定向登陆页面(这里的登陆页面默认是web下的login.html,正常咱们经过设置shiro中的filterChainDefinitions属性设置页面)。
port : org.apache.shiro.web.filter.authz.PortFilter
/admins/user/**=port[8081] : 当访问的请求端口不是8001时,则shiro会重定向到schemal://serverName:8081?queryString请求。这个请求中schemal是http或者https,serverName是咱们原请求中的域名,8081就是咱们port里设置端口号,queryString是咱们原请求中携带的参数。
/admins/user/**=rest[user] : rest表示请求方法。至关于perms[user:method],这里method值得是post,get , delete.
roles :org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
/admins/user/**=roles[admin] : 这个和perms使用时同样的,只不过在后台咱们是经过
setRoles
方法给用户设置角色的。
ssl : org.apache.shiro.web.filter.authz.SslFilter
/admins/user/**=ssl : 表示该请求是安全请求,协议是https
/admins/user/**=user 表示必须存在用户,在登陆操做是不进行检查的,由于登陆的时候根本就不存在用户。
logout : org.apache.shiro.web.filter.authc.LogoutFilter
注意!上面中roles,perms,rest这三个里面是能够带参数的,若是有多个参数参数之间必须用英文装填下的逗号分隔。在页面中判断是全部参数都知足才算是知足的。/admins/user/**=logout : 表示该请求是退出操做