Remove redundant validation for redirect-uri
Fixes gh-7706
This commit is contained in:
parent
752d5f29aa
commit
148b570a98
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -30,7 +30,6 @@ import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResp
|
||||||
*/
|
*/
|
||||||
final class OAuth2AuthorizationExchangeValidator {
|
final class OAuth2AuthorizationExchangeValidator {
|
||||||
private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
|
private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
|
||||||
private static final String INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE = "invalid_redirect_uri_parameter";
|
|
||||||
|
|
||||||
static void validate(OAuth2AuthorizationExchange authorizationExchange) {
|
static void validate(OAuth2AuthorizationExchange authorizationExchange) {
|
||||||
OAuth2AuthorizationRequest authorizationRequest = authorizationExchange.getAuthorizationRequest();
|
OAuth2AuthorizationRequest authorizationRequest = authorizationExchange.getAuthorizationRequest();
|
||||||
|
@ -44,10 +43,5 @@ final class OAuth2AuthorizationExchangeValidator {
|
||||||
OAuth2Error oauth2Error = new OAuth2Error(INVALID_STATE_PARAMETER_ERROR_CODE);
|
OAuth2Error oauth2Error = new OAuth2Error(INVALID_STATE_PARAMETER_ERROR_CODE);
|
||||||
throw new OAuth2AuthorizationException(oauth2Error);
|
throw new OAuth2AuthorizationException(oauth2Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!authorizationResponse.getRedirectUri().equals(authorizationRequest.getRedirectUri())) {
|
|
||||||
OAuth2Error oauth2Error = new OAuth2Error(INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE);
|
|
||||||
throw new OAuth2AuthorizationException(oauth2Error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,6 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public class OidcAuthorizationCodeAuthenticationProvider implements AuthenticationProvider {
|
public class OidcAuthorizationCodeAuthenticationProvider implements AuthenticationProvider {
|
||||||
private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
|
private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
|
||||||
private static final String INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE = "invalid_redirect_uri_parameter";
|
|
||||||
private static final String INVALID_ID_TOKEN_ERROR_CODE = "invalid_id_token";
|
private static final String INVALID_ID_TOKEN_ERROR_CODE = "invalid_id_token";
|
||||||
private static final String INVALID_NONCE_ERROR_CODE = "invalid_nonce";
|
private static final String INVALID_NONCE_ERROR_CODE = "invalid_nonce";
|
||||||
private final OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient;
|
private final OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient;
|
||||||
|
@ -132,11 +131,6 @@ public class OidcAuthorizationCodeAuthenticationProvider implements Authenticati
|
||||||
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!authorizationResponse.getRedirectUri().equals(authorizationRequest.getRedirectUri())) {
|
|
||||||
OAuth2Error oauth2Error = new OAuth2Error(INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE);
|
|
||||||
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
OAuth2AccessTokenResponse accessTokenResponse;
|
OAuth2AccessTokenResponse accessTokenResponse;
|
||||||
try {
|
try {
|
||||||
accessTokenResponse = this.accessTokenResponseClient.getTokenResponse(
|
accessTokenResponse = this.accessTokenResponseClient.getTokenResponse(
|
||||||
|
|
|
@ -80,7 +80,6 @@ public class OidcAuthorizationCodeReactiveAuthenticationManager implements
|
||||||
ReactiveAuthenticationManager {
|
ReactiveAuthenticationManager {
|
||||||
|
|
||||||
private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
|
private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
|
||||||
private static final String INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE = "invalid_redirect_uri_parameter";
|
|
||||||
private static final String INVALID_ID_TOKEN_ERROR_CODE = "invalid_id_token";
|
private static final String INVALID_ID_TOKEN_ERROR_CODE = "invalid_id_token";
|
||||||
private static final String INVALID_NONCE_ERROR_CODE = "invalid_nonce";
|
private static final String INVALID_NONCE_ERROR_CODE = "invalid_nonce";
|
||||||
|
|
||||||
|
@ -131,11 +130,6 @@ public class OidcAuthorizationCodeReactiveAuthenticationManager implements
|
||||||
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!authorizationResponse.getRedirectUri().equals(authorizationRequest.getRedirectUri())) {
|
|
||||||
OAuth2Error oauth2Error = new OAuth2Error(INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE);
|
|
||||||
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
OAuth2AuthorizationCodeGrantRequest authzRequest = new OAuth2AuthorizationCodeGrantRequest(
|
OAuth2AuthorizationCodeGrantRequest authzRequest = new OAuth2AuthorizationCodeGrantRequest(
|
||||||
authorizationCodeAuthentication.getClientRegistration(),
|
authorizationCodeAuthentication.getClientRegistration(),
|
||||||
authorizationCodeAuthentication.getAuthorizationExchange());
|
authorizationCodeAuthentication.getAuthorizationExchange());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -98,19 +98,6 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
|
||||||
}).isInstanceOf(OAuth2AuthorizationException.class).hasMessageContaining("invalid_state_parameter");
|
}).isInstanceOf(OAuth2AuthorizationException.class).hasMessageContaining("invalid_state_parameter");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void authenticateWhenAuthorizationResponseRedirectUriNotEqualAuthorizationRequestRedirectUriThenThrowOAuth2AuthorizationException() {
|
|
||||||
OAuth2AuthorizationResponse authorizationResponse = success().redirectUri("https://example2.com").build();
|
|
||||||
OAuth2AuthorizationExchange authorizationExchange = new OAuth2AuthorizationExchange(
|
|
||||||
this.authorizationRequest, authorizationResponse);
|
|
||||||
|
|
||||||
assertThatThrownBy(() -> {
|
|
||||||
this.authenticationProvider.authenticate(
|
|
||||||
new OAuth2AuthorizationCodeAuthenticationToken(
|
|
||||||
this.clientRegistration, authorizationExchange));
|
|
||||||
}).isInstanceOf(OAuth2AuthorizationException.class).hasMessageContaining("invalid_redirect_uri_parameter");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void authenticateWhenAuthorizationSuccessResponseThenExchangedForAccessToken() {
|
public void authenticateWhenAuthorizationSuccessResponseThenExchangedForAccessToken() {
|
||||||
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().refreshToken("refresh").build();
|
OAuth2AccessTokenResponse accessTokenResponse = accessTokenResponse().refreshToken("refresh").build();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -81,13 +81,6 @@ public class OAuth2AuthorizationCodeReactiveAuthenticationManagerTests {
|
||||||
.isInstanceOf(OAuth2AuthorizationException.class);
|
.isInstanceOf(OAuth2AuthorizationException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void authenticateWhenRedirectUriNotEqualThenOAuth2AuthorizationException() {
|
|
||||||
this.authorizationRequest.redirectUri("https://example.org/notequal");
|
|
||||||
assertThatCode(() -> authenticate())
|
|
||||||
.isInstanceOf(OAuth2AuthorizationException.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void authenticateWhenValidThenSuccess() {
|
public void authenticateWhenValidThenSuccess() {
|
||||||
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(this.tokenResponse.build()));
|
when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(this.tokenResponse.build()));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -151,20 +151,6 @@ public class OAuth2LoginAuthenticationProviderTests {
|
||||||
new OAuth2LoginAuthenticationToken(this.clientRegistration, authorizationExchange));
|
new OAuth2LoginAuthenticationToken(this.clientRegistration, authorizationExchange));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void authenticateWhenAuthorizationResponseRedirectUriNotEqualAuthorizationRequestRedirectUriThenThrowOAuth2AuthenticationException() {
|
|
||||||
this.exception.expect(OAuth2AuthenticationException.class);
|
|
||||||
this.exception.expectMessage(containsString("invalid_redirect_uri_parameter"));
|
|
||||||
|
|
||||||
OAuth2AuthorizationResponse authorizationResponse =
|
|
||||||
success().redirectUri("https://example2.com").build();
|
|
||||||
OAuth2AuthorizationExchange authorizationExchange =
|
|
||||||
new OAuth2AuthorizationExchange(this.authorizationRequest, authorizationResponse);
|
|
||||||
|
|
||||||
this.authenticationProvider.authenticate(
|
|
||||||
new OAuth2LoginAuthenticationToken(this.clientRegistration, authorizationExchange));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void authenticateWhenLoginSuccessThenReturnAuthentication() {
|
public void authenticateWhenLoginSuccessThenReturnAuthentication() {
|
||||||
OAuth2AccessTokenResponse accessTokenResponse = this.accessTokenSuccessResponse();
|
OAuth2AccessTokenResponse accessTokenResponse = this.accessTokenSuccessResponse();
|
||||||
|
|
|
@ -186,19 +186,6 @@ public class OidcAuthorizationCodeAuthenticationProviderTests {
|
||||||
new OAuth2LoginAuthenticationToken(this.clientRegistration, authorizationExchange));
|
new OAuth2LoginAuthenticationToken(this.clientRegistration, authorizationExchange));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void authenticateWhenAuthorizationResponseRedirectUriNotEqualAuthorizationRequestRedirectUriThenThrowOAuth2AuthenticationException() {
|
|
||||||
this.exception.expect(OAuth2AuthenticationException.class);
|
|
||||||
this.exception.expectMessage(containsString("invalid_redirect_uri_parameter"));
|
|
||||||
|
|
||||||
OAuth2AuthorizationResponse authorizationResponse = success().redirectUri("https://example2.com").build();
|
|
||||||
OAuth2AuthorizationExchange authorizationExchange =
|
|
||||||
new OAuth2AuthorizationExchange(this.authorizationRequest, authorizationResponse);
|
|
||||||
|
|
||||||
this.authenticationProvider.authenticate(
|
|
||||||
new OAuth2LoginAuthenticationToken(this.clientRegistration, authorizationExchange));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void authenticateWhenTokenResponseDoesNotContainIdTokenThenThrowOAuth2AuthenticationException() {
|
public void authenticateWhenTokenResponseDoesNotContainIdTokenThenThrowOAuth2AuthenticationException() {
|
||||||
this.exception.expect(OAuth2AuthenticationException.class);
|
this.exception.expect(OAuth2AuthenticationException.class);
|
||||||
|
|
|
@ -255,42 +255,6 @@ public class OAuth2LoginApplicationTests {
|
||||||
assertThat(errorElement.asText()).contains("authorization_request_not_found");
|
assertThat(errorElement.asText()).contains("authorization_request_not_found");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void requestAuthorizationCodeGrantWhenInvalidRedirectUriThenDisplayLoginPageWithError() throws Exception {
|
|
||||||
HtmlPage page = this.webClient.getPage("/");
|
|
||||||
URL loginPageUrl = page.getBaseURL();
|
|
||||||
URL loginErrorPageUrl = new URL(loginPageUrl.toString() + "?error");
|
|
||||||
|
|
||||||
ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId("google");
|
|
||||||
|
|
||||||
HtmlAnchor clientAnchorElement = this.getClientAnchorElement(page, clientRegistration);
|
|
||||||
assertThat(clientAnchorElement).isNotNull();
|
|
||||||
|
|
||||||
WebResponse response = this.followLinkDisableRedirects(clientAnchorElement);
|
|
||||||
|
|
||||||
UriComponents authorizeRequestUriComponents = UriComponentsBuilder.fromUri(
|
|
||||||
URI.create(response.getResponseHeaderValue("Location"))).build();
|
|
||||||
|
|
||||||
Map<String, String> params = authorizeRequestUriComponents.getQueryParams().toSingleValueMap();
|
|
||||||
String code = "auth-code";
|
|
||||||
String state = URLDecoder.decode(params.get(OAuth2ParameterNames.STATE), "UTF-8");
|
|
||||||
String redirectUri = URLDecoder.decode(params.get(OAuth2ParameterNames.REDIRECT_URI), "UTF-8");
|
|
||||||
redirectUri += "-invalid";
|
|
||||||
|
|
||||||
String authorizationResponseUri =
|
|
||||||
UriComponentsBuilder.fromHttpUrl(redirectUri)
|
|
||||||
.queryParam(OAuth2ParameterNames.CODE, code)
|
|
||||||
.queryParam(OAuth2ParameterNames.STATE, state)
|
|
||||||
.build().encode().toUriString();
|
|
||||||
|
|
||||||
page = this.webClient.getPage(new URL(authorizationResponseUri));
|
|
||||||
assertThat(page.getBaseURL()).isEqualTo(loginErrorPageUrl);
|
|
||||||
|
|
||||||
HtmlElement errorElement = page.getBody().getFirstByXPath("div");
|
|
||||||
assertThat(errorElement).isNotNull();
|
|
||||||
assertThat(errorElement.asText()).contains("invalid_redirect_uri_parameter");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertLoginPage(HtmlPage page) {
|
private void assertLoginPage(HtmlPage page) {
|
||||||
assertThat(page.getTitleText()).isEqualTo("Please sign in");
|
assertThat(page.getTitleText()).isEqualTo("Please sign in");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue