SpringSecurity系列——访问控制之基于方法的控制day6-3(源于官网5.7.2版本)

181 篇文章 3 订阅
24 篇文章 31 订阅

方法安全表达式

方法安全性比简单的允许或拒绝规则要复杂一些。 Spring Security 3.0 引入了一些新的注解,以便全面支持表达式的使用。

EnableMethodSecurity(启用方法安全)

在 Spring Security 5.6 中,我们可以在任何 @Configuration 实例上使用 @EnableMethodSecurity 注解启用基于注解的安全性。

这以多种方式改进了@EnableGlobalMethodSecurity。 @EnableMethodSecurity:

  1. 使用简化的 AuthorizationManager API,而不是元数据源、配置属性、决策管理器和选民。 这简化了重用和定制。
  2. 支持直接基于 bean 的配置,而不是需要扩展 GlobalMethodSecurityConfiguration 来自定义 bean
  3. 使用原生 Spring AOP 构建,去除抽象并允许您使用 Spring AOP 构建块进行自定义
  4. 检查冲突的注释以确保明确的安全配置
  5. 符合 JSR-250
  6. 默认启用@PreAuthorize、@PostAuthorize、@PreFilter 和@PostFilter

关于@Pre 和 @Post 注释

有四个注释支持表达式属性,以允许调用前和调用后的授权检查,还支持过滤提交的集合参数或返回值。 他们是 @PreAuthorize, @PreFilter, @PostAuthorize和 @PostFilter

关于@PreAuthorize

在方法执行前进行判断
最明显有用的注释是 @PreAuthorize它决定了是否可以实际调用方法

@PreAuthorize("hasRole('USER')")
public void create(Contact contact);

这意味着只有角色为“ROLE_USER”的用户才允许访问。 显然,使用传统配置和所需角色的简单配置属性可以轻松实现相同的目标

@PreAuthorize实例

当然在注解中也可以对各种权限判断策略进行判断,使用这个注解的形式就不用进行配置了
在这里插入图片描述

1.在SpringSecurity上开启方法安全

@EnableMethodSecurity
@EnableWebSecurity
@Configuration
public class SpringSecurityConfig {}

2.在需要权限控制方法上加注解

	@PreAuthorize("hasAuthority('ROLE_admin')")
    @GetMapping("/test7")
    public String tt6() {
        return "/test7....";
    }

关于@PostAuthorize

@PostAuthorize注解其实使用的并不多,因为是在方法执行结束之后对于权限进行判断

Customizing Authorization(自定义授权)

Spring Security 的@PreAuthorize、@PostAuthorize、@PreFilter 和@PostFilter 提供了丰富的基于表达式的支持。

如果您需要自定义处理表达式的方式,您可以公开一个自定义 MethodSecurityExpressionHandler,就像这样

自定义 MethodSecurityExpressionHandler

@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler() {
	DefaultMethodSecurityExpressionHandler handler = new DefaultMethodSecurityExpressionHandler();
	handler.setTrustResolver(myCustomTrustResolver);
	return handler;
}

我们使用静态方法暴露 MethodSecurityExpressionHandler 以确保 Spring 在初始化 Spring Security 的方法安全 @Configuration 类之前发布它

此外,对于基于角色的授权,Spring Security 添加了一个默认的 ROLE_ 前缀,用于评估像 hasRole 这样的表达式。

您可以通过公开 GrantedAuthorityDefaults bean 来配置授权规则以使用不同的前缀,如下所示

示例 :自定义 MethodSecurityExpressionHandler

@Bean
static GrantedAuthorityDefaults grantedAuthorityDefaults() {
	return new GrantedAuthorityDefaults("MYPREFIX_");
}

我们使用静态方法暴露 GrantedAuthorityDefaults 以确保 Spring 在初始化 Spring Security 的方法 security @Configuration 类之前发布它

Custom Authorization Managers(自定义授权管理器)

方法授权是方法前授权和方法后授权的组合。

方法前授权是在调用方法之前执行的。 如果该授权拒绝访问,则不调用该方法,并抛出 AccessDeniedException 方法后授权在调用该方法之后,但在该方法返回给调用者之前执行。 如果该授权拒绝访问,则不返回该值,并抛出 AccessDeniedException

要重新创建默认情况下添加 @EnableMethodSecurity 所做的事情,您将发布以下配置

完整的前置后置方法安全配置

@EnableMethodSecurity(prePostEnabled = false)
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor preFilterAuthorizationMethodInterceptor() {
		return new PreFilterAuthorizationMethodInterceptor();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor preAuthorizeAuthorizationMethodInterceptor() {
		return AuthorizationManagerBeforeMethodInterceptor.preAuthorize();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor postAuthorizeAuthorizationMethodInterceptor() {
		return AuthorizationManagerAfterMethodInterceptor.postAuthorize();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor postFilterAuthorizationMethodInterceptor() {
		return new PostFilterAuthorizationMethodInterceptor();
	}
}

请注意,Spring Security 的方法安全性是使用 Spring AOP 构建的。 因此,拦截器是根据指定的顺序调用的。 这可以通过在拦截器实例上调用 setOrder 来定制,如下所示

发布自定义顾问

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Advisor postFilterAuthorizationMethodInterceptor() {
	PostFilterAuthorizationMethodInterceptor interceptor = new PostFilterAuthorizationMethodInterceptor();
	interceptor.setOrder(AuthorizationInterceptorOrders.POST_AUTHORIZE.getOrder() - 1);
	return interceptor;
}

仅@PreAuthorize 配置

您可能只想在应用程序中支持 @PreAuthorize,在这种情况下,您可以执行以下操作:

@EnableMethodSecurity(prePostEnabled = false)
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor preAuthorize() {
		return AuthorizationManagerBeforeMethodInterceptor.preAuthorize();
	}
}

或者,您可能有一个要添加到列表中的自定义方法前 AuthorizationManager。

在这种情况下,您需要告诉 Spring Security AuthorizationManager 以及您的授权管理器适用于哪些方法和类。

因此,您可以配置 Spring Security 以在 @PreAuthorize 和 @PostAuthorize 之间调用您的 AuthorizationManager,如下所示:

建议之前的自定义

@EnableMethodSecurity
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public Advisor customAuthorize() {
		JdkRegexpMethodPointcut pattern = new JdkRegexpMethodPointcut();
		pattern.setPattern("org.mycompany.myapp.service.*");
		AuthorizationManager<MethodInvocation> rule = AuthorityAuthorizationManager.isAuthenticated();
		AuthorizationManagerBeforeMethodInterceptor interceptor = new AuthorizationManagerBeforeMethodInterceptor(pattern, rule);
		interceptor.setOrder(AuthorizationInterceptorsOrder.PRE_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1);
		return interceptor;
    }
}

您可以使用 AuthorizationInterceptorsOrder 中指定的顺序常量将拦截器放置在 Spring Security 方法拦截器之间。
对于后方法授权也可以这样做。 方法后授权通常涉及分析返回值以验证访问。

例如,您可能有一个方法可以确认请求的帐户实际上属于登录用户,如下所示:

@PostAuthorize 示例

@EnableMethodSecurity
class MethodSecurityConfig {
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public Advisor customAuthorize(AuthorizationManager<MethodInvocationResult> rules) {
		AnnotationMethodMatcher pattern = new AnnotationMethodMatcher(MySecurityAnnotation.class);
		AuthorizationManagerAfterMethodInterceptor interceptor = new AuthorizationManagerAfterMethodInterceptor(pattern, rules);
		interceptor.setOrder(AuthorizationInterceptorsOrder.POST_AUTHORIZE_ADVISOR_ORDER.getOrder() + 1);
		return interceptor;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值