如果授权中缺少承载令牌,请不要将 API 请求重定向到登录页面 header
Do not redirect API request to login page if bearer token is missing in authorisation header
我正在编写 Spring 具有 Spring 安全性的引导应用程序,它具有 REST API 和 Web 界面。当用户未通过身份验证时,REST API 应该只是 return 401 Unauthorized
而 Web 界面应该重定向到登录页面。使用下面的配置,这在以下情况下有效:
- 如果不记名令牌无效或过期
- 如果没有授权 header
如果请求包含授权 header 但 没有 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")
}
}
Spring 安全的 BearerTokenAuthenticationFilter
(以及相应的 BearerTokenAuthenticationEntryPoint
)在存在不记名令牌时被触发。
如果你想在其他时间调用BearerTokenAuthenticationEntryPoint
,你可以在全局异常处理程序中注册它:
http
.exceptionHandling((exceptions) -> exceptions
.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
);
这将告诉 Spring 安全对任何 AuthenticationException
.
使用 BearerTokenAuthenticationEntryPoint
或者,如果您支持多种身份验证机制(例如表单登录),那么您可以指定 RequestMatcher
:
http
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new BearerTokenAuthenticationEntryPoint(),
(request) -> request.getHeader("Authorization") != null
)
);
也就是说,使用 Spring 安全性而不使用 Keycloak 包装器可能会取得更大的成功。这样做的原因是 Spring 安全性现在随 its own bearer token support.
一起提供
我正在编写 Spring 具有 Spring 安全性的引导应用程序,它具有 REST API 和 Web 界面。当用户未通过身份验证时,REST API 应该只是 return 401 Unauthorized
而 Web 界面应该重定向到登录页面。使用下面的配置,这在以下情况下有效:
- 如果不记名令牌无效或过期
- 如果没有授权 header
如果请求包含授权 header 但 没有 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")
}
}
Spring 安全的 BearerTokenAuthenticationFilter
(以及相应的 BearerTokenAuthenticationEntryPoint
)在存在不记名令牌时被触发。
如果你想在其他时间调用BearerTokenAuthenticationEntryPoint
,你可以在全局异常处理程序中注册它:
http
.exceptionHandling((exceptions) -> exceptions
.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
);
这将告诉 Spring 安全对任何 AuthenticationException
.
BearerTokenAuthenticationEntryPoint
或者,如果您支持多种身份验证机制(例如表单登录),那么您可以指定 RequestMatcher
:
http
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new BearerTokenAuthenticationEntryPoint(),
(request) -> request.getHeader("Authorization") != null
)
);
也就是说,使用 Spring 安全性而不使用 Keycloak 包装器可能会取得更大的成功。这样做的原因是 Spring 安全性现在随 its own bearer token support.
一起提供