Shiro权限控制之注解验证(三)

一、目标
通过注解方式实现URL的权限验证

二、前言
在前面的一篇博文中《Shiro权限控制之自定义Filter(二)》,我们的权限验证是配置在shiro配置文件中的,即在spring-shiro-web.xml中的ShiroFilterFactoryBean的filterChainDefinitions属性中,如下

    <!-- Shiro的web过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    	<property name="securityManager" ref="securityManager"></property>
    	<property name="filters">
    		<map>
    			<entry key="authc" value-ref="loginCheckPermissionFilter"></entry>
    			<entry key="perms" value-ref="permissionsAuthorizationFilter"></entry>
    		</map>
    	</property>
    	<property name="filterChainDefinitions">
    		<value>
                /user/queryUserInfo = authc
                /user/deleteUser/** = perms[USER:DELETE]
    		</value>
    	</property>
    </bean>

如何通过注解的方式,实现权限的验证呢?请看下面的介绍

三、启用注解
1、必须在Spring MVC的配置文件中,增加以下配置,启用Shiro的权限注解功能

    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
	        depends-on="lifecycleBeanPostProcessor" />
	        
	<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
	        <property name="securityManager" ref="securityManager" />
	</bean>

说明:我的Spring MVC的文件是spring-servlet.xml,该文件必须在web.xml文件中引入

   <servlet>
	 	<servlet-name>springmvc</servlet-name>
	 	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	 	<init-param>
	 		<param-name>contextConfigLocation</param-name>
	 		<param-value>classpath:config/spring-servlet.xml</param-value>
	 	</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>

2、在spring-shiro-web.xml文件中增加以下配置

    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>

通过上面的配置,Shiro的权限注解已经生效,下面来验证一下

三、验证
有如下服务,使用了@RequiresPermissions注解,拥有USER角色的ADD权限才可访问

    @ResponseBody
	@RequiresPermissions({"USER:ADD"})
	@RequestMapping(value="/addUser",method = RequestMethod.GET)
	public ResponseVO<String> addUser() {
		ResponseVO<String> response = new ResponseVO<String>();
		try {
			response.setMessage("add user success");
		} catch (Exception e) {
			logger.error("add user error:",e);
			response.setStatus(ResponseVO.failCode);
		}
		return response;
	}

未登录,直接访问http://localhost:8080/bug.web/user/addUser,报如下错误,提示没有登录
Shiro权限控制之注解验证(三)
登录成功后,再次访问http://localhost:8080/bug.web/user/addUser,报如下错误,提示没有USER:ADD的权限,说明我们配置的注解权限验证生效了
Shiro权限控制之注解验证(三)
上面的异常如何处理请看另一篇博文《Shiro权限控制之注解验证异常处理(四)》

上面只是用到了@RequiresPermissions注解,其他注解如下

四、其他注解说明
@RequiresAuthentication

验证用户是否登录,等同于方法subject.isAuthenticated() 结果为true时。

@RequiresUser

验证用户是否被记忆,user有两种含义:

一种是成功登录的(subject.isAuthenticated() 结果为true);

另外一种是被记忆的(subject.isRemembered()结果为true)。

@RequiresGuest

验证是否是一个guest的请求,与@RequiresUser完全相反。

换言之,RequiresUser == !RequiresGuest。

此时subject.getPrincipal() 结果为null.

@RequiresRoles

例如:@RequiresRoles(“aRoleName”);

void someMethod();

如果subject中有aRoleName角色才可以访问方法someMethod。如果没有这个权限则会抛出异常AuthorizationException。

@RequiresPermissions

例如: @RequiresPermissions({“file:read”, “write:aFile.txt”} )
void someMethod();

要求subject中必须同时含有file:read和write:aFile.txt的权限才能执行方法someMethod()。否则抛出异常AuthorizationException。