Skip to content

Commit 9ebc52b

Browse files
committed
Missing response_type in POST authorization request returns invalid_request
Closes gh-2226
1 parent 2af805b commit 9ebc52b

File tree

4 files changed

+40
-25
lines changed

4 files changed

+40
-25
lines changed

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.springframework.security.oauth2.core.OAuth2Error;
4040
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse;
4141
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
42+
import org.springframework.security.oauth2.core.endpoint.PkceParameterNames;
4243
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationException;
4344
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationProvider;
4445
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationToken;
@@ -150,18 +151,24 @@ private static RequestMatcher createDefaultRequestMatcher(String authorizationEn
150151
HttpMethod.GET.name());
151152
RequestMatcher authorizationRequestPostMatcher = new AntPathRequestMatcher(authorizationEndpointUri,
152153
HttpMethod.POST.name());
153-
154-
RequestMatcher responseTypeParameterMatcher = (
155-
request) -> request.getParameter(OAuth2ParameterNames.RESPONSE_TYPE) != null;
156-
154+
RequestMatcher authorizationConsentMatcher = createAuthorizationConsentMatcher(authorizationEndpointUri);
157155
RequestMatcher authorizationRequestMatcher = new OrRequestMatcher(authorizationRequestGetMatcher,
158-
new AndRequestMatcher(authorizationRequestPostMatcher, responseTypeParameterMatcher));
159-
RequestMatcher authorizationConsentMatcher = new AndRequestMatcher(authorizationRequestPostMatcher,
160-
new NegatedRequestMatcher(responseTypeParameterMatcher));
161-
156+
new AndRequestMatcher(authorizationRequestPostMatcher,
157+
new NegatedRequestMatcher(authorizationConsentMatcher)));
162158
return new OrRequestMatcher(authorizationRequestMatcher, authorizationConsentMatcher);
163159
}
164160

161+
private static RequestMatcher createAuthorizationConsentMatcher(String authorizationEndpointUri) {
162+
final RequestMatcher authorizationConsentPostMatcher = new AntPathRequestMatcher(authorizationEndpointUri,
163+
HttpMethod.POST.name());
164+
return (request) -> authorizationConsentPostMatcher.matches(request)
165+
&& request.getParameter(OAuth2ParameterNames.RESPONSE_TYPE) == null
166+
&& request.getParameter(OAuth2ParameterNames.REQUEST_URI) == null
167+
&& request.getParameter(OAuth2ParameterNames.REDIRECT_URI) == null
168+
&& request.getParameter(PkceParameterNames.CODE_CHALLENGE) == null
169+
&& request.getParameter(PkceParameterNames.CODE_CHALLENGE_METHOD) == null;
170+
}
171+
165172
@Override
166173
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
167174
throws ServletException, IOException {

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@
4343
import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationEndpointFilter;
4444
import org.springframework.security.oauth2.server.authorization.web.OAuth2PushedAuthorizationRequestEndpointFilter;
4545
import org.springframework.security.web.authentication.AuthenticationConverter;
46-
import org.springframework.security.web.util.matcher.AndRequestMatcher;
47-
import org.springframework.security.web.util.matcher.OrRequestMatcher;
4846
import org.springframework.security.web.util.matcher.RequestMatcher;
4947
import org.springframework.util.CollectionUtils;
5048
import org.springframework.util.MultiValueMap;
@@ -197,12 +195,10 @@ private boolean isPushedAuthorizationRequest(HttpServletRequest request) {
197195
}
198196

199197
private static RequestMatcher createDefaultRequestMatcher() {
200-
RequestMatcher getMethodMatcher = (request) -> "GET".equals(request.getMethod());
201-
RequestMatcher postMethodMatcher = (request) -> "POST".equals(request.getMethod());
202-
RequestMatcher responseTypeParameterMatcher = (
203-
request) -> request.getParameter(OAuth2ParameterNames.RESPONSE_TYPE) != null;
204-
return new OrRequestMatcher(getMethodMatcher,
205-
new AndRequestMatcher(postMethodMatcher, responseTypeParameterMatcher));
198+
final RequestMatcher authorizationConsentMatcher = OAuth2AuthorizationConsentAuthenticationConverter
199+
.createDefaultRequestMatcher();
200+
return (request) -> "GET".equals(request.getMethod())
201+
|| ("POST".equals(request.getMethod()) && !authorizationConsentMatcher.matches(request));
206202
}
207203

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

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,11 @@
2929
import org.springframework.security.oauth2.core.OAuth2Error;
3030
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
3131
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
32+
import org.springframework.security.oauth2.core.endpoint.PkceParameterNames;
3233
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeRequestAuthenticationException;
3334
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationConsentAuthenticationToken;
3435
import org.springframework.security.oauth2.server.authorization.web.OAuth2AuthorizationEndpointFilter;
3536
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;
3837
import org.springframework.security.web.util.matcher.RequestMatcher;
3938
import org.springframework.util.MultiValueMap;
4039
import org.springframework.util.StringUtils;
@@ -105,11 +104,13 @@ public Authentication convert(HttpServletRequest request) {
105104
additionalParameters);
106105
}
107106

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));
107+
static RequestMatcher createDefaultRequestMatcher() {
108+
return (request) -> "POST".equals(request.getMethod())
109+
&& request.getParameter(OAuth2ParameterNames.RESPONSE_TYPE) == null
110+
&& request.getParameter(OAuth2ParameterNames.REQUEST_URI) == null
111+
&& request.getParameter(OAuth2ParameterNames.REDIRECT_URI) == null
112+
&& request.getParameter(PkceParameterNames.CODE_CHALLENGE) == null
113+
&& request.getParameter(PkceParameterNames.CODE_CHALLENGE_METHOD) == null;
113114
}
114115

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

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,17 @@ public void doFilterWhenAuthorizationRequestMissingResponseTypeThenInvalidReques
206206
});
207207
}
208208

209+
// gh-2226
210+
@Test
211+
public void doFilterWhenPostAuthorizationRequestMissingResponseTypeThenInvalidRequestError() throws Exception {
212+
doFilterWhenAuthorizationRequestInvalidParameterThenError(TestRegisteredClients.registeredClient().build(),
213+
OAuth2ParameterNames.RESPONSE_TYPE, OAuth2ErrorCodes.INVALID_REQUEST, (request) -> {
214+
request.setMethod("POST");
215+
request.removeParameter(OAuth2ParameterNames.RESPONSE_TYPE);
216+
request.setQueryString(null);
217+
});
218+
}
219+
209220
@Test
210221
public void doFilterWhenAuthorizationRequestMultipleResponseTypeThenInvalidRequestError() throws Exception {
211222
doFilterWhenAuthorizationRequestInvalidParameterThenError(TestRegisteredClients.registeredClient().build(),
@@ -645,7 +656,7 @@ public void doFilterWhenPostAuthorizationRequestAuthenticatedThenAuthorizationRe
645656

646657
this.filter.doFilter(request, response, filterChain);
647658

648-
verify(this.authenticationManager).authenticate(any());
659+
verify(this.authenticationManager).authenticate(any(OAuth2AuthorizationCodeRequestAuthenticationToken.class));
649660
verifyNoInteractions(filterChain);
650661

651662
assertThat(response.getStatus()).isEqualTo(HttpStatus.FOUND.value());
@@ -674,7 +685,7 @@ public void doFilterWhenAuthenticationRequestAuthenticatedThenAuthorizationRespo
674685

675686
this.filter.doFilter(request, response, filterChain);
676687

677-
verify(this.authenticationManager).authenticate(any());
688+
verify(this.authenticationManager).authenticate(any(OAuth2AuthorizationCodeRequestAuthenticationToken.class));
678689
verifyNoInteractions(filterChain);
679690

680691
assertThat(response.getStatus()).isEqualTo(HttpStatus.FOUND.value());

0 commit comments

Comments
 (0)