本文小编为大家详细介绍“Spring Security基于注解的接口角色访问控制怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring Security基于注解的接口角色访问控制怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
1. 前言
DEMO 获取方式在文末。
2. Spring Security 方法安全
Spring Security 基于注解的安全认证是通过在相关的方法上进行安全注解标记来实现的。
2.1 开启全局方法安全
我们可以在任何 @Configuration实例上使用 @EnableGlobalMethodSecurity 注解来启用全局方法安全注解功能。该注解提供了三种不同的机制来实现同一种功能,所以我们单独开一章进行探讨。
3. @EnableGlobalMethodSecurity 注解
@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME) @Target(value = { java.lang.annotation.ElementType.TYPE }) @Documented @Import({ GlobalMethodSecuritySelector.class }) @EnableGlobalAuthentication @Configuration public @interface EnableGlobalMethodSecurity { /** * 基于表达式进行方法访问控制 */ boolean prePostEnabled() default false; /** * 基于 @Secured 注解 */ boolean securedEnabled() default false; /** * 基于 JSR-250 注解 */ boolean jsr250Enabled() default false; boolean proxyTargetClass() default false; int order() default Ordered.LOWEST_PRECEDENCE; }
@EnableGlobalMethodSecurity 源码中提供了 prePostEnabled 、securedEnabled 和 jsr250Enabled 三种方式。当你开启全局基于注解的方法安全功能时,也就是使用 @EnableGlobalMethodSecurity 注解时我们需要选择使用这三种的一种或者其中几种。我们接下来将分别介绍它们。
4. 使用 prePostEnabled
如果你在 @EnableGlobalMethodSecurity 设置 prePostEnabled 为 true ,则开启了基于表达式的方法安全控制。通过表达式运算结果的布尔值来决定是否可以访问(true 开放, false 拒绝 )。
有时您可能需要执行开启 prePostEnabled 复杂的操作。对于这些实例,您可以扩展 GlobalMethodSecurityConfiguration,确保子类上存在@EnableGlobalMethodSecurity(prePostEnabled = true) 。例如,如果要提供自定义 MethodSecurityExpressionHandler :
@EnableGlobalMethodSecurity(prePostEnabled = true) public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { @Override protected MethodSecurityExpressionHandler createExpressionHandler() { // ... create and return custom MethodSecurityExpressionHandler ... return expressionHandler; } }
上面示例属于高级操作,一般没有必要。无论是否继承GlobalMethodSecurityConfiguration 都将会开启四个注解。 @PreAuthorize 和 @PostAuthorize 侧重于方法调用的控制;而 @PreFilter 和 @PostFilter 侧重于数据的控制。
4.1 @PreAuthorize
在标记的方法调用之前,通过表达式来计算是否可以授权访问。接下来我来总结以下常用的表达式。
基于 SecurityExpressionOperations 接口的表达式,也就是我们在上一文的 javaConfig 配置。示例: @PreAuthorize("hasRole('ADMIN')") 必须拥有 ROLE_ADMIN 角色。
基于 UserDetails 的表达式,此表达式用以对当前用户的一些额外的限定操作。示例:@PreAuthorize("principal.username.startsWith('Felordcn')") 用户名开头为 Felordcn 的用户才能访问。
基于对入参的 SpEL表达式处理。 示例: @PreAuthorize("#id.equals(principal.username)") 入参 id 必须同当前的用户名相同。
4.2 @PostAuthorize
在标记的方法调用之后,通过表达式来计算是否可以授权访问。该注解是针对 @PreAuthorize 。区别在于先执行方法。而后进行表达式判断。如果方法没有返回值实际上等于开放权限控制;如果有返回值实际的结果是用户操作成功但是得不到响应。
4.3 @PreFilter
基于方法入参相关的表达式,对入参进行过滤。分页慎用!该过程发生在接口接收参数之前。 入参必须为 java.util.Collection 且支持 remove(Object) 的参数。如果有多个集合需要通过 filterTarget=<参数名> 来指定过滤的集合。内置保留名称 filterObject 作为集合元素的操作名来进行评估过滤。
样例:
// 入参为Collection<String> ids 测试数据 ["Felordcn","felord","jetty"] // 过滤掉 felord jetty 为 Felordcn @PreFilter(value = "filterObject.startsWith('F')",filterTarget = "ids") // 如果 当前用户持有 ROLE_AD 角色 参数都符合 否则 过滤掉不是 f 开头的 // DEMO 用户不持有 ROLE_AD 角色 故而 集合只剩下 felord @PreFilter("hasRole('AD') or filterObject.startsWith('f')")
4.4 @PostFilter
和@PreFilter 不同的是, 基于返回值相关的表达式,对返回值进行过滤。分页慎用!该过程发生接口进行数据返回之前。
5. 使用 securedEnabled
如果你在 @EnableGlobalMethodSecurity 设置 securedEnabled 为 true ,就开启了角色注解 @Secured ,该注解功能要简单的多,默认情况下只能基于角色(默认需要带前缀 ROLE_)集合来进行访问控制决策。
该注解的机制是只要其声明的角色集合(value)中包含当前用户持有的任一角色就可以访问。也就是 用户的角色集合和 @Secured 注解的角色集合要存在非空的交集。 不支持使用 SpEL 表达式进行决策。
6. 使用 jsr250Enabled
启用 JSR-250 安全控制注解,这属于 JavaEE 的安全规范(现为 jakarta 项目)。一共有五个安全注解。如果你在 @EnableGlobalMethodSecurity 设置 jsr250Enabled 为 true ,就开启了 JavaEE 安全注解中的以下三个:
@DenyAll 拒绝所有的访问
@PermitAll 同意所有的访问
@RolesAllowed 用法和 5. 中的 @Secured 一样。
读到这里,这篇“Spring Security基于注解的接口角色访问控制怎么实现”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。