如果授权标头中缺少承载令牌,则不要将api请求重定向到登录页面

nkcskrwz  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(239)

我正在用SpringSecurity编写一个SpringBoot应用程序,它有一个RESTAPI和一个web界面。当用户未经过身份验证时,RESTAPI应该只返回 401 Unauthorized 而web界面应该重定向到登录页面。通过以下配置,这在以下情况下起作用:
如果承载令牌无效或过期
如果不存在授权标头
如果请求包含授权标头但没有,我无法做到的是有相同的行为 bearer 代币在这种情况下,无论是api请求还是“web”请求,请求总是重定向到登录页面。到目前为止,我发现防止这种情况发生的唯一方法是设置 bearer-only 设置为true,但之后不会再将任何请求重定向到登录页面。。。
是否有其他配置我可以尝试?谢谢!

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = [KeycloakSecurityComponents::class])
open class SecurityConfiguration : KeycloakWebSecurityConfigurerAdapter() {
    @Autowired
    fun configureGlobal(auth: AuthenticationManagerBuilder) {
        auth.authenticationProvider(keycloakAuthenticationProvider())
    }

    @Bean
    open fun keycloakConfigResolver(): KeycloakSpringBootConfigResolver {
        return KeycloakSpringBootConfigResolver()
    }

    @Bean
    override fun sessionAuthenticationStrategy(): SessionAuthenticationStrategy {
        return RegisterSessionAuthenticationStrategy(SessionRegistryImpl())
    }

    override fun authenticationEntryPoint(): AuthenticationEntryPoint? {
        val requestMatcher = NegatedRequestMatcher(
            OrRequestMatcher(
                WEBAPP_ANT_PATHS.map {
                    AntPathRequestMatcher(it)
                }
            )
        )

        return KeycloakAuthenticationEntryPoint(adapterDeploymentContext(), requestMatcher)
    }

    override fun configure(http: HttpSecurity) {
        super.configure(http)
        http.cors().and().csrf().disable()
            .authorizeRequests()
            .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
            .antMatchers("/actuator/health").permitAll()
            .antMatchers("/**").authenticated()
    }

    companion object {
        val WEBAPP_ANT_PATHS = listOf("/swagger-ui/**", "/swagger-ui.html")
    }
}
h5qlskok

h5qlskok1#

Spring 安全 BearerTokenAuthenticationFilter (及相应的 BearerTokenAuthenticationEntryPoint )当存在承载令牌时触发。
如果要调用 BearerTokenAuthenticationEntryPoint 在其他时候,您可以向全局异常处理程序注册它:

http
    .exceptionHandling((exceptions) -> exceptions
        .authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
    );

这将告诉spring security使用 BearerTokenAuthenticationEntryPoint 无论如何 AuthenticationException .
或者,如果您支持多个身份验证机制(如表单登录),则可以指定 RequestMatcher :

http
    .exceptionHandling((exceptions) -> exceptions
        .defaultAuthenticationEntryPointFor(
            new BearerTokenAuthenticationEntryPoint(),
            (request) -> request.getHeader("Authorization") != null
        )
    );

也就是说,如果使用Spring Security 而不使用KeyClope Package 器,您可能会获得更大的成功。原因是spring security现在提供了自己的承载令牌支持。

相关问题