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

一、目标

权限配置在数据库中,通过注解Shiro的注解实现服务的权限验证

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

    
    
    	
    	
    		
    			
    			
    		
    	
    	
    		
                /user/queryUserInfo = authc
                /user/deleteUser/** = perms[USER:DELETE]
    		
    	
    

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

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

    
	        
	
	        
	

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

   
	 	springmvc
	 	org.springframework.web.servlet.DispatcherServlet
	 	
	 		contextConfigLocation
	 		classpath:config/spring-servlet.xml
	 	
	
	
		springmvc
		/*
	

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

    

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

三、验证

1.创建权限表
分别增加角色表sys_role_t,角色权限表sys_role_perm_t,用户角色权限关系表user_role_perm_t

在角色表sys_role_t中初始化三个角色,分别为系统管理员,普通用户,区域管理员Shiro权限控制(三):Shiro注解权限验证_第1张图片

在角色权限表sys_role_perm_t中初始化普通用户,区域管理员具有增、删、改、查权限
Shiro权限控制(三):Shiro注解权限验证_第2张图片
在用户角色权限关系表user_role_perm_t中配置user_id=1的用户,有普通用户角色的查询、编辑、新增权限;有区域管理员角色的删除权限
Shiro权限控制(三):Shiro注解权限验证_第3张图片

2.自定义UserShiroRealm
自定义UserShiroRealm,继承AuthorizingRealm,重写doGetAuthorizationInfo方法,在方法中查询用户的所有权限,并交给Shiro进行权限验证

    @Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String userName = (String)principals.getPrimaryPrincipal();
		if(userName == null) {
			throw new BugException("未登录");
		}
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		Set roles = new HashSet();
		Set stringPermissions = new HashSet();
		List list = userService.queryUserPermission(userName);
		for (UserPermissionVO userPermissionVO : list) {
			roles.add(userPermissionVO.getRoleCode());
			stringPermissions.add(userPermissionVO.getPermCodes());
		}
		//roles.add("USER");
		//stringPermissions.add("USER:DELETE");//角色:删除权限
		info.setRoles(roles);
		info.setStringPermissions(stringPermissions);
		
		return info;
	}

3.编写服务
服务名称:增加用户
权限要求:普通用户角色的新增权限 或 区域管理员的新增权限才可访问

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

logical=Logical.OR 表示或,满足其中一个权限即可访问
logical=Logical.AND 表示与,满足所有权限才可访问

未登录,直接访问http://localhost:8080/bug.web/user/addUser,报如下错误,提示没有登录
Shiro权限控制(三):Shiro注解权限验证_第4张图片
登录成功后,再次访问http://localhost:8080/bug.web/user/addUser,请求成功,如果从数据库中删除用户的 CUSTOMER_USER:ADD权限和AREA_MANAGER:DELETE权限,再次请求时报如下错误,提示没有访问权限
在这里插入图片描述
上面的异常如何处理请看另一篇博文《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。

你可能感兴趣的:(Shiro)