Browse Source

Polish Bearer Token Error Handling

Issue gh-7822
Issue gh-7823
Josh Cummings 5 years ago
parent
commit
3e07b35611
13 changed files with 46 additions and 152 deletions
  1. 2 2
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java
  2. 3 24
      oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProvider.java
  3. 5 23
      oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolver.java
  4. 3 23
      oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManager.java
  5. 3 21
      oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProvider.java
  6. 3 20
      oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManager.java
  7. 7 15
      oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolver.java
  8. 10 14
      oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverter.java
  9. 2 2
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProviderTests.java
  10. 2 2
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolverTests.java
  11. 2 2
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManagerTests.java
  12. 2 2
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProviderTests.java
  13. 2 2
      oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManagerTests.java

+ 2 - 2
config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java

@@ -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");
  * 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)))
 				.andExpect(status().isUnauthorized())
-				.andExpect(invalidTokenHeader("An error occurred while attempting to decode the Jwt"));
+				.andExpect(invalidTokenHeader("Invalid token"));
 	}
 
 	@Test

+ 3 - 24
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProvider.java

@@ -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");
  * 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 org.springframework.core.convert.converter.Converter;
-import org.springframework.http.HttpStatus;
 import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.AuthenticationException;
 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.JwtDecoder;
 import org.springframework.security.oauth2.jwt.JwtException;
 import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
-import org.springframework.security.oauth2.server.resource.BearerTokenError;
-import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
+import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
 import org.springframework.util.Assert;
 
 /**
@@ -63,9 +59,6 @@ public final class JwtAuthenticationProvider implements AuthenticationProvider {
 
 	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) {
 		Assert.notNull(jwtDecoder, "jwtDecoder cannot be null");
 		this.jwtDecoder = jwtDecoder;
@@ -88,8 +81,7 @@ public final class JwtAuthenticationProvider implements AuthenticationProvider {
 		try {
 			jwt = this.jwtDecoder.decode(bearer.getToken());
 		} catch (JwtException failed) {
-			OAuth2Error invalidToken = invalidToken(failed.getMessage());
-			throw new OAuth2AuthenticationException(invalidToken, invalidToken.getDescription(), failed);
+			throw new InvalidBearerTokenException(failed.getMessage(), failed);
 		}
 
 		AbstractAuthenticationToken token = this.jwtAuthenticationConverter.convert(jwt);
@@ -112,17 +104,4 @@ public final class JwtAuthenticationProvider implements AuthenticationProvider {
 		Assert.notNull(jwtAuthenticationConverter, "jwtAuthenticationConverter cannot be null");
 		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;
-		}
-	}
 }

+ 5 - 23
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolver.java

@@ -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");
  * 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 org.springframework.core.convert.converter.Converter;
-import org.springframework.http.HttpStatus;
 import org.springframework.lang.NonNull;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.AuthenticationManagerResolver;
 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.JwtDecoders;
-import org.springframework.security.oauth2.server.resource.BearerTokenError;
-import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
+import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
 import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
 import org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver;
 import org.springframework.util.Assert;
@@ -57,8 +54,6 @@ import org.springframework.util.Assert;
  * @since 5.3
  */
 public final class JwtIssuerAuthenticationManagerResolver implements AuthenticationManagerResolver<HttpServletRequest> {
-	private static final OAuth2Error DEFAULT_INVALID_TOKEN = invalidToken("Invalid token");
-
 	private final AuthenticationManagerResolver<String> issuerAuthenticationManagerResolver;
 	private final Converter<HttpServletRequest, String> issuerConverter = new JwtClaimIssuerConverter();
 
@@ -118,7 +113,7 @@ public final class JwtIssuerAuthenticationManagerResolver implements Authenticat
 		String issuer = this.issuerConverter.convert(request);
 		AuthenticationManager authenticationManager = this.issuerAuthenticationManagerResolver.resolve(issuer);
 		if (authenticationManager == null) {
-			throw new OAuth2AuthenticationException(invalidToken("Invalid issuer " + issuer));
+			throw new InvalidBearerTokenException("Invalid issuer");
 		}
 		return authenticationManager;
 	}
@@ -137,9 +132,9 @@ public final class JwtIssuerAuthenticationManagerResolver implements Authenticat
 					return issuer;
 				}
 			} 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;
 		}
 	}
-
-	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;
-		}
-	}
 }

+ 3 - 23
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManager.java

@@ -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");
  * 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 org.springframework.core.convert.converter.Converter;
-import org.springframework.http.HttpStatus;
 import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.authentication.ReactiveAuthenticationManager;
 import org.springframework.security.core.Authentication;
 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.JwtException;
 import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
 import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
-import org.springframework.security.oauth2.server.resource.BearerTokenError;
-import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
+import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
 import org.springframework.util.Assert;
 
 /**
@@ -45,9 +42,6 @@ public final class JwtReactiveAuthenticationManager implements ReactiveAuthentic
 	private Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> 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) {
 		Assert.notNull(jwtDecoder, "jwtDecoder cannot be null");
 		this.jwtDecoder = jwtDecoder;
@@ -78,20 +72,6 @@ public final class JwtReactiveAuthenticationManager implements ReactiveAuthentic
 	}
 
 	private OAuth2AuthenticationException onError(JwtException e) {
-		OAuth2Error invalidRequest = invalidToken(e.getMessage());
-		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;
-		}
+		return new InvalidBearerTokenException(e.getMessage(), e);
 	}
 }

+ 3 - 21
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProvider.java

@@ -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");
  * 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.util.Collection;
 
-import org.springframework.http.HttpStatus;
 import org.springframework.security.authentication.AbstractAuthenticationToken;
 import org.springframework.security.authentication.AuthenticationProvider;
 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.oauth2.core.OAuth2AccessToken;
 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.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.OpaqueTokenIntrospector;
 import org.springframework.util.Assert;
@@ -60,9 +57,6 @@ import static org.springframework.security.oauth2.server.resource.introspection.
  * @see 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;
 
 	/**
@@ -95,8 +89,7 @@ public final class OpaqueTokenAuthenticationProvider implements AuthenticationPr
 		try {
 			principal = this.introspector.introspect(bearer.getToken());
 		} catch (OAuth2IntrospectionException failed) {
-			OAuth2Error invalidToken = invalidToken(failed.getMessage());
-			throw new OAuth2AuthenticationException(invalidToken);
+			throw new InvalidBearerTokenException(failed.getMessage());
 		}
 
 		AbstractAuthenticationToken result = convert(principal, bearer.getToken());
@@ -119,15 +112,4 @@ public final class OpaqueTokenAuthenticationProvider implements AuthenticationPr
 				token, iat, exp);
 		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;
-		}
-	}
 }

+ 3 - 20
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManager.java

@@ -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");
  * 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 org.springframework.http.HttpStatus;
 import org.springframework.security.authentication.ReactiveAuthenticationManager;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.oauth2.core.OAuth2AccessToken;
 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.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.ReactiveOpaqueTokenIntrospector;
 import org.springframework.util.Assert;
@@ -60,9 +58,6 @@ import static org.springframework.security.oauth2.server.resource.introspection.
  * @see 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;
 
 	/**
@@ -99,19 +94,7 @@ public class OpaqueTokenReactiveAuthenticationManager implements ReactiveAuthent
 				.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) {
-		OAuth2Error invalidRequest = invalidToken(e.getMessage());
-		return new OAuth2AuthenticationException(invalidRequest, e.getMessage());
+		return new InvalidBearerTokenException(e.getMessage(), e);
 	}
 }

+ 7 - 15
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolver.java

@@ -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");
  * 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 org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
 import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 import org.springframework.security.oauth2.server.resource.BearerTokenError;
-import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
 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.
  *
@@ -53,10 +54,7 @@ public final class DefaultBearerTokenResolver implements BearerTokenResolver {
 		String parameterToken = resolveFromRequestParameters(request);
 		if (authorizationHeaderToken != null) {
 			if (parameterToken != null) {
-				BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_REQUEST,
-						HttpStatus.BAD_REQUEST,
-						"Found multiple bearer tokens in the request",
-						"https://tools.ietf.org/html/rfc6750#section-3.1");
+				BearerTokenError error = invalidRequest("Found multiple bearer tokens in the request");
 				throw new OAuth2AuthenticationException(error);
 			}
 			return authorizationHeaderToken;
@@ -93,10 +91,7 @@ public final class DefaultBearerTokenResolver implements BearerTokenResolver {
 			Matcher matcher = authorizationPattern.matcher(authorization);
 
 			if (!matcher.matches()) {
-				BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_TOKEN,
-						HttpStatus.UNAUTHORIZED,
-						"Bearer token is malformed",
-						"https://tools.ietf.org/html/rfc6750#section-3.1");
+				BearerTokenError error = invalidToken("Bearer token is malformed");
 				throw new OAuth2AuthenticationException(error);
 			}
 
@@ -115,10 +110,7 @@ public final class DefaultBearerTokenResolver implements BearerTokenResolver {
 			return values[0];
 		}
 
-		BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_REQUEST,
-				HttpStatus.BAD_REQUEST,
-				"Found multiple bearer tokens in the request",
-				"https://tools.ietf.org/html/rfc6750#section-3.1");
+		BearerTokenError error = invalidRequest("Found multiple bearer tokens in the request");
 		throw new OAuth2AuthenticationException(error);
 	}
 

+ 10 - 14
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverter.java

@@ -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");
  * 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;
 
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import reactor.core.publisher.Mono;
+
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
 import org.springframework.http.server.reactive.ServerHttpRequest;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
 import org.springframework.security.oauth2.server.resource.BearerTokenAuthenticationToken;
 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.util.StringUtils;
 import org.springframework.web.server.ServerWebExchange;
-import reactor.core.publisher.Mono;
 
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import static org.springframework.security.oauth2.server.resource.BearerTokenErrors.invalidRequest;
+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
@@ -65,10 +67,7 @@ public class ServerBearerTokenAuthenticationConverter
 		String parameterToken = request.getQueryParams().getFirst("access_token");
 		if (authorizationHeaderToken != null) {
 			if (parameterToken != null) {
-				BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_REQUEST,
-						HttpStatus.BAD_REQUEST,
-						"Found multiple bearer tokens in the request",
-						"https://tools.ietf.org/html/rfc6750#section-3.1");
+				BearerTokenError error = invalidRequest("Found multiple bearer tokens in the request");
 				throw new OAuth2AuthenticationException(error);
 			}
 			return authorizationHeaderToken;
@@ -107,10 +106,7 @@ public class ServerBearerTokenAuthenticationConverter
 	}
 
 	private static BearerTokenError invalidTokenError() {
-		return new BearerTokenError(BearerTokenErrorCodes.INVALID_TOKEN,
-							HttpStatus.UNAUTHORIZED,
-							"Bearer token is malformed",
-							"https://tools.ietf.org/html/rfc6750#section-3.1");
+		return invalidToken("Bearer token is malformed");
 	}
 
 	private boolean isParameterTokenSupportedForRequest(ServerHttpRequest request) {

+ 2 - 2
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProviderTests.java

@@ -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");
  * you may not use this file except in compliance with the License.
@@ -95,7 +95,7 @@ public class JwtAuthenticationProviderTests {
 				.isInstanceOf(OAuth2AuthenticationException.class)
 				.hasFieldOrPropertyWithValue(
 						"error.description",
-						"An error occurred while attempting to decode the Jwt: Invalid token");
+						"Invalid token");
 	}
 
 	@Test

+ 2 - 2
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolverTests.java

@@ -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");
  * 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);
 		assertThatCode(() -> authenticationManagerResolver.resolve(request))
 				.isInstanceOf(OAuth2AuthenticationException.class)
-				.hasMessage("Invalid token");
+				.hasMessage("Invalid issuer");
 	}
 
 	@Test

+ 2 - 2
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManagerTests.java

@@ -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");
  * you may not use this file except in compliance with the License.
@@ -98,7 +98,7 @@ public class JwtReactiveAuthenticationManagerTests {
 				.isInstanceOf(OAuth2AuthenticationException.class)
 				.hasFieldOrPropertyWithValue(
 						"error.description",
-						"An error occurred while attempting to decode the Jwt: Invalid token");
+						"Invalid token");
 	}
 
 	@Test

+ 2 - 2
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProviderTests.java

@@ -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");
  * 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")))
 				.isInstanceOf(OAuth2AuthenticationException.class)
 				.extracting("error.description")
-				.isEqualTo("An error occurred while attempting to introspect the token: Invalid token");
+				.isEqualTo("Invalid token");
 	}
 
 	@Test

+ 2 - 2
oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManagerTests.java

@@ -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");
  * 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())
 				.isInstanceOf(OAuth2AuthenticationException.class)
 				.extracting("error.description")
-				.isEqualTo("An error occurred while attempting to introspect the token: Invalid token");
+				.isEqualTo("Invalid token");
 	}
 
 	@Test