Here is my code:
Security Config
@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
internal class WebAuthorizationConfig(
private val userDetailsManager: ReactiveUserDetailsManager,
@Qualifier("customPasswordEncoder") private val passwordEncoder: PasswordEncoder
) {
@Bean
fun configureSecurity(
http: ServerHttpSecurity,
requestValidationFilter: RequestValidationFilter,
): SecurityWebFilterChain {
http
.csrf { csrf -> csrf.disable() }
.addFilterBefore(validEndPointFilter, SecurityWebFiltersOrder.HTTP_BASIC)
.httpBasic { httpBasic ->
httpBasic.authenticationEntryPoint(customAuthenticationEntryPoint())
}
.authorizeExchange { authorize ->
authorize
.anyExchange().hasAuthority("WRITE")
}
.authenticationManager(customAuthenticationManager())
.securityContextRepository(customSecurityContextRepository())
return http.build()
}
@Bean
fun customAuthenticationManager(): ReactiveAuthenticationManager {
return CustomAuthenticationManager(userDetailsManager, passwordEncoder)
}
@Bean
fun customAuthenticationEntryPoint(): CustomAuthenticationEntryPoint {
return CustomAuthenticationEntryPoint()
}
@Bean
fun customSecurityContextRepository(): ServerSecurityContextRepository {
return CustomSecurityContextRepository()
}
}
Controller
@RestController
internal class UserController(
@Autowired
private val userService: UserServiceImpl,
) {
@GetMapping("/users/{uid}")
final suspend fun getUser(
@PathVariable("uid") uidString: String
): ResponseEntity<UserDTO> {
// validate user ID
val uid = userService.validateUserId(uidString)
// get from database inside this co-routine
return withContext(Dispatchers.IO) {
ResponseEntity.ok(userService.getUser(uid))
}
}
}
Service
@Service
internal class UserGetServiceDelegate(
@Autowired
private val userRepo: UserRepositoryImpl,
private val userDTOEntityMapMapper: UserDTOEntityMapMapperImpl,
private val userMapKeyRenamer: UserMapKeyRenamerImpl,
) : UserGetService {
@PreAuthorize("denyAll()")
final override suspend fun getUser(uid: ObjectId): UserDTO {
//** SIGNIFICANT DATABASE STEP **//
// attempt to get user from database
val userEntity = userRepo.getUser(uid)
?: throw ErrorManager.getException("service-user-does-not-exist")
// return retrieved user
return userDTOEntityMapMapper.fromEntity(userEntity)
}
}
Whatever I do, it still grants access to the sevice, and returns the result, despite having, @PreAuthorize(“denyAll()”), in the service?
There are loads of posts going back years, complaining about this. Some suggest adding this annotation @EnableReactiveMethodSecurity (already done). Some suggest removing final (but kotlin, if you remove the visibility modifier it is final by default, and when I chose open or sealed, they are grayed out, and my IDE says they are redundant)
None of them help though.
Any ideas?
Thanks in advance