-
Notifications
You must be signed in to change notification settings - Fork 3k
3.0 auth
hsweb 已实现权限控制api,基于注解。默认提供shiro实现。支持RBAC以及行级,列级的权限控制。
引入shiro实现
<dependency>
<groupId>org.hswebframework.web</groupId>
<artifactId>hsweb-authorization-shiro</artifactId>
<version>${project.version}</version>
</dependency>
方式1: 使用hsweb自带的注解 @Authorize
,例如:
@RestController
@RequestMapping("/foo")
@Authorize(permission = "foo")
public class MyController{
@RequestMapping("/test")
@Authorize(action = "read")
public ResponsMessage<Foo> test(){
return ok();
}
}
类上的注解 @Authorize(permission = "foo")
表示此类的所有请求都使用permission="foo",方法上的注解@Authorize(action = "read")
代表需要持有foo权限的read操作许可(默认是合并类上的注解).如果不想与类上的注解合并,可以使用 @Authorize(action = "read",merge=false)
Authorize
全部属性:
属性名 | 说明 |
---|---|
permission | 权限ID |
action | 事件(按钮) |
role | 角色ID |
user | 用户名 |
merge | 是否合并类上的注解 |
logical | 多个条件的验证逻辑,如 并且,或者 |
message | 验证失败时提示的消息 |
方式2: 使用shiro的注解,请查看shiro的相关文档,这里不再赘述。
可使用表达式注解@RequiresExpression
,
注解的value值为表达式内容,表达式默认为spel。可通过language属性指定语言,支持spel,ognl,js等
例如:
@RequestMapping("/test")
//如果food的type属性为1,则判断当前用户是否拥有admin权限
@RequiresExpression("#foo.type=1?hasRole('admin'):true")
public ResponsMessage<Foo> test(Foo foo){
return ok();
}
可使用注解'@RequiresDataAccess' 声明需要进行权限控制.注意:此注解仅为声明要控制,具体的控制方式,是由权限管理模块中进行配置的,如何配置,请看这里. 假设权限配置如下:
{
id:"test", //权限ID
dataAccesses:[
{
action:"query",//需要控制的操作事件
type:"OWN_CREATED" //控制方式
},{
action:"update", //需要控制的操作事件
type:"OWN_CREATED" //控制方式
}
]
}
表示: test的query和update操作,使用OWN_CREATED(只能操作自己创建的)方式进行控制。如何自定义控制?请看这里.
注意: OWN_CREATED为内置控制方式,需满足条件为: controller实现QueryController或者
接口,实体类实现RecordCreationEntity
.
例如:
@GetMapping("/test")
//声明此操作对应的权限,访问此方法时,将使用对应的配置进行控制
@RequiresDataAccess(permission = "test", action = "query")
public ResponsMessage<Foo> test(QueryParamEntity entity){
// entity将自动填充条件,最终应该生成的查询为: where creator_id=? and (前端提交的查询条件)
//....
return ok();
}
@PutMapping("/test")
//声明此操作对应的权限,访问此方法时,将使用对应的配置进行控制
//在执行此方法前,会先查询旧数据,判断其creator_id 是否与当前的登录用户相同。
@RequiresDataAccess(permission = "test/{id}", action = "update",idParamName="id")
public ResponsMessage<Foo> test(@PathVariable String id,@Foo foo){
//....
return ok();
}
列级权限控制依然使用 RequiresDataAccess
注解,权限配置如下:
{
id:"test", //权限ID
dataAccesses:[
{
action:"query",//需要控制的操作事件
type:"DENY_FIELDS", //控制方式,禁止操作
fields:["password"] //控制字段
},{
action:"update", //需要控制的操作事件
type:"DENY_FIELDS", //控制方式,禁止操作
fields:["password"]//控制字段
}
]
}
表示: test的权限的query
和update
操作.都将禁止操作password
字段。注意: 控制的方式说到底其实是改变实体的属性.因此需要orm的相关逻辑支持,比如不修改为null的值。
例如:
@GetMapping("/test")
//声明此操作对应的权限,访问此方法时,将使用对应的配置进行控制
@RequiresDataAccess(permission = "test", action = "query")
public ResponsMessage<Foo> test(QueryParamEntity entity){
// entity将自动设置excludes属性为["password"]
//....
return ok();
}
@PutMapping("/test")
//调用方法前,将设置foo的password属性为null。
@RequiresDataAccess(permission = "test/{id}", action = "update")
public ResponsMessage<Foo> test(@PathVariable String id,@Foo foo){
//....
return ok();
}
用户的权限信息是用 api中的 Authentication
接口进行保存,可通过多种方式获取:
- 静态方法:
Authentication.current().orElseThrow(AuthorizeException::new);
- 静态方法:
AuthenticationHolder.get()
- springmvc参数方式注入:
@PutMapping("/test")
public ResponsMessage<Foo> test(Authentication auth){
//....
return ok();
}