From 3e07b3561129a2b5ff39142549ae5a5be2cd7aae Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Mon, 13 Jan 2020 16:03:28 -0700 Subject: [PATCH] Polish Bearer Token Error Handling Issue gh-7822 Issue gh-7823 --- .../OAuth2ResourceServerConfigurerTests.java | 4 +-- .../JwtAuthenticationProvider.java | 27 ++---------------- ...wtIssuerAuthenticationManagerResolver.java | 28 ++++--------------- .../JwtReactiveAuthenticationManager.java | 26 ++--------------- .../OpaqueTokenAuthenticationProvider.java | 24 ++-------------- ...queTokenReactiveAuthenticationManager.java | 23 ++------------- .../web/DefaultBearerTokenResolver.java | 22 +++++---------- ...verBearerTokenAuthenticationConverter.java | 24 +++++++--------- .../JwtAuthenticationProviderTests.java | 4 +-- ...uerAuthenticationManagerResolverTests.java | 4 +-- ...JwtReactiveAuthenticationManagerTests.java | 4 +-- ...paqueTokenAuthenticationProviderTests.java | 4 +-- ...kenReactiveAuthenticationManagerTests.java | 4 +-- 13 files changed, 46 insertions(+), 152 deletions(-) diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java index 9c45b53006..e4427541f1 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java +++ b/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 diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProvider.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProvider.java index 35bcfc1b3a..8eb80a947d 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProvider.java +++ b/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 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; - } - } } diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolver.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolver.java index e64544bcf0..3f132fbe2c 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolver.java +++ b/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 { - private static final OAuth2Error DEFAULT_INVALID_TOKEN = invalidToken("Invalid token"); - private final AuthenticationManagerResolver issuerAuthenticationManagerResolver; private final Converter 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; - } - } } diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManager.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManager.java index f25933cf9c..c475ef37c0 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManager.java +++ b/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> 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); } } diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProvider.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProvider.java index 204e70099a..20cc1c56cd 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProvider.java +++ b/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; - } - } } diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManager.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManager.java index a2ddcaba4d..e7ab5b4e79 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManager.java +++ b/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); } } diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolver.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolver.java index 14c3a2558f..f96cdbcddb 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolver.java +++ b/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); } diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverter.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverter.java index b3aa15a829..f6dda6cab7 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverter.java +++ b/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 Bearer Tokens @@ -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) { diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProviderTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProviderTests.java index 381c5bb38e..936ebb0bbf 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtAuthenticationProviderTests.java +++ b/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 diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolverTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolverTests.java index e4d215a3ca..21df5189fe 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerAuthenticationManagerResolverTests.java +++ b/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 diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManagerTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManagerTests.java index 536f76cfec..e103dd4851 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/JwtReactiveAuthenticationManagerTests.java +++ b/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 diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProviderTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProviderTests.java index 1eb83167c1..0186d6b724 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenAuthenticationProviderTests.java +++ b/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 diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManagerTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManagerTests.java index e8c64d9277..5226d0bef4 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/authentication/OpaqueTokenReactiveAuthenticationManagerTests.java +++ b/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