Malformed Bearer Token Returns 401 for WebFlux
Fixes gh-7668
This commit is contained in:
parent
4706b16a2b
commit
cb7786bf97
|
@ -55,6 +55,7 @@ import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
import org.springframework.security.authorization.ReactiveAuthorizationManager;
|
import org.springframework.security.authorization.ReactiveAuthorizationManager;
|
||||||
import org.springframework.security.config.Customizer;
|
import org.springframework.security.config.Customizer;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.authority.AuthorityUtils;
|
import org.springframework.security.core.authority.AuthorityUtils;
|
||||||
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
|
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
|
||||||
|
@ -105,6 +106,7 @@ import org.springframework.security.web.server.DelegatingServerAuthenticationEnt
|
||||||
import org.springframework.security.web.server.MatcherSecurityWebFilterChain;
|
import org.springframework.security.web.server.MatcherSecurityWebFilterChain;
|
||||||
import org.springframework.security.web.server.SecurityWebFilterChain;
|
import org.springframework.security.web.server.SecurityWebFilterChain;
|
||||||
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
|
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
|
||||||
|
import org.springframework.security.web.server.WebFilterExchange;
|
||||||
import org.springframework.security.web.server.authentication.AnonymousAuthenticationWebFilter;
|
import org.springframework.security.web.server.authentication.AnonymousAuthenticationWebFilter;
|
||||||
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;
|
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;
|
||||||
import org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint;
|
import org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint;
|
||||||
|
@ -1823,6 +1825,28 @@ public class ServerHttpSecurity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class BearerTokenAuthenticationWebFilter extends AuthenticationWebFilter {
|
||||||
|
private ServerAuthenticationFailureHandler authenticationFailureHandler;
|
||||||
|
|
||||||
|
BearerTokenAuthenticationWebFilter(ReactiveAuthenticationManager authenticationManager) {
|
||||||
|
super(authenticationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||||
|
WebFilterExchange webFilterExchange = new WebFilterExchange(exchange, chain);
|
||||||
|
return super.filter(exchange, chain)
|
||||||
|
.onErrorResume(AuthenticationException.class, e -> this.authenticationFailureHandler
|
||||||
|
.onAuthenticationFailure(webFilterExchange, e));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAuthenticationFailureHandler(ServerAuthenticationFailureHandler authenticationFailureHandler) {
|
||||||
|
super.setAuthenticationFailureHandler(authenticationFailureHandler);
|
||||||
|
this.authenticationFailureHandler = authenticationFailureHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures JWT Resource Server Support
|
* Configures JWT Resource Server Support
|
||||||
*/
|
*/
|
||||||
|
@ -1896,7 +1920,7 @@ public class ServerHttpSecurity {
|
||||||
|
|
||||||
protected void configure(ServerHttpSecurity http) {
|
protected void configure(ServerHttpSecurity http) {
|
||||||
ReactiveAuthenticationManager authenticationManager = getAuthenticationManager();
|
ReactiveAuthenticationManager authenticationManager = getAuthenticationManager();
|
||||||
AuthenticationWebFilter oauth2 = new AuthenticationWebFilter(authenticationManager);
|
AuthenticationWebFilter oauth2 = new BearerTokenAuthenticationWebFilter(authenticationManager);
|
||||||
oauth2.setServerAuthenticationConverter(bearerTokenConverter);
|
oauth2.setServerAuthenticationConverter(bearerTokenConverter);
|
||||||
oauth2.setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(entryPoint));
|
oauth2.setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(entryPoint));
|
||||||
http
|
http
|
||||||
|
@ -2002,7 +2026,7 @@ public class ServerHttpSecurity {
|
||||||
|
|
||||||
protected void configure(ServerHttpSecurity http) {
|
protected void configure(ServerHttpSecurity http) {
|
||||||
ReactiveAuthenticationManager authenticationManager = getAuthenticationManager();
|
ReactiveAuthenticationManager authenticationManager = getAuthenticationManager();
|
||||||
AuthenticationWebFilter oauth2 = new AuthenticationWebFilter(authenticationManager);
|
AuthenticationWebFilter oauth2 = new BearerTokenAuthenticationWebFilter(authenticationManager);
|
||||||
oauth2.setServerAuthenticationConverter(bearerTokenConverter);
|
oauth2.setServerAuthenticationConverter(bearerTokenConverter);
|
||||||
oauth2.setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(entryPoint));
|
oauth2.setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(entryPoint));
|
||||||
http.addFilterAt(oauth2, SecurityWebFiltersOrder.AUTHENTICATION);
|
http.addFilterAt(oauth2, SecurityWebFiltersOrder.AUTHENTICATION);
|
||||||
|
|
|
@ -172,6 +172,17 @@ public class OAuth2ResourceServerSpecTests {
|
||||||
.expectHeader().value(HttpHeaders.WWW_AUTHENTICATE, startsWith("Bearer error=\"invalid_token\""));
|
.expectHeader().value(HttpHeaders.WWW_AUTHENTICATE, startsWith("Bearer error=\"invalid_token\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getWhenEmptyBearerTokenThenReturnsInvalidToken() {
|
||||||
|
this.spring.register(PublicKeyConfig.class).autowire();
|
||||||
|
|
||||||
|
this.client.get()
|
||||||
|
.headers(headers -> headers.add("Authorization", "Bearer "))
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isUnauthorized()
|
||||||
|
.expectHeader().value(HttpHeaders.WWW_AUTHENTICATE, startsWith("Bearer error=\"invalid_token\""));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getWhenValidTokenAndPublicKeyInLambdaThenReturnsOk() {
|
public void getWhenValidTokenAndPublicKeyInLambdaThenReturnsOk() {
|
||||||
this.spring.register(PublicKeyInLambdaConfig.class, RootController.class).autowire();
|
this.spring.register(PublicKeyInLambdaConfig.class, RootController.class).autowire();
|
||||||
|
|
Loading…
Reference in New Issue