- Notifications
You must be signed in to change notification settings - Fork3k
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")publicclassMyController{@RequestMapping("/test")@Authorize(action ="read")publicResponsMessage<Foo>test(){returnok();}}
类上的注解@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")publicResponsMessage<Foo>test(Foofoo){returnok();}
可使用注解'@RequiresDataAccess' 声明需要进行权限控制.注意:此注解仅为声明要控制,具体的控制方式,是由权限管理模块中进行配置的,如何配置,请看这里.假设权限配置如下:
{id:"test",//权限IDdataAccesses:[{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")publicResponsMessage<Foo>test(QueryParamEntityentity){// entity将自动填充条件,最终应该生成的查询为: where creator_id=? and (前端提交的查询条件)//....returnok();}@PutMapping("/test")//声明此操作对应的权限,访问此方法时,将使用对应的配置进行控制//在执行此方法前,会先查询旧数据,判断其creator_id 是否与当前的登录用户相同。@RequiresDataAccess(permission ="test/{id}",action ="update",idParamName="id")publicResponsMessage<Foo>test(@PathVariableStringid,@Foofoo){//....returnok();}
列级权限控制依然使用RequiresDataAccess注解,权限配置如下:
{id:"test",//权限IDdataAccesses:[{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")publicResponsMessage<Foo>test(QueryParamEntityentity){// entity将自动设置excludes属性为["password"]//....returnok();}@PutMapping("/test")//调用方法前,将设置foo的password属性为null。@RequiresDataAccess(permission ="test/{id}",action ="update")publicResponsMessage<Foo>test(@PathVariableStringid,@Foofoo){//....returnok();}
用户的权限信息是用 api中的Authentication接口进行保存,可通过多种方式获取:
- 静态方法:
Authentication.current().orElseThrow(AuthorizeException::new); - 静态方法:
AuthenticationHolder.get() - springmvc参数方式注入:
@PutMapping("/test")publicResponsMessage<Foo>test(Authenticationauth){//....returnok();}