Shiro内置过滤器
认证相关过滤器:
anon(不需要任何认证直接可以访问),authBasic(也就是httpBasic),authc(需要认证之后才可以访问),user(需要当前存在用户才可以访问),logout(退出)
授权相关的过滤器:
perms(后面跟[ ] 里面加参数,表示具备一些权限才可以访问),roles(与前者相似),ssl(要求是安全的协议才可以访问,比如https),port(后面跟[ ] 里面放端口,必须是指定端口的才可以访问)
(ps:ssl与port用的比较少)
测试一下以上部分过滤器:
@RequestMapping(value = "/testRole",method = RequestMethod.GET) @ResponseBody public String testRole(){ return "test Role success"; } @RequestMapping(value = "/testRole1",method = RequestMethod.GET) @ResponseBody public String testRole1(){ return "test Role success"; } @RequestMapping(value = "/testPerms",method = RequestMethod.GET) @ResponseBody public String testPerms(){ return "testPerms success"; } @RequestMapping(value = "/testPerms1",method = RequestMethod.GET) @ResponseBody public String testPerms1(){ return "testPerms1 success"; }
在spring.xml中配置一下:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!--登录页的url--> <property name="loginUrl" value="login.html"/> <!--未认证的跳转页面--> <property name="unauthorizedUrl" value="403.html" /> <!--过滤器链//从上往下匹配拦截认证,--> <property name="filterChainDefinitions"> <value> <!--登录页面不需要拦截--> /login.html = anon <!--提交登录请求的url也不许要拦截--> /subLogin = anon /testRole = roles["admin"] /testRole1 = roles["admind","admin1"] /testPerms = perms["user:delete"] /testPerms1 = perms["user:delete","user:update"] <!--登录页面以外的需要拦截认证--> /* = authc </value> </property> </bean>
我的权限表如下:
1.先是访问testRole:
说明登录账户具备角色admin
2.访问testRole1
跳转
3.访问testPerms 与一个相同
4.testPerms1也一样
都ok。
这里配置的拦截
/testRole1 = roles["admind","admin1"]必须同时拥有两种角色才有权限访问,那么如何让登录用户拥有其中一个角色就可以访问呢,这就需要自定义Filter了,这之前需要先导入Servlet相关的依赖,不然方法会报红:
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.4</version> <scope>provided</scope> </dependency>
自定义Filter:
public class RolesOrFilter extends AuthorizationFilter { @Override protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception { //先或得到主体 Subject subject = getSubject(servletRequest, servletResponse); //强转String类型数组 String[] roles = (String[])o; if (roles == null || roles.length == 0){ return true; } //若不为空,遍历一下数组 for (String role : roles) { //如果一经发现数组里有指定角色时,立即返回true if (subject.hasRole(role)){ return true; } } return false; } }
接着要去spring.xml配置注入自定义Filter:
<!--创建注入自定义Filter--> <bean class="com.yunyun.filter.RolesOrFilter" id="rolesOrFilter"/>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!--登录页的url--> <property name="loginUrl" value="login.html"/> <!--未认证的跳转页面--> <property name="unauthorizedUrl" value="403.html" /> <!--过滤器链//从上往下匹配拦截认证,--> <property name="filterChainDefinitions"> <value> <!--登录页面不需要拦截--> /login.html = anon <!--提交登录请求的url也不许要拦截--> /subLogin = anon <!--/testRole = roles["admin"]--> /testRole2 = rolesOr["admin","admin1"] <!--/testPerms = perms["user:delete"]--> <!--/testPerms1 = perms["user:delete","user:update"]--> <!--登录页面以外的需要拦截认证--> /* = authc </value> </property> <property name="filters"> <util:map> <entry key="rolesOr" value-ref="rolesOrFilter"/> </util:map> </property> </bean> <!--创建注入自定义Filter--> <bean class="com.yunyun.filter.RolesOrFilter" id="rolesOrFilter"/>
在controller中添加:
@RequestMapping(value = "/testRole2",method = RequestMethod.GET) @ResponseBody public String testRole2(){ return "test Role2 success"; }
这里Controller层要注意,我发现加了@RequiresRoles("admin1")注解的方法,优先级要高于你自定义的拦截器,也就是说,只能用一个,不能都用= =。不知道这么理解有没有问题,但是之前就没注意,俩个一起用在同一个方法上,一直报错
Subject does not have role [admin1]
,后来重写了一个方法,不加注解,只用自定义的filter,就完全没有问题了。
运行效果如下:
来源:https://www.cnblogs.com/xk920/p/10827025.html