From 7e7f85c18c54008d760edc855ca7a695db8782a3 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 69f804eb69..3e8483fb7f 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 @@ -36,7 +36,7 @@ import org.springframework.util.StringUtils; */ public final class DefaultBearerTokenResolver implements BearerTokenResolver { - private static final Pattern authorizationPattern = Pattern.compile("^Bearer (?[a-zA-Z0-9-._~+/]+)=*$"); + private static final Pattern authorizationPattern = Pattern.compile("^Bearer (?[a-zA-Z0-9-._~+/]+=*)$"); private boolean allowFormEncodedBodyParameter = false; @@ -98,7 +98,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 8908360f19..24d6969c11 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 @@ -43,7 +43,7 @@ import java.util.regex.Pattern; */ public class ServerBearerTokenAuthenticationConverter implements ServerAuthenticationConverter { - private static final Pattern authorizationPattern = Pattern.compile("^Bearer (?[a-zA-Z0-9-._~+/]+)=*$"); + private static final Pattern authorizationPattern = Pattern.compile("^Bearer (?[a-zA-Z0-9-._~+/]+=*)$"); 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 d4398bb80f..6504fee442 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 a1a88255aa..c16f65c373 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() {