【发布时间】:2019-01-06 23:00:46
【问题描述】:
我有一个自定义身份验证方案。我有一个 REST 端点,它在 http uri 路径中有 userId,在 http 标头中有 token。我想检查此类请求是否由具有有效令牌的有效用户执行。用户和令牌存储在 mongo 集合中。
我不知道我应该在哪个类中授权用户。
我的SecurityConfig:
@EnableWebFluxSecurity
class SecurityConfig {
@Bean
fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
val build = http
.httpBasic().disable()
.formLogin().disable()
.csrf().disable()
.logout().disable()
.authenticationManager(CustomReactiveAuthenticationManager())
.securityContextRepository(CustomServerSecurityContextRepository())
.authorizeExchange().pathMatchers("/api/measurement/**").hasAuthority("ROLE_USER")
.anyExchange().permitAll().and()
return build.build()
}
@Bean
fun userDetailsService(): MapReactiveUserDetailsService {
val user = User.withDefaultPasswordEncoder()
.username("sampleDeviceIdV1")
.password("foo")
.roles("USER")
.build()
return MapReactiveUserDetailsService(user)
}
}
我的ServerSecurityContextRepository:
class CustomServerSecurityContextRepository : ServerSecurityContextRepository {
override fun load(exchange: ServerWebExchange): Mono<SecurityContext> {
val authHeader = exchange.request.headers.getFirst(HttpHeaders.AUTHORIZATION)
val path = exchange.request.uri.path
return if (path.startsWith("/api/measurement/") && authHeader != null && authHeader.startsWith(prefix = "Bearer ")) {
val deviceId = path.drop(17)
val authToken = authHeader.drop(7)
val auth = UsernamePasswordAuthenticationToken(deviceId, authToken)
Mono.just(SecurityContextImpl(auth))
} else {
Mono.empty()
}
}
override fun save(exchange: ServerWebExchange?, context: SecurityContext?): Mono<Void> {
return Mono.empty()
}
}
出现两个问题:
ServerSecurityContextRepository是从交易所获取用户名和令牌的好地方 - 还是有更好的地方来做?我应该在哪里执行身份验证(根据 mongo 集合检查令牌和用户名)? 我的自定义
AuthenticationManager不会在任何地方被调用。我应该在ServerSecurityContextRepository内执行所有操作还是在ReactiveAuthenticationManager内执行用户和令牌验证?或者其他班级可能更合适?
【问题讨论】:
标签: spring-boot spring-security kotlin spring-webflux