Malformed Bearer Token Returns 401 for WebFlux

Fixes gh-7668
This commit is contained in:
Josh Cummings 2020-03-03 15:39:10 -07:00
parent 4706b16a2b
commit cb7786bf97
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
2 changed files with 37 additions and 2 deletions

View File

@ -55,6 +55,7 @@ import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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.SecurityWebFilterChain;
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.AuthenticationWebFilter;
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
*/
@ -1896,7 +1920,7 @@ public class ServerHttpSecurity {
protected void configure(ServerHttpSecurity http) {
ReactiveAuthenticationManager authenticationManager = getAuthenticationManager();
AuthenticationWebFilter oauth2 = new AuthenticationWebFilter(authenticationManager);
AuthenticationWebFilter oauth2 = new BearerTokenAuthenticationWebFilter(authenticationManager);
oauth2.setServerAuthenticationConverter(bearerTokenConverter);
oauth2.setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(entryPoint));
http
@ -2002,7 +2026,7 @@ public class ServerHttpSecurity {
protected void configure(ServerHttpSecurity http) {
ReactiveAuthenticationManager authenticationManager = getAuthenticationManager();
AuthenticationWebFilter oauth2 = new AuthenticationWebFilter(authenticationManager);
AuthenticationWebFilter oauth2 = new BearerTokenAuthenticationWebFilter(authenticationManager);
oauth2.setServerAuthenticationConverter(bearerTokenConverter);
oauth2.setAuthenticationFailureHandler(new ServerAuthenticationEntryPointFailureHandler(entryPoint));
http.addFilterAt(oauth2, SecurityWebFiltersOrder.AUTHENTICATION);

View File

@ -172,6 +172,17 @@ public class OAuth2ResourceServerSpecTests {
.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
public void getWhenValidTokenAndPublicKeyInLambdaThenReturnsOk() {
this.spring.register(PublicKeyInLambdaConfig.class, RootController.class).autowire();