Polish Bearer Token Error Handling

Issue gh-7822
Issue gh-7823
This commit is contained in:
Josh Cummings 2020-01-13 16:03:28 -07:00
parent 1b15f74f57
commit 3e07b35611
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
13 changed files with 46 additions and 152 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -269,7 +269,7 @@ public class OAuth2ResourceServerConfigurerTests {
this.mvc.perform(get("/").with(bearerToken(token))) this.mvc.perform(get("/").with(bearerToken(token)))
.andExpect(status().isUnauthorized()) .andExpect(status().isUnauthorized())
.andExpect(invalidTokenHeader("An error occurred while attempting to decode the Jwt")); .andExpect(invalidTokenHeader("Invalid token"));
} }
@Test @Test

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,20 +18,16 @@ package org.springframework.security.oauth2.server.resource.authentication;
import java.util.Collection; import java.util.Collection;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtException; import org.springframework.security.oauth2.jwt.JwtException;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.BearerTokenError; import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -63,9 +59,6 @@ public final class JwtAuthenticationProvider implements AuthenticationProvider {
private Converter<Jwt, ? extends AbstractAuthenticationToken> jwtAuthenticationConverter = new JwtAuthenticationConverter(); private Converter<Jwt, ? extends AbstractAuthenticationToken> jwtAuthenticationConverter = new JwtAuthenticationConverter();
private static final OAuth2Error DEFAULT_INVALID_TOKEN =
invalidToken("An error occurred while attempting to decode the Jwt: Invalid token");
public JwtAuthenticationProvider(JwtDecoder jwtDecoder) { public JwtAuthenticationProvider(JwtDecoder jwtDecoder) {
Assert.notNull(jwtDecoder, "jwtDecoder cannot be null"); Assert.notNull(jwtDecoder, "jwtDecoder cannot be null");
this.jwtDecoder = jwtDecoder; this.jwtDecoder = jwtDecoder;
@ -88,8 +81,7 @@ public final class JwtAuthenticationProvider implements AuthenticationProvider {
try { try {
jwt = this.jwtDecoder.decode(bearer.getToken()); jwt = this.jwtDecoder.decode(bearer.getToken());
} catch (JwtException failed) { } catch (JwtException failed) {
OAuth2Error invalidToken = invalidToken(failed.getMessage()); throw new InvalidBearerTokenException(failed.getMessage(), failed);
throw new OAuth2AuthenticationException(invalidToken, invalidToken.getDescription(), failed);
} }
AbstractAuthenticationToken token = this.jwtAuthenticationConverter.convert(jwt); AbstractAuthenticationToken token = this.jwtAuthenticationConverter.convert(jwt);
@ -112,17 +104,4 @@ public final class JwtAuthenticationProvider implements AuthenticationProvider {
Assert.notNull(jwtAuthenticationConverter, "jwtAuthenticationConverter cannot be null"); Assert.notNull(jwtAuthenticationConverter, "jwtAuthenticationConverter cannot be null");
this.jwtAuthenticationConverter = jwtAuthenticationConverter; this.jwtAuthenticationConverter = jwtAuthenticationConverter;
} }
private static OAuth2Error invalidToken(String message) {
try {
return new BearerTokenError(
BearerTokenErrorCodes.INVALID_TOKEN,
HttpStatus.UNAUTHORIZED,
message,
"https://tools.ietf.org/html/rfc6750#section-3.1");
} catch (IllegalArgumentException malformed) {
// some third-party library error messages are not suitable for RFC 6750's error message charset
return DEFAULT_INVALID_TOKEN;
}
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -27,16 +27,13 @@ import javax.servlet.http.HttpServletRequest;
import com.nimbusds.jwt.JWTParser; import com.nimbusds.jwt.JWTParser;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpStatus;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationManagerResolver; import org.springframework.security.authentication.AuthenticationManagerResolver;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtDecoders; import org.springframework.security.oauth2.jwt.JwtDecoders;
import org.springframework.security.oauth2.server.resource.BearerTokenError; import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver; import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
import org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver; import org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -57,8 +54,6 @@ import org.springframework.util.Assert;
* @since 5.3 * @since 5.3
*/ */
public final class JwtIssuerAuthenticationManagerResolver implements AuthenticationManagerResolver<HttpServletRequest> { public final class JwtIssuerAuthenticationManagerResolver implements AuthenticationManagerResolver<HttpServletRequest> {
private static final OAuth2Error DEFAULT_INVALID_TOKEN = invalidToken("Invalid token");
private final AuthenticationManagerResolver<String> issuerAuthenticationManagerResolver; private final AuthenticationManagerResolver<String> issuerAuthenticationManagerResolver;
private final Converter<HttpServletRequest, String> issuerConverter = new JwtClaimIssuerConverter(); private final Converter<HttpServletRequest, String> issuerConverter = new JwtClaimIssuerConverter();
@ -118,7 +113,7 @@ public final class JwtIssuerAuthenticationManagerResolver implements Authenticat
String issuer = this.issuerConverter.convert(request); String issuer = this.issuerConverter.convert(request);
AuthenticationManager authenticationManager = this.issuerAuthenticationManagerResolver.resolve(issuer); AuthenticationManager authenticationManager = this.issuerAuthenticationManagerResolver.resolve(issuer);
if (authenticationManager == null) { if (authenticationManager == null) {
throw new OAuth2AuthenticationException(invalidToken("Invalid issuer " + issuer)); throw new InvalidBearerTokenException("Invalid issuer");
} }
return authenticationManager; return authenticationManager;
} }
@ -137,9 +132,9 @@ public final class JwtIssuerAuthenticationManagerResolver implements Authenticat
return issuer; return issuer;
} }
} catch (Exception e) { } catch (Exception e) {
throw new OAuth2AuthenticationException(invalidToken(e.getMessage())); throw new InvalidBearerTokenException(e.getMessage(), e);
} }
throw new OAuth2AuthenticationException(invalidToken("Missing issuer")); throw new InvalidBearerTokenException("Missing issuer");
} }
} }
@ -164,17 +159,4 @@ public final class JwtIssuerAuthenticationManagerResolver implements Authenticat
return null; return null;
} }
} }
private static OAuth2Error invalidToken(String message) {
try {
return new BearerTokenError(
BearerTokenErrorCodes.INVALID_TOKEN,
HttpStatus.UNAUTHORIZED,
message,
"https://tools.ietf.org/html/rfc6750#section-3.1");
} catch (IllegalArgumentException malformed) {
// some third-party library error messages are not suitable for RFC 6750's error message charset
return DEFAULT_INVALID_TOKEN;
}
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,18 +19,15 @@ package org.springframework.security.oauth2.server.resource.authentication;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.ReactiveAuthenticationManager; import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtException; import org.springframework.security.oauth2.jwt.JwtException;
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder; import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.BearerTokenError; import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -45,9 +42,6 @@ public final class JwtReactiveAuthenticationManager implements ReactiveAuthentic
private Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> jwtAuthenticationConverter private Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> jwtAuthenticationConverter
= new ReactiveJwtAuthenticationConverterAdapter(new JwtAuthenticationConverter()); = new ReactiveJwtAuthenticationConverterAdapter(new JwtAuthenticationConverter());
private static final OAuth2Error DEFAULT_INVALID_TOKEN =
invalidToken("An error occurred while attempting to decode the Jwt: Invalid token");
public JwtReactiveAuthenticationManager(ReactiveJwtDecoder jwtDecoder) { public JwtReactiveAuthenticationManager(ReactiveJwtDecoder jwtDecoder) {
Assert.notNull(jwtDecoder, "jwtDecoder cannot be null"); Assert.notNull(jwtDecoder, "jwtDecoder cannot be null");
this.jwtDecoder = jwtDecoder; this.jwtDecoder = jwtDecoder;
@ -78,20 +72,6 @@ public final class JwtReactiveAuthenticationManager implements ReactiveAuthentic
} }
private OAuth2AuthenticationException onError(JwtException e) { private OAuth2AuthenticationException onError(JwtException e) {
OAuth2Error invalidRequest = invalidToken(e.getMessage()); return new InvalidBearerTokenException(e.getMessage(), e);
return new OAuth2AuthenticationException(invalidRequest, invalidRequest.getDescription(), e);
}
private static OAuth2Error invalidToken(String message) {
try {
return new BearerTokenError(
BearerTokenErrorCodes.INVALID_TOKEN,
HttpStatus.UNAUTHORIZED,
message,
"https://tools.ietf.org/html/rfc6750#section-3.1");
} catch (IllegalArgumentException malformed) {
// some third-party library error messages are not suitable for RFC 6750's error message charset
return DEFAULT_INVALID_TOKEN;
}
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,7 +18,6 @@ package org.springframework.security.oauth2.server.resource.authentication;
import java.time.Instant; import java.time.Instant;
import java.util.Collection; import java.util.Collection;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -26,10 +25,8 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.BearerTokenError; import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector; import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -60,9 +57,6 @@ import static org.springframework.security.oauth2.server.resource.introspection.
* @see AuthenticationProvider * @see AuthenticationProvider
*/ */
public final class OpaqueTokenAuthenticationProvider implements AuthenticationProvider { public final class OpaqueTokenAuthenticationProvider implements AuthenticationProvider {
private static final BearerTokenError DEFAULT_INVALID_TOKEN =
invalidToken("An error occurred while attempting to introspect the token: Invalid token");
private OpaqueTokenIntrospector introspector; private OpaqueTokenIntrospector introspector;
/** /**
@ -95,8 +89,7 @@ public final class OpaqueTokenAuthenticationProvider implements AuthenticationPr
try { try {
principal = this.introspector.introspect(bearer.getToken()); principal = this.introspector.introspect(bearer.getToken());
} catch (OAuth2IntrospectionException failed) { } catch (OAuth2IntrospectionException failed) {
OAuth2Error invalidToken = invalidToken(failed.getMessage()); throw new InvalidBearerTokenException(failed.getMessage());
throw new OAuth2AuthenticationException(invalidToken);
} }
AbstractAuthenticationToken result = convert(principal, bearer.getToken()); AbstractAuthenticationToken result = convert(principal, bearer.getToken());
@ -119,15 +112,4 @@ public final class OpaqueTokenAuthenticationProvider implements AuthenticationPr
token, iat, exp); token, iat, exp);
return new BearerTokenAuthentication(principal, accessToken, principal.getAuthorities()); return new BearerTokenAuthentication(principal, accessToken, principal.getAuthorities());
} }
private static BearerTokenError invalidToken(String message) {
try {
return new BearerTokenError("invalid_token",
HttpStatus.UNAUTHORIZED, message,
"https://tools.ietf.org/html/rfc7662#section-2.2");
} catch (IllegalArgumentException malformed) {
// some third-party library error messages are not suitable for RFC 6750's error message charset
return DEFAULT_INVALID_TOKEN;
}
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,15 +21,13 @@ import java.util.Collection;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.ReactiveAuthenticationManager; import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.BearerTokenError; import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;
import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector; import org.springframework.security.oauth2.server.resource.introspection.ReactiveOpaqueTokenIntrospector;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -60,9 +58,6 @@ import static org.springframework.security.oauth2.server.resource.introspection.
* @see ReactiveAuthenticationManager * @see ReactiveAuthenticationManager
*/ */
public class OpaqueTokenReactiveAuthenticationManager implements ReactiveAuthenticationManager { public class OpaqueTokenReactiveAuthenticationManager implements ReactiveAuthenticationManager {
private static final BearerTokenError DEFAULT_INVALID_TOKEN =
invalidToken("An error occurred while attempting to introspect the token: Invalid token");
private ReactiveOpaqueTokenIntrospector introspector; private ReactiveOpaqueTokenIntrospector introspector;
/** /**
@ -99,19 +94,7 @@ public class OpaqueTokenReactiveAuthenticationManager implements ReactiveAuthent
.onErrorMap(OAuth2IntrospectionException.class, this::onError); .onErrorMap(OAuth2IntrospectionException.class, this::onError);
} }
private static BearerTokenError invalidToken(String message) {
try {
return new BearerTokenError("invalid_token",
HttpStatus.UNAUTHORIZED, message,
"https://tools.ietf.org/html/rfc7662#section-2.2");
} catch (IllegalArgumentException e) {
// some third-party library error messages are not suitable for RFC 6750's error message charset
return DEFAULT_INVALID_TOKEN;
}
}
private OAuth2AuthenticationException onError(OAuth2IntrospectionException e) { private OAuth2AuthenticationException onError(OAuth2IntrospectionException e) {
OAuth2Error invalidRequest = invalidToken(e.getMessage()); return new InvalidBearerTokenException(e.getMessage(), e);
return new OAuth2AuthenticationException(invalidRequest, e.getMessage());
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,12 +21,13 @@ import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.server.resource.BearerTokenError; import org.springframework.security.oauth2.server.resource.BearerTokenError;
import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import static org.springframework.security.oauth2.server.resource.BearerTokenErrors.invalidRequest;
import static org.springframework.security.oauth2.server.resource.BearerTokenErrors.invalidToken;
/** /**
* The default {@link BearerTokenResolver} implementation based on RFC 6750. * The default {@link BearerTokenResolver} implementation based on RFC 6750.
* *
@ -53,10 +54,7 @@ public final class DefaultBearerTokenResolver implements BearerTokenResolver {
String parameterToken = resolveFromRequestParameters(request); String parameterToken = resolveFromRequestParameters(request);
if (authorizationHeaderToken != null) { if (authorizationHeaderToken != null) {
if (parameterToken != null) { if (parameterToken != null) {
BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_REQUEST, BearerTokenError error = invalidRequest("Found multiple bearer tokens in the request");
HttpStatus.BAD_REQUEST,
"Found multiple bearer tokens in the request",
"https://tools.ietf.org/html/rfc6750#section-3.1");
throw new OAuth2AuthenticationException(error); throw new OAuth2AuthenticationException(error);
} }
return authorizationHeaderToken; return authorizationHeaderToken;
@ -93,10 +91,7 @@ public final class DefaultBearerTokenResolver implements BearerTokenResolver {
Matcher matcher = authorizationPattern.matcher(authorization); Matcher matcher = authorizationPattern.matcher(authorization);
if (!matcher.matches()) { if (!matcher.matches()) {
BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_TOKEN, BearerTokenError error = invalidToken("Bearer token is malformed");
HttpStatus.UNAUTHORIZED,
"Bearer token is malformed",
"https://tools.ietf.org/html/rfc6750#section-3.1");
throw new OAuth2AuthenticationException(error); throw new OAuth2AuthenticationException(error);
} }
@ -115,10 +110,7 @@ public final class DefaultBearerTokenResolver implements BearerTokenResolver {
return values[0]; return values[0];
} }
BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_REQUEST, BearerTokenError error = invalidRequest("Found multiple bearer tokens in the request");
HttpStatus.BAD_REQUEST,
"Found multiple bearer tokens in the request",
"https://tools.ietf.org/html/rfc6750#section-3.1");
throw new OAuth2AuthenticationException(error); throw new OAuth2AuthenticationException(error);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,22 +16,24 @@
package org.springframework.security.oauth2.server.resource.web.server; package org.springframework.security.oauth2.server.resource.web.server;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import reactor.core.publisher.Mono;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken; import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
import org.springframework.security.oauth2.server.resource.BearerTokenError; import org.springframework.security.oauth2.server.resource.BearerTokenError;
import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter; import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.regex.Matcher; import static org.springframework.security.oauth2.server.resource.BearerTokenErrors.invalidRequest;
import java.util.regex.Pattern; import static org.springframework.security.oauth2.server.resource.BearerTokenErrors.invalidToken;
/** /**
* A strategy for resolving <a href="https://tools.ietf.org/html/rfc6750#section-1.2" target="_blank">Bearer Token</a>s * A strategy for resolving <a href="https://tools.ietf.org/html/rfc6750#section-1.2" target="_blank">Bearer Token</a>s
@ -65,10 +67,7 @@ public class ServerBearerTokenAuthenticationConverter
String parameterToken = request.getQueryParams().getFirst("access_token"); String parameterToken = request.getQueryParams().getFirst("access_token");
if (authorizationHeaderToken != null) { if (authorizationHeaderToken != null) {
if (parameterToken != null) { if (parameterToken != null) {
BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_REQUEST, BearerTokenError error = invalidRequest("Found multiple bearer tokens in the request");
HttpStatus.BAD_REQUEST,
"Found multiple bearer tokens in the request",
"https://tools.ietf.org/html/rfc6750#section-3.1");
throw new OAuth2AuthenticationException(error); throw new OAuth2AuthenticationException(error);
} }
return authorizationHeaderToken; return authorizationHeaderToken;
@ -107,10 +106,7 @@ public class ServerBearerTokenAuthenticationConverter
} }
private static BearerTokenError invalidTokenError() { private static BearerTokenError invalidTokenError() {
return new BearerTokenError(BearerTokenErrorCodes.INVALID_TOKEN, return invalidToken("Bearer token is malformed");
HttpStatus.UNAUTHORIZED,
"Bearer token is malformed",
"https://tools.ietf.org/html/rfc6750#section-3.1");
} }
private boolean isParameterTokenSupportedForRequest(ServerHttpRequest request) { private boolean isParameterTokenSupportedForRequest(ServerHttpRequest request) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -95,7 +95,7 @@ public class JwtAuthenticationProviderTests {
.isInstanceOf(OAuth2AuthenticationException.class) .isInstanceOf(OAuth2AuthenticationException.class)
.hasFieldOrPropertyWithValue( .hasFieldOrPropertyWithValue(
"error.description", "error.description",
"An error occurred while attempting to decode the Jwt: Invalid token"); "Invalid token");
} }
@Test @Test

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -162,7 +162,7 @@ public class JwtIssuerAuthenticationManagerResolverTests {
request.addHeader("Authorization", "Bearer " + this.evil); request.addHeader("Authorization", "Bearer " + this.evil);
assertThatCode(() -> authenticationManagerResolver.resolve(request)) assertThatCode(() -> authenticationManagerResolver.resolve(request))
.isInstanceOf(OAuth2AuthenticationException.class) .isInstanceOf(OAuth2AuthenticationException.class)
.hasMessage("Invalid token"); .hasMessage("Invalid issuer");
} }
@Test @Test

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -98,7 +98,7 @@ public class JwtReactiveAuthenticationManagerTests {
.isInstanceOf(OAuth2AuthenticationException.class) .isInstanceOf(OAuth2AuthenticationException.class)
.hasFieldOrPropertyWithValue( .hasFieldOrPropertyWithValue(
"error.description", "error.description",
"An error occurred while attempting to decode the Jwt: Invalid token"); "Invalid token");
} }
@Test @Test

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -111,7 +111,7 @@ public class OpaqueTokenAuthenticationProviderTests {
assertThatCode(() -> provider.authenticate(new BearerTokenAuthenticationToken("token"))) assertThatCode(() -> provider.authenticate(new BearerTokenAuthenticationToken("token")))
.isInstanceOf(OAuth2AuthenticationException.class) .isInstanceOf(OAuth2AuthenticationException.class)
.extracting("error.description") .extracting("error.description")
.isEqualTo("An error occurred while attempting to introspect the token: Invalid token"); .isEqualTo("Invalid token");
} }
@Test @Test

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2019 the original author or authors. * Copyright 2002-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -117,7 +117,7 @@ public class OpaqueTokenReactiveAuthenticationManagerTests {
assertThatCode(() -> provider.authenticate(new BearerTokenAuthenticationToken("token")).block()) assertThatCode(() -> provider.authenticate(new BearerTokenAuthenticationToken("token")).block())
.isInstanceOf(OAuth2AuthenticationException.class) .isInstanceOf(OAuth2AuthenticationException.class)
.extracting("error.description") .extracting("error.description")
.isEqualTo("An error occurred while attempting to introspect the token: Invalid token"); .isEqualTo("Invalid token");
} }
@Test @Test