From 77db241ef0fe5532cf31c0c9ec9c7be38752d266 Mon Sep 17 00:00:00 2001 From: "shazin.sadakath@gmail.com" Date: Fri, 13 Oct 2017 21:33:54 +0530 Subject: [PATCH] Adding nonce to Authentication Request #4442 --- .../AuthorizationCodeRequestRedirectFilter.java | 3 +++ .../web/AuthorizationRequestUriBuilder.java | 1 + .../DefaultAuthorizationRequestUriBuilder.java | 3 ++- ...nCodeAuthenticationProcessingFilterTests.java | 16 ++++++++++++---- ...horizationCodeRequestRedirectFilterTests.java | 2 ++ .../endpoint/AuthorizationRequestAttributes.java | 11 +++++++++++ .../oauth2/core/endpoint/OAuth2Parameter.java | 2 ++ 7 files changed, 33 insertions(+), 5 deletions(-) diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java index da97192a895..00620a44a7f 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java @@ -122,6 +122,8 @@ protected void sendRedirectForAuthorizationCode(HttpServletRequest request, Http throw new IllegalArgumentException("Invalid Client Identifier (Registration Id): " + registrationId); } + String nonce = request.getParameter(OAuth2Parameter.NONCE); + String redirectUriStr = this.expandRedirectUri(request, clientRegistration); Map additionalParameters = new HashMap<>(); @@ -134,6 +136,7 @@ protected void sendRedirectForAuthorizationCode(HttpServletRequest request, Http .redirectUri(redirectUriStr) .scope(clientRegistration.getScope()) .state(this.stateGenerator.generateKey()) + .nonce(nonce) .additionalParameters(additionalParameters) .build(); diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationRequestUriBuilder.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationRequestUriBuilder.java index a2fe694c361..c399c253a61 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationRequestUriBuilder.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationRequestUriBuilder.java @@ -32,6 +32,7 @@ *
  • response type (required)
  • *
  • requested scope(s) (optional)
  • *
  • state (recommended)
  • + *
  • nonce (recommended)
  • *
  • redirection URI (optional) - the authorization server will send the user-agent back to once access is granted (or denied) by the end-user (resource owner)
  • * * diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultAuthorizationRequestUriBuilder.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultAuthorizationRequestUriBuilder.java index f5e7b6d7bf2..382e220536e 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultAuthorizationRequestUriBuilder.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultAuthorizationRequestUriBuilder.java @@ -46,7 +46,8 @@ public URI build(AuthorizationRequestAttributes authorizationRequestAttributes) .queryParam(OAuth2Parameter.CLIENT_ID, authorizationRequestAttributes.getClientId()) .queryParam(OAuth2Parameter.SCOPE, authorizationRequestAttributes.getScope().stream().collect(Collectors.joining(" "))) - .queryParam(OAuth2Parameter.STATE, authorizationRequestAttributes.getState()); + .queryParam(OAuth2Parameter.STATE, authorizationRequestAttributes.getState()) + .queryParam(OAuth2Parameter.NONCE, authorizationRequestAttributes.getNonce()); return uriBuilder.build().encode().toUri(); } diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilterTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilterTests.java index 42b23093263..da81d82342b 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilterTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeAuthenticationProcessingFilterTests.java @@ -105,10 +105,12 @@ public void doFilterWhenAuthorizationCodeSuccessResponseThenAuthenticationSucces MockHttpServletRequest request = this.setupRequest(clientRegistration); String authCode = "some code"; String state = "some state"; + String nonce = "some nonce"; request.addParameter(OAuth2Parameter.CODE, authCode); request.addParameter(OAuth2Parameter.STATE, state); + request.addParameter(OAuth2Parameter.NONCE, nonce); MockHttpServletResponse response = new MockHttpServletResponse(); - setupAuthorizationRequest(authorizationRequestRepository, request, response, clientRegistration, state); + setupAuthorizationRequest(authorizationRequestRepository, request, response, clientRegistration, state, nonce); FilterChain filterChain = Mockito.mock(FilterChain.class); filter.doFilter(request, response, filterChain); @@ -155,10 +157,12 @@ public void doFilterWhenAuthorizationCodeSuccessResponseWithInvalidStateParamThe MockHttpServletRequest request = this.setupRequest(clientRegistration); String authCode = "some code"; String state = "some other state"; + String nonce = "some nonce"; request.addParameter(OAuth2Parameter.CODE, authCode); request.addParameter(OAuth2Parameter.STATE, state); + request.addParameter(OAuth2Parameter.NONCE, nonce); MockHttpServletResponse response = new MockHttpServletResponse(); - setupAuthorizationRequest(authorizationRequestRepository, request, response, clientRegistration, "some state"); + setupAuthorizationRequest(authorizationRequestRepository, request, response, clientRegistration, "some state", nonce); FilterChain filterChain = Mockito.mock(FilterChain.class); filter.doFilter(request, response, filterChain); @@ -180,10 +184,12 @@ public void doFilterWhenAuthorizationCodeSuccessResponseWithInvalidRedirectUriPa request.setRequestURI(request.getRequestURI() + "-other"); String authCode = "some code"; String state = "some state"; + String nonce = "some nonce"; request.addParameter(OAuth2Parameter.CODE, authCode); request.addParameter(OAuth2Parameter.STATE, state); + request.addParameter(OAuth2Parameter.NONCE, nonce); MockHttpServletResponse response = new MockHttpServletResponse(); - setupAuthorizationRequest(authorizationRequestRepository, request, response, clientRegistration, state); + setupAuthorizationRequest(authorizationRequestRepository, request, response, clientRegistration, state, nonce); FilterChain filterChain = Mockito.mock(FilterChain.class); filter.doFilter(request, response, filterChain); @@ -230,7 +236,8 @@ private void setupAuthorizationRequest(AuthorizationRequestRepository authorizat HttpServletRequest request, HttpServletResponse response, ClientRegistration clientRegistration, - String state) { + String state, + String nonce) { Map additionalParameters = new HashMap<>(); additionalParameters.put(OAuth2Parameter.REGISTRATION_ID, clientRegistration.getRegistrationId()); @@ -242,6 +249,7 @@ private void setupAuthorizationRequest(AuthorizationRequestRepository authorizat .redirectUri(clientRegistration.getRedirectUri()) .scope(clientRegistration.getScope()) .state(state) + .nonce(nonce) .additionalParameters(additionalParameters) .build(); diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilterTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilterTests.java index 70478c5f3c9..c02b49f3baf 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilterTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilterTests.java @@ -92,6 +92,7 @@ public void doFilterWhenRequestMatchesClientThenAuthorizationRequestSavedInSessi String requestUri = TestUtil.AUTHORIZATION_BASE_URI + "/" + clientRegistration.getRegistrationId(); MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri); request.setServletPath(requestUri); + request.addParameter("nonce", "some nonce"); MockHttpServletResponse response = new MockHttpServletResponse(); FilterChain filterChain = Mockito.mock(FilterChain.class); @@ -111,6 +112,7 @@ public void doFilterWhenRequestMatchesClientThenAuthorizationRequestSavedInSessi Assertions.assertThat(authorizationRequestAttributes.getRedirectUri()).isNotNull(); Assertions.assertThat(authorizationRequestAttributes.getScope()).isNotNull(); Assertions.assertThat(authorizationRequestAttributes.getState()).isNotNull(); + Assertions.assertThat(authorizationRequestAttributes.getNonce()).isNotNull(); } private AuthorizationCodeRequestRedirectFilter setupFilter(String authorizationUri, diff --git a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/AuthorizationRequestAttributes.java b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/AuthorizationRequestAttributes.java index 06df2dbaf9b..4c6b0bb552e 100644 --- a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/AuthorizationRequestAttributes.java +++ b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/AuthorizationRequestAttributes.java @@ -31,6 +31,7 @@ * for the authorization code grant type or implicit grant type. * * @author Joe Grandja + * @author Shazin Sadakath * @since 5.0 * @see AuthorizationGrantType * @see ResponseType @@ -45,6 +46,7 @@ public final class AuthorizationRequestAttributes implements Serializable { private String redirectUri; private Set scope; private String state; + private String nonce; private Map additionalParameters; private AuthorizationRequestAttributes() { @@ -82,6 +84,10 @@ public Map getAdditionalParameters() { return this.additionalParameters; } + public String getNonce() { + return nonce; + } + public static Builder withAuthorizationCode() { return new Builder(AuthorizationGrantType.AUTHORIZATION_CODE); } @@ -123,6 +129,11 @@ public Builder state(String state) { return this; } + public Builder nonce(String nonce) { + this.authorizationRequest.nonce = nonce; + return this; + } + public Builder additionalParameters(Map additionalParameters) { this.authorizationRequest.additionalParameters = additionalParameters; return this; diff --git a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/OAuth2Parameter.java b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/OAuth2Parameter.java index c548b3ec2f0..f034895304b 100644 --- a/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/OAuth2Parameter.java +++ b/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/endpoint/OAuth2Parameter.java @@ -45,4 +45,6 @@ public interface OAuth2Parameter { String REGISTRATION_ID = "registration_id"; // Non-standard additional parameter + String NONCE = "nonce"; + }