From 9d8920f1b12cabf43942ca2911d7eca189557988 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 e8be1b11e8..2a38156ca4 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 @@ -37,7 +37,7 @@ import org.springframework.util.StringUtils; 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; @@ -100,7 +100,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 b3aa15a829..2e4c296ae5 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 @@ -44,7 +44,7 @@ import java.util.regex.Pattern; 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() {