Spring security Spring被动安全性|如何实现被动许可评估器
假设我们得到一个带注释的rest控制器方法:Spring security Spring被动安全性|如何实现被动许可评估器,spring-security,spring-webflux,Spring Security,Spring Webflux,假设我们得到一个带注释的rest控制器方法: @PreAuthorize("hasPermission(#username, 'USER_PROFILE', 'WRITE')") 在SpringMVC中,我们将实现一个PermissionEvaluator,以实现隐藏在以下方法签名后面的授权 boolean hasPermission( Authentication authentication, Serializable targetId, String targetType
@PreAuthorize("hasPermission(#username, 'USER_PROFILE', 'WRITE')")
在SpringMVC中,我们将实现一个PermissionEvaluator
,以实现隐藏在以下方法签名后面的授权
boolean hasPermission(
Authentication authentication,
Serializable targetId,
String targetType,
Object permission
)
在使用SpringWebFlux时,只要您不需要在hasPermission方法中调用反应式服务/方法,这似乎仍然有效,我想这种情况很少发生,因为您通常也希望在数据库层中使用反应式接口。如果您无论如何都要在这个方法中调用一个反应式服务,那么您将需要在某个时间调用一些Mono
上的block()
,因此会遇到麻烦,因为您是从反应式管道中调用的
在关于Spring WebFlux安全性的教程中,他解释了如何通过提供自定义ReactiveAuthorizationManager
s,使用路径匹配器直接在SecurityWebFilterchain
上实现授权。但是没有解释如何在SpringWebFlux中使用预授权
注释
我希望实现一些ReactivePermissionEvaluator
Mono<Boolean> hasPermission(
Authentication authentication,
Serializable targetId,
String targetType,
Object permission
)
Mono拥有权限(
身份验证,
可序列化的targetId,
字符串targetType,
对象权限
)
这将允许在实现中使用反应式服务,但我无法找到任何ReactiveAuthorizationManager
的实现,该实现将扫描预授权
注释并将评估发送给反应式许可评估者
ReactivePermissionEvaluator
接口存在
因此,最后的问题是,如何实现一个反应式
许可评估器
,它允许调用反应式服务,例如在不阻塞的情况下查询数据库中的自动化信息 遗憾的是。。。Spring Security在中还不支持这一点,下面是您应该如何做到这一点。只需从applicationContext获取DefaultMethodSecurityExpressionHandler bean并显式替换PermissionsValuator
@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfiguration {
@Autowire
private ApplicationContext applicationContext;
@Bean
@DependsOn({"methodSecurityExpressionHandler"})
public SecurityWebFilterChain springSecurityFilterChain(
ServerHttpSecurity http) {
DefaultMethodSecurityExpressionHandler defaultWebSecurityExpressionHandler = this.applicationContext.getBean(DefaultMethodSecurityExpressionHandler.class);
defaultWebSecurityExpressionHandler.setPermissionEvaluator(permissionEvaluator());
return http.csrf().disable()
.httpBasic().disable()
.formLogin().disable()
.logout().disable()
.securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
.addFilterAt(tokenAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
.authorizeExchange()
.anyExchange().authenticated()
.and().build();
}
PermissionEvaluator permissionEvaluator() {
return new PermissionEvaluator() {
@Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
//Custom logic to evaluate @PreAuthorize("hasPermission('123', '123')")
return false;
}
@Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
//Custom logic to evaluate @PreAuthorize("hasPermission('123', '123','123')")
return false;
}
};
}