From 9045636a4b5c7345885978c5c661942813ff354f Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Wed, 15 Jul 2020 18:12:53 -0600 Subject: [PATCH] Polish Bearer Token Padding Issue gh-8502 --- .../web/DefaultBearerTokenResolver.java | 4 ++-- ...rverBearerTokenAuthenticationConverter.java | 2 +- .../web/DefaultBearerTokenResolverTests.java | 14 +++----------- ...earerTokenAuthenticationConverterTests.java | 18 +++++++++++++++--- 4 files changed, 21 insertions(+), 17 deletions(-) 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 d99e6ad248..2e05c4ba52 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 @@ -38,7 +38,7 @@ import static org.springframework.security.oauth2.server.resource.BearerTokenErr public final class DefaultBearerTokenResolver implements BearerTokenResolver { private static final Pattern authorizationPattern = Pattern.compile( - "^Bearer (?[a-zA-Z0-9-._~+/]+)=*$", + "^Bearer (?[a-zA-Z0-9-._~+/]+=*)$", Pattern.CASE_INSENSITIVE); private boolean allowFormEncodedBodyParameter = false; @@ -95,7 +95,7 @@ public final class DefaultBearerTokenResolver implements BearerTokenResolver { throw new OAuth2AuthenticationException(error); } - return authorization.substring(7); + return matcher.group("token"); } return null; } 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 f6dda6cab7..ae14e621a3 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 @@ -46,7 +46,7 @@ import static org.springframework.security.oauth2.server.resource.BearerTokenErr public class ServerBearerTokenAuthenticationConverter implements ServerAuthenticationConverter { private static final Pattern authorizationPattern = Pattern.compile( - "^Bearer (?[a-zA-Z0-9-._~+/]+)=*$", + "^Bearer (?[a-zA-Z0-9-._~+/]+=*)$", Pattern.CASE_INSENSITIVE); private boolean allowUriQueryParameter = false; diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolverTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolverTests.java index 6fc88569a2..6f9a7402bc 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolverTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolverTests.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. @@ -51,17 +51,9 @@ public class DefaultBearerTokenResolverTests { assertThat(this.resolver.resolve(request)).isEqualTo(TEST_TOKEN); } + // gh-8502 @Test - public void resolveWhenValidHeaderIsPresentWithSingleBytePaddingIndicatorThenTokenIsResolved() { - String token = TEST_TOKEN + "="; - MockHttpServletRequest request = new MockHttpServletRequest(); - request.addHeader("Authorization", "Bearer " + token); - - assertThat(this.resolver.resolve(request)).isEqualTo(token); - } - - @Test - public void resolveWhenValidHeaderIsPresentWithTwoBytesPaddingIndicatorThenTokenIsResolved() { + public void resolveWhenHeaderEndsWithPaddingIndicatorThenTokenIsResolved() { String token = TEST_TOKEN + "=="; MockHttpServletRequest request = new MockHttpServletRequest(); request.addHeader("Authorization", "Bearer " + token); diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverterTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverterTests.java index 1a36a2eef8..16e4740f34 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverterTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverterTests.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,8 +16,11 @@ package org.springframework.security.oauth2.server.resource.web.server; +import java.util.Base64; + import org.junit.Before; import org.junit.Test; + import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; @@ -27,8 +30,6 @@ import org.springframework.security.oauth2.server.resource.BearerTokenAuthentica import org.springframework.security.oauth2.server.resource.BearerTokenError; import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes; -import java.util.Base64; - import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.catchThrowableOfType; @@ -56,6 +57,17 @@ public class ServerBearerTokenAuthenticationConverterTests { assertThat(convertToToken(request).getToken()).isEqualTo(TEST_TOKEN); } + // gh-8502 + @Test + public void resolveWhenHeaderEndsWithPaddingIndicatorThenTokenIsResolved() { + String token = TEST_TOKEN + "=="; + MockServerHttpRequest.BaseBuilder request = MockServerHttpRequest + .get("/") + .header(HttpHeaders.AUTHORIZATION, "Bearer " + token); + + assertThat(convertToToken(request).getToken()).isEqualTo(token); + } + // gh-7011 @Test public void resolveWhenValidHeaderIsEmptyStringThenTokenIsResolved() {