想要控制好权限,这8个注解必须知道!

发布时间:2025-05-19 01:48:04 作者:益华网络 来源:undefined 浏览量(3) 点赞(3)
摘要:来源:码猿技术专栏 在码猿慢病云管理系统采用的是Spring Cloud 集成Spring Security OAuth2的方式实现认证、鉴权,其中涉及到的一个重要问题则是数据权限的过滤,今天就来介绍一下实现的方案。 在之前的文章中曾经介绍过通过自定义的三个

来源:码猿技术专栏

在码猿慢病云管理系统采用的是Spring Cloud 集成Spring Security OAuth2的方式实现认证、鉴权,其中涉及到的一个重要问题则是数据权限的过滤,今天就来介绍一下实现的方案。

在之前的文章中曾经介绍过通过自定义的三个注解 @RequiresLogin@RequiresPermissions@RequiresRoles 实现微服务的鉴权其实就是参考Spring Security 内置的注解实现,有想要了解的请看:3 个注解,优雅的实现微服务鉴权

在介绍数据权限之前,先来看下Spring Security 中内置的8个权限注解,只有理解了这8个注解,对于理解码猿慢病云管理系统中的实现方案就非常easy了。

Spring Security 内置的权限注解是将鉴权下放到各个微服务,想要了解在网关处统一鉴权处理的请看之前分享的文章:实战干货!Spring Cloud Gateway 整合 OAuth2.0 实现分布式统一认证授权!

码猿慢病云管理系统已在星球中持续更新,想要加入的私信!

Spring Security 中的权限注解

Spring Security 中支持多种数据权限注解,若想使用内置的注解,首先需要通过@EnableGlobalMethodSecurity这个注解开启权限注解的支持,代码如下:

/**

 * @author

 公众号:码猿技术专栏

 * 自定义资源服务注解

 * {@link

 com.code.ape.codeape.common.security.annotation.EnableCodeapeResourceServer}

 */
@Documented@Inherited@Target

({ ElementType.TYPE })

@Retention

(RetentionPolicy.RUNTIME)

@EnableGlobalMethodSecurity(prePostEnabled = true

)

@Import({ CodeapeResourceServerAutoConfiguration.classCodeapeResourceServerConfiguration.class

 })

public @interface EnableCodeapeResourceServer 

{}

在码猿慢病云管理系统中是将Spring Security集成为一个Spring Boot Starter,因此需要一个直接开启对于Spring Security的支持,EnableCodeapeResourceServer是自定义的资源服务注解,便于一键导入资源服务配置,只要是资源服务,只需要在资源服务配置类上添加这个注解即可。

比如设备服务(codeape-device-biz)的启动类如下:

如果是直接集成Spring Security ,那么直接在配置类标注@EnableGlobalMethodSecurity这个注解也是一样效果,代码如下:

@Configuration@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true, jsr250Enabled = true

)

public class SecurityConfig extends WebSecurityConfigurerAdapter 

{

}

@EnableGlobalMethodSecurity注解的三个属性如下:

prePostEnabled:设置为true,将会开启 Spring Security 提供的四个权限注解,@PostAuthorize、@PostFilter、@PreAuthorize 以及 @PreFilter,这四个注解支持权限表达式,支持 SpEL,功能比较丰富。securedEnabled:设置为true,将会开启 Spring Security 提供的 @Secured 注解,该注解不支持权限表达式。jsr250Enabled:设置为true,将会开启 JSR-250 提供的注解,主要包括 @DenyAll、@PermitAll 以及 @RolesAllowed 三个注解,这些注解也不支持权限表达式。

以上的8个注解总结如下:

@PostAuthorize:在目标方法执行之后进行权限校验。@PostFilter:在目标方法执行之后对方法的返回结果进行过滤。@PreAuthorize:在目标方法执行之前进行权限校验。@PreFilter:在目标方法执行之前对方法参数进行过滤。@Secured:访问目标方法必须具备相应的角色。@DenyAll:拒绝所有访问。@PermitAll:允许所有访问。@RolesAllowed:访问目标方法必须具备相应的角色。

其实在日常开发中使用前四个注解已经完全够用,且支持灵活的SPEL权限表达式,方便定制。因此只需要设置prePostEnabled = true

权限注解使用

接下来就来简单介绍一下这8个权限注解的使用。

1. @PreAuthorize

@PreAuthorize这个注解在方法执行之前进行安全校验,支持SPEL,比如在接口使用代码如下:

@RestController@RequestMappingpublic class HelloService 

{

    @PreAuthorize("hasRole(IN_HOS_NURSE)"

)

    @GetMapping    public String hello() 

{

        return "hello"

;

    }

}

@PreAuthorize("hasRole(IN_HOS_NURSE)")代码含义则是只有拥有住院护士的角色的用户才能访问这个接口。这里用到了hasRole这个权限表达式,表示拥有某个角色

2. @PreFilter

@PreFilter这个注解主要是对参数进行过滤,其中两个属性如下:

value :SPEL表达式校验filterTarget:多个参数的情况下,指定对某个参数校验

使用如下:

@RestController@RequestMappingpublic class HelloService 

{

    @PreFilter(value = "obj.id!=1",filterTarget = "users"

)

    @GetMapping    public String hello(List<Obj> obj,Integer a) 

{

        return "hello"

;

    }

}

3. @PostAuthorize

@PostAuthorize是在方法执行之后进行数据校验,平常所有的数据校验一般是在方法执行之前,所以一般结合@PreAuthorize使用。

PostAuthorize中内置了一个returnObject返回值,对方法的返回值校验,使用如下:

@RestController@RequestMappingpublic class HelloService 

{

    @PostAuthorize(value = "returnObject.id==1"

)

    @GetMapping    public Obj hello(List<Obj> obj,Integer a) 

{

        return "hello"

;

    }

}

这个接口的返回值的id必须等于1才会通过,否则将会抛出异常。

4. @PostFilter

@PostFilter 注解是在目标方法执行之后,对目标方法的返回结果进行过滤,该注解中包含了一个内置对象 filterObject,表示目标方法返回的集合/数组中的具体元素:

@RestController@RequestMappingpublic class HelloService 

{

    @PostFilter(value = "filterObject.id==1"

)

    @GetMapping    public Obj hello(List<Obj> obj,Integer a) 

{

        return "hello"

;

    }

}

5. @Secured

@Secured 注解也是 Spring Security 提供的权限注解,不同于前面四个注解,该注解不支持权限表达式,只能做一些简单的权限描述。

使用如下:

@RestController@RequestMappingpublic class HelloService 

{

    @Secured({"ROLE_IN_HOS_NURSE","ROLE_IN_HOS_DOC"

})

    @GetMapping    public Obj hello(List<Obj> obj,Integer a) 

{

        return "hello"

;

    }

}

这段代码表示只有当前用户拥有住院护士、住院医生的权限才能访问这个接口。

@Secured能够做的,@PreAuthorize也都能做,且给的更多!

6. @DenyAll

@DenyAll 是 JSR-250 提供的方法注解,顾名思义,拒绝所有请求。

@RestController@RequestMappingpublic class HelloService 

{

    @DenyAll    @GetMapping    public String hello() 

{

        return "hello"

;

    }

}

7. @PermitAll

@PermitAll 也是 JSR-250 提供的方法注解,顾名思义,允许所有访问!

@RestController@RequestMappingpublic class HelloService 

{

    @PermitAll    @GetMapping    public String hello() 

{

        return "hello"

;

    }

}

8. @RolesAllowed

@RolesAllowed 也是 JSR-250 提供的注解,可以添加在方法上或者类上,当添加在类上时,表示该注解对类中的所有方法生效;如果类上和方法上都有该注解,并且起冲突,则以方法上的注解为准。

@RestController@RequestMappingpublic class HelloService 

{

    @RolesAllowed({"IN_HOS_NURSE","IN_HOS_DOC"

})

    @GetMapping    public Obj hello(List<Obj> obj,Integer a) 

{

        return "hello"

;

    }

}

这段代码表示只有当前用户拥有住院护士、住院医生的权限才能访问这个接口。

根据上述的介绍,大致理解了这8个注解,实际项目中建议使用@PostAuthorize、@PostFilter、@PreAuthorize 以及 @PreFilter这四个注解,完全够用了!

慢病云管理系统的实践

在码猿慢病云管理系统中使用的权限注解是@PreAuthorize,在接口执行之前对数据权限进行校验。

比如住院服务codeape-inhos-biz中的分页查询住院患者接口如下:

这里的@PreAuthorize("@pms.hasPermission(inhos_patinfohot_get)" )则是对用户的权限进行拦截校验,只有拥有inhos_patinfohot_get权限的用户才能访问这个接口。

而这里是直接通过SPEL表达式调用IOC容器中的方法进行拦截校验,代码如下:

com.code.ape.codeape.common.security.component.PermissionService#hasPermission

逻辑很简单,从SecurityContext中获取用户的权限和指定的权限进行比较,校验通过则返回true。

总结

本篇文章介绍了Spring Security 中内置的8个权限注解以及码猿慢病云管理系统中的实践,这个权限注解的使用是必须将权限下放到微服务鉴权才能用到,如果你的系统是在网关处统一鉴权则用不到。

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!