使用@Preauthorize 注释保护控制器不起作用

时间:2021-05-26 10:53:53

标签: kotlin spring-security

我正在尝试使用 Spring Security 来保护端点。但是代码似乎不起作用。不知道我哪里出错了。

我的安全类

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true,proxyTargetClass = true)
open class WebSecurity : WebSecurityConfigurerAdapter() {
    @Throws(Exception::class)
    override fun configure(http: HttpSecurity) {
        http.httpBasic()
                .and()
                .cors().and()
                .csrf().disable().authorizeRequests()
                .antMatchers("/authorize/users/*").permitAll()
                .anyRequest().authenticated().hasRole("MANAGER")
                .and()
                .formLogin()
    }

    @Bean
    public override fun userDetailsService(): UserDetailsService {

        //User Role
        val theUser = User.withUsername("sergey")
                .passwordEncoder { charSequence: String? -> PasswordEncoderFactories.createDelegatingPasswordEncoder().encode(charSequence) }
                .password("12345678").roles("USER").build()

        //Manager Role
        val theManager = User.withUsername("john")
                .password("87654321").roles("MANAGER").build()
        val userDetailsManager = InMemoryUserDetailsManager()
        userDetailsManager.createUser(theUser)
        userDetailsManager.createUser(theManager)
        return userDetailsManager
    }
}

控制器

 @RestController
    @RequestMapping("/authorize")
    open class AuthController {

   @PreAuthorize("hasRole('MANAGER')")
        @PostMapping("/users/add")
        fun createUsers(@RequestHeader("Authorization") token: String,
                             @RequestBody users: UserDTO) : ResponseEntity<Any> {
            lateinit var message: String
            try {
    
                val response = authService.insert(users, token)     
    
            }
            catch (exception: RuntimeException) {
                return ResponseEntity(exception.message, HttpStatus.INTERNAL_SERVER_ERROR)
            }
        }
    
        }

在 Postman 中,我设置了基本身份验证。仍然得到 401 未授权

enter image description here

1 个答案:

答案 0 :(得分:1)

401 Unauthorized 与无法识别或显示的凭据相关联。

我认为问题出在这里:

val theManager = User.withUsername("john")
        .password("87654321").roles("MANAGER").build()

如果没有编码前缀,Spring Security 在执行密码比较时可能会出错。

相反,做

val theManager = User.withUsername("john")
        .password("{noop}87654321").roles("MANAGER").build()

The {noop} hint 告诉 Spring Security 这个密码没有经过哈希处理。

调试技巧

如果这不能解决问题,请考虑将 antMatchers("/error").permitAll() 添加到您的授权请求列表中,并可能将堆栈简化为:

.authorizeRequests()
    .antMatchers("/error").permitAll()
    .anyRequest().authenticated()

这不会修复它,但打开 /error 端点可能会为您提供额外的调试信息。