SpringSecurity权限控制
用户每次访问微服务的时候,先去oauth2.0服务登录,登录后再访问微服务网关,微服务网关将请求转发给其他微服务处理。
由于我们项目使用了微服务,任何用户都有可能使用任意微服务,此时我们需要控制相关权限,例如:普通用户角色不能使用用户的删除操作,只有管理员才可以使用,那么这个时候就需要使用到SpringSecurity的权限控制功能了。
角色权限加载
在changgou-user-oauth服务中,com.changgou.oauth.config.UserDetailsServiceImpl该类实现了加载用户相关信息,如下代码:
上述代码给登录用户定义了三个角色,分别为salesman
,accountant
,user
,这一块我们目前使用的是硬编码方式将角色写死了。
角色权限控制
在每个微服务中,需要获取用户的角色,然后根据角色识别是否允许操作指定的方法,Spring Security中定义了四个支持权限控制的表达式注解,分别是@PreAuthorize
、@PostAuthorize
、@PreFilter
和@PostFilter
。其中前两者可以用来在方法调用前或者调用后进行权限检查,后两者可以用来对集合类型的参数或者返回值进行过滤。在需要控制权限的方法上,我们可以添加@PreAuthorize
注解,用于方法执行前进行权限检查,校验用户当前角色是否能访问该方法。
(1)开启@PreAuthorize
在changgou-user-service
的ResourceServerConfig
类上添加@EnableGlobalMethodSecurity
注解,用于开启@PreAuthorize的支持,代码如下:
(2)方法权限控制
在changgoug-service-user
微服务的com.changgou.user.controller.UserController
类的delete()方法上添加权限控制注解@PreAuthorize
,代码如下:
(3)测试
我们使用Postman测试,先创建令牌,然后将令牌数存放到头文件中访问微服务网关来调用user微服务的search方法,效果如下:
地址:http://localhost:8001/api/user/search/1/10 提交方式:GET
发现上面无法访问,因为用户登录的时候,角色不包含admin角色,而search方法需要admin角色,所以被拦截了。
我们再测试其他方法,其他方法没有配置拦截,所以用户登录后就会放行。
访问http://localhost:8001/api/user
效果如下:
小结
如果希望一个方法能被多个角色访问,配置:@PreAuthorize("hasAnyAuthority('admin','user')")
如果希望一个类都能被多个角色访问,在类上配置:@PreAuthorize("hasAnyAuthority('admin','user')")