Skip to content

Commit 629239f

Browse files
committed
Polish gh-1874
1 parent b0fca27 commit 629239f

File tree

4 files changed

+60
-13
lines changed

4 files changed

+60
-13
lines changed

Diff for: oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationEndpointFilter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2024 the original author or authors.
2+
* Copyright 2020-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

Diff for: oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AuthorizationCodeRequestAuthenticationConverter.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2024 the original author or authors.
2+
* Copyright 2020-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@
3838
import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationEndpointFilter;
3939
import org.springframework.security.web.authentication.AuthenticationConverter;
4040
import org.springframework.security.web.util.matcher.AndRequestMatcher;
41+
import org.springframework.security.web.util.matcher.OrRequestMatcher;
4142
import org.springframework.security.web.util.matcher.RequestMatcher;
4243
import org.springframework.util.CollectionUtils;
4344
import org.springframework.util.MultiValueMap;
@@ -64,11 +65,11 @@ public final class OAuth2AuthorizationCodeRequestAuthenticationConverter impleme
6465
private static final Authentication ANONYMOUS_AUTHENTICATION = new AnonymousAuthenticationToken("anonymous",
6566
"anonymousUser", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
6667

67-
private static final RequestMatcher POST_WITH_RESPONSE_TYPE_REQUEST_MATCHER = createPostWithResponseTypeRequestMatcher();
68+
private final RequestMatcher requestMatcher = createDefaultRequestMatcher();
6869

6970
@Override
7071
public Authentication convert(HttpServletRequest request) {
71-
if (!"GET".equals(request.getMethod()) && !POST_WITH_RESPONSE_TYPE_REQUEST_MATCHER.matches(request)) {
72+
if (!this.requestMatcher.matches(request)) {
7273
return null;
7374
}
7475

@@ -153,11 +154,13 @@ else if (!responseType.equals(OAuth2AuthorizationResponseType.CODE.getValue()))
153154
state, scopes, additionalParameters);
154155
}
155156

156-
private static RequestMatcher createPostWithResponseTypeRequestMatcher() {
157+
private static RequestMatcher createDefaultRequestMatcher() {
158+
RequestMatcher getMethodMatcher = (request) -> "GET".equals(request.getMethod());
157159
RequestMatcher postMethodMatcher = (request) -> "POST".equals(request.getMethod());
158160
RequestMatcher responseTypeParameterMatcher = (
159161
request) -> request.getParameter(OAuth2ParameterNames.RESPONSE_TYPE) != null;
160-
return new AndRequestMatcher(postMethodMatcher, responseTypeParameterMatcher);
162+
return new OrRequestMatcher(getMethodMatcher,
163+
new AndRequestMatcher(postMethodMatcher, responseTypeParameterMatcher));
161164
}
162165

163166
private static void throwError(String errorCode, String parameterName) {

Diff for: oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AuthorizationConsentAuthenticationConverter.java

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2023 the original author or authors.
2+
* Copyright 2020-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,6 +33,9 @@
3333
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationToken;
3434
import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationEndpointFilter;
3535
import org.springframework.security.web.authentication.AuthenticationConverter;
36+
import org.springframework.security.web.util.matcher.AndRequestMatcher;
37+
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
38+
import org.springframework.security.web.util.matcher.RequestMatcher;
3639
import org.springframework.util.MultiValueMap;
3740
import org.springframework.util.StringUtils;
3841

@@ -55,14 +58,16 @@ public final class OAuth2AuthorizationConsentAuthenticationConverter implements
5558
private static final Authentication ANONYMOUS_AUTHENTICATION = new AnonymousAuthenticationToken("anonymous",
5659
"anonymousUser", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
5760

61+
private final RequestMatcher requestMatcher = createDefaultRequestMatcher();
62+
5863
@Override
5964
public Authentication convert(HttpServletRequest request) {
60-
MultiValueMap<String, String> parameters = OAuth2EndpointUtils.getFormParameters(request);
61-
62-
if (!"POST".equals(request.getMethod()) || parameters.getFirst(OAuth2ParameterNames.RESPONSE_TYPE) != null) {
65+
if (!this.requestMatcher.matches(request)) {
6366
return null;
6467
}
6568

69+
MultiValueMap<String, String> parameters = OAuth2EndpointUtils.getFormParameters(request);
70+
6671
String authorizationUri = request.getRequestURL().toString();
6772

6873
// client_id (REQUIRED)
@@ -100,6 +105,13 @@ public Authentication convert(HttpServletRequest request) {
100105
additionalParameters);
101106
}
102107

108+
private static RequestMatcher createDefaultRequestMatcher() {
109+
RequestMatcher postMethodMatcher = (request) -> "POST".equals(request.getMethod());
110+
RequestMatcher responseTypeParameterMatcher = (
111+
request) -> request.getParameter(OAuth2ParameterNames.RESPONSE_TYPE) != null;
112+
return new AndRequestMatcher(postMethodMatcher, new NegatedRequestMatcher(responseTypeParameterMatcher));
113+
}
114+
103115
private static void throwError(String errorCode, String parameterName) {
104116
OAuth2Error error = new OAuth2Error(errorCode, "OAuth 2.0 Parameter: " + parameterName, DEFAULT_ERROR_URI);
105117
throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);

Diff for: oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationEndpointFilterTests.java

+35-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2024 the original author or authors.
2+
* Copyright 2020-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -609,17 +609,49 @@ public void doFilterWhenAuthorizationRequestAuthenticatedThenAuthorizationRespon
609609
.isEqualTo("https://example.com?param=encoded%20parameter%20value&code=code&state=client%20state");
610610
}
611611

612+
@Test
613+
public void doFilterWhenPostAuthorizationRequestAuthenticatedThenAuthorizationResponse() throws Exception {
614+
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().redirectUris((redirectUris) -> {
615+
redirectUris.clear();
616+
redirectUris.add("https://example.com?param=encoded%20parameter%20value");
617+
}).build();
618+
OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthenticationResult = new OAuth2AuthorizationCodeRequestAuthenticationToken(
619+
AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, this.authorizationCode,
620+
registeredClient.getRedirectUris().iterator().next(), "client state", registeredClient.getScopes());
621+
authorizationCodeRequestAuthenticationResult.setAuthenticated(true);
622+
given(this.authenticationManager.authenticate(any())).willReturn(authorizationCodeRequestAuthenticationResult);
623+
624+
MockHttpServletRequest request = createAuthorizationRequest(registeredClient);
625+
request.setMethod("POST");
626+
request.setQueryString(null);
627+
MockHttpServletResponse response = new MockHttpServletResponse();
628+
FilterChain filterChain = mock(FilterChain.class);
629+
630+
this.filter.doFilter(request, response, filterChain);
631+
632+
verify(this.authenticationManager).authenticate(any());
633+
verifyNoInteractions(filterChain);
634+
635+
assertThat(response.getStatus()).isEqualTo(HttpStatus.FOUND.value());
636+
assertThat(response.getRedirectedUrl())
637+
.isEqualTo("https://example.com?param=encoded%20parameter%20value&code=code&state=client%20state");
638+
}
639+
612640
@Test
613641
public void doFilterWhenAuthenticationRequestAuthenticatedThenAuthorizationResponse() throws Exception {
614-
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().scopes(Set::clear).build();
642+
// Setup OpenID Connect request
643+
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().scopes((scopes) -> {
644+
scopes.clear();
645+
scopes.add(OidcScopes.OPENID);
646+
}).build();
615647
OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthenticationResult = new OAuth2AuthorizationCodeRequestAuthenticationToken(
616648
AUTHORIZATION_URI, registeredClient.getClientId(), this.principal, this.authorizationCode,
617649
registeredClient.getRedirectUris().iterator().next(), STATE, registeredClient.getScopes());
618650
authorizationCodeRequestAuthenticationResult.setAuthenticated(true);
619651
given(this.authenticationManager.authenticate(any())).willReturn(authorizationCodeRequestAuthenticationResult);
620652

621653
MockHttpServletRequest request = createAuthorizationRequest(registeredClient);
622-
request.setMethod("POST");
654+
request.setMethod("POST"); // OpenID Connect supports POST method
623655
request.setQueryString(null);
624656
MockHttpServletResponse response = new MockHttpServletResponse();
625657
FilterChain filterChain = mock(FilterChain.class);

0 commit comments

Comments
 (0)