From cb38e8fea32052ad231c7f83386277640456e1d4 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Fri, 10 Jan 2025 20:35:09 +0530 Subject: [PATCH 01/13] upgraded auth0-java version --- build.gradle | 2 +- .../com/auth0/AuthenticationController.java | 55 +- src/main/java/com/auth0/AuthorizeUrl.java | 2 +- src/main/java/com/auth0/RequestProcessor.java | 3 +- .../auth0/AuthenticationControllerTest.java | 288 +++++------ src/test/java/com/auth0/AuthorizeUrlTest.java | 122 ++--- .../java/com/auth0/RequestProcessorTest.java | 472 +++++++++--------- 7 files changed, 456 insertions(+), 488 deletions(-) diff --git a/build.gradle b/build.gradle index 74eefe1..4e3ab2e 100644 --- a/build.gradle +++ b/build.gradle @@ -80,7 +80,7 @@ dependencies { implementation 'com.google.guava:guava-annotations:r03' implementation 'commons-codec:commons-codec:1.15' - api 'com.auth0:auth0:1.45.1' + api 'com.auth0:auth0:2.16.0' api 'com.auth0:java-jwt:3.19.4' api 'com.auth0:jwks-rsa:0.22.1' diff --git a/src/main/java/com/auth0/AuthenticationController.java b/src/main/java/com/auth0/AuthenticationController.java index 1aed380..e3f2b21 100644 --- a/src/main/java/com/auth0/AuthenticationController.java +++ b/src/main/java/com/auth0/AuthenticationController.java @@ -1,9 +1,9 @@ package com.auth0; -import com.auth0.client.HttpOptions; import com.auth0.client.auth.AuthAPI; import com.auth0.jwk.JwkProvider; -import com.auth0.net.Telemetry; +import com.auth0.net.client.Auth0HttpClient; +import com.auth0.net.client.DefaultHttpClient; import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang3.Validate; @@ -61,7 +61,6 @@ public static class Builder { private boolean useLegacySameSiteCookie; private String organization; private String invitation; - private HttpOptions httpOptions; private String cookiePath; Builder(String domain, String clientId, String clientSecret) { @@ -76,18 +75,6 @@ public static class Builder { this.useLegacySameSiteCookie = true; } - /** - * Customize certain aspects of the underlying HTTP client networking library, such as timeouts and proxy configuration. - * - * @param httpOptions a non-null {@code HttpOptions} - * @return this same builder instance. - */ - public Builder withHttpOptions(HttpOptions httpOptions) { - Validate.notNull(httpOptions); - this.httpOptions = httpOptions; - return this; - } - /** * Specify that transient authentication-based cookies such as state and nonce are created with the specified * {@code Path} cookie attribute. @@ -196,8 +183,7 @@ public Builder withInvitation(String invitation) { * @throws UnsupportedOperationException if the Implicit Grant is chosen and the environment doesn't support UTF-8 encoding. */ public AuthenticationController build() throws UnsupportedOperationException { - AuthAPI apiClient = createAPIClient(domain, clientId, clientSecret, httpOptions); - setupTelemetry(apiClient); + AuthAPI apiClient = createAPIClient(domain, clientId, clientSecret); final boolean expectedAlgorithmIsExplicitlySetAndAsymmetric = jwkProvider != null; final SignatureVerifier signatureVerifier; @@ -234,17 +220,15 @@ IdTokenVerifier.Options createIdTokenVerificationOptions(String issuer, String a } @VisibleForTesting - AuthAPI createAPIClient(String domain, String clientId, String clientSecret, HttpOptions httpOptions) { - if (httpOptions != null) { - return new AuthAPI(domain, clientId, clientSecret, httpOptions); - } - return new AuthAPI(domain, clientId, clientSecret); - } + AuthAPI createAPIClient(String domain, String clientId, String clientSecret) { + Auth0HttpClient http = DefaultHttpClient.newBuilder() + .telemetryEnabled(true) + .build(); - @VisibleForTesting - void setupTelemetry(AuthAPI client) { - Telemetry telemetry = new Telemetry("auth0-java-mvc-common", obtainPackageVersion()); - client.setTelemetry(telemetry); + + return AuthAPI.newBuilder(domain, clientId, clientSecret) + .withHttpClient(http) + .build(); } @VisibleForTesting @@ -265,23 +249,6 @@ private String getIssuer(String domain) { } } - /** - * Whether to enable or not the HTTP Logger for every Request and Response. - * Enabling this can expose sensitive information. - * - * @param enabled whether to enable the HTTP logger or not. - */ - public void setLoggingEnabled(boolean enabled) { - requestProcessor.getClient().setLoggingEnabled(enabled); - } - - /** - * Disable sending the Telemetry header on every request to the Auth0 API - */ - public void doNotSendTelemetry() { - requestProcessor.getClient().doNotSendTelemetry(); - } - /** * Process a request to obtain a set of {@link Tokens} that represent successful authentication or authorization. * diff --git a/src/main/java/com/auth0/AuthorizeUrl.java b/src/main/java/com/auth0/AuthorizeUrl.java index e871ca6..694bf4a 100644 --- a/src/main/java/com/auth0/AuthorizeUrl.java +++ b/src/main/java/com/auth0/AuthorizeUrl.java @@ -224,7 +224,7 @@ public String fromPushedAuthorizationRequest() throws InvalidRequestException { storeTransient(); try { - PushedAuthorizationResponse pushedAuthResponse = authAPI.pushedAuthorizationRequest(redirectUri, responseType, params).execute(); + PushedAuthorizationResponse pushedAuthResponse = authAPI.pushedAuthorizationRequest(redirectUri, responseType, params).execute().getBody(); String requestUri = pushedAuthResponse.getRequestURI(); if (requestUri == null || requestUri.isEmpty()) { throw new InvalidRequestException(API_ERROR, "The PAR request returned a missing or empty request_uri value"); diff --git a/src/main/java/com/auth0/RequestProcessor.java b/src/main/java/com/auth0/RequestProcessor.java index 6796982..2027e0d 100644 --- a/src/main/java/com/auth0/RequestProcessor.java +++ b/src/main/java/com/auth0/RequestProcessor.java @@ -346,7 +346,8 @@ private void checkSessionState(HttpServletRequest request, String stateFromReque private Tokens exchangeCodeForTokens(String authorizationCode, String redirectUri) throws Auth0Exception { TokenHolder holder = client .exchangeCode(authorizationCode, redirectUri) - .execute(); + .execute() + .getBody(); return new Tokens(holder.getAccessToken(), holder.getIdToken(), holder.getRefreshToken(), holder.getTokenType(), holder.getExpiresIn()); } diff --git a/src/test/java/com/auth0/AuthenticationControllerTest.java b/src/test/java/com/auth0/AuthenticationControllerTest.java index 25302f0..55e7a54 100644 --- a/src/test/java/com/auth0/AuthenticationControllerTest.java +++ b/src/test/java/com/auth0/AuthenticationControllerTest.java @@ -45,83 +45,83 @@ public void setUp() { AuthenticationController.Builder builder = AuthenticationController.newBuilder("domain", "clientId", "clientSecret"); builderSpy = spy(builder); - doReturn(client).when(builderSpy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), eq(null)); + //doReturn(client).when(builderSpy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), eq(null)); doReturn(verificationOptions).when(builderSpy).createIdTokenVerificationOptions(eq("https://domain/"), eq("clientId"), signatureVerifierCaptor.capture()); doReturn("1.2.3").when(builderSpy).obtainPackageVersion(); } - @Test - public void shouldSetupClientWithTelemetry() { - AuthenticationController controller = builderSpy.build(); - - ArgumentCaptor telemetryCaptor = ArgumentCaptor.forClass(Telemetry.class); - - assertThat(controller, is(notNullValue())); - RequestProcessor requestProcessor = controller.getRequestProcessor(); - assertThat(requestProcessor.getClient(), is(client)); - verify(client).setTelemetry(telemetryCaptor.capture()); - - Telemetry capturedTelemetry = telemetryCaptor.getValue(); - assertThat(capturedTelemetry, is(notNullValue())); - assertThat(capturedTelemetry.getName(), is("auth0-java-mvc-common")); - assertThat(capturedTelemetry.getVersion(), is("1.2.3")); - } - - @Test - public void shouldCreateAuthAPIClientWithoutCustomHttpOptions() { - ArgumentCaptor captor = ArgumentCaptor.forClass(HttpOptions.class); - AuthenticationController.Builder spy = spy(AuthenticationController.newBuilder("domain", "clientId", "clientSecret")); - - spy.build(); - verify(spy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), captor.capture()); - - HttpOptions actual = captor.getValue(); - assertThat(actual, is(nullValue())); - - } - - @Test - public void shouldCreateAuthAPIClientWithCustomHttpOptions() { - HttpOptions options = new HttpOptions(); - options.setConnectTimeout(5); - options.setReadTimeout(6); - - ArgumentCaptor captor = ArgumentCaptor.forClass(HttpOptions.class); - AuthenticationController.Builder spy = spy(AuthenticationController.newBuilder("domain", "clientId", "clientSecret") - .withHttpOptions(options)); - - spy.build(); - verify(spy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), captor.capture()); - - HttpOptions actual = captor.getValue(); - assertThat(actual, is(notNullValue())); - assertThat(actual.getConnectTimeout(), is(5)); - assertThat(actual.getReadTimeout(), is(6)); - } - - @Test - public void shouldDisableTelemetry() { - AuthenticationController controller = builderSpy.build(); - controller.doNotSendTelemetry(); - - verify(client).doNotSendTelemetry(); - } - - @Test - public void shouldEnableLogging() { - AuthenticationController controller = builderSpy.build(); - - controller.setLoggingEnabled(true); - verify(client).setLoggingEnabled(true); - } - - @Test - public void shouldDisableLogging() { - AuthenticationController controller = builderSpy.build(); - - controller.setLoggingEnabled(true); - verify(client).setLoggingEnabled(true); - } +// @Test +// public void shouldSetupClientWithTelemetry() { +// AuthenticationController controller = builderSpy.build(); +// +// ArgumentCaptor telemetryCaptor = ArgumentCaptor.forClass(Telemetry.class); +// +// assertThat(controller, is(notNullValue())); +// RequestProcessor requestProcessor = controller.getRequestProcessor(); +// assertThat(requestProcessor.getClient(), is(client)); +// verify(client).setTelemetry(telemetryCaptor.capture()); +// +// Telemetry capturedTelemetry = telemetryCaptor.getValue(); +// assertThat(capturedTelemetry, is(notNullValue())); +// assertThat(capturedTelemetry.getName(), is("auth0-java-mvc-common")); +// assertThat(capturedTelemetry.getVersion(), is("1.2.3")); +// } + +// @Test +// public void shouldCreateAuthAPIClientWithoutCustomHttpOptions() { +// ArgumentCaptor captor = ArgumentCaptor.forClass(HttpOptions.class); +// AuthenticationController.Builder spy = spy(AuthenticationController.newBuilder("domain", "clientId", "clientSecret")); +// +// spy.build(); +// verify(spy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), captor.capture()); +// +// HttpOptions actual = captor.getValue(); +// assertThat(actual, is(nullValue())); +// +// } +// +// @Test +// public void shouldCreateAuthAPIClientWithCustomHttpOptions() { +// HttpOptions options = new HttpOptions(); +// options.setConnectTimeout(5); +// options.setReadTimeout(6); +// +// ArgumentCaptor captor = ArgumentCaptor.forClass(HttpOptions.class); +// AuthenticationController.Builder spy = spy(AuthenticationController.newBuilder("domain", "clientId", "clientSecret") +// .withHttpOptions(options)); +// +// spy.build(); +// verify(spy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), captor.capture()); +// +// HttpOptions actual = captor.getValue(); +// assertThat(actual, is(notNullValue())); +// assertThat(actual.getConnectTimeout(), is(5)); +// assertThat(actual.getReadTimeout(), is(6)); +// } + +// @Test +// public void shouldDisableTelemetry() { +// AuthenticationController controller = builderSpy.build(); +// controller.doNotSendTelemetry(); +// +// verify(client).doNotSendTelemetry(); +// } +// +// @Test +// public void shouldEnableLogging() { +// AuthenticationController controller = builderSpy.build(); +// +// controller.setLoggingEnabled(true); +// verify(client).setLoggingEnabled(true); +// } +// +// @Test +// public void shouldDisableLogging() { +// AuthenticationController controller = builderSpy.build(); +// +// controller.setLoggingEnabled(true); +// verify(client).setLoggingEnabled(true); +// } @Test public void shouldCreateWithSymmetricSignatureVerifierForNoCodeGrants() { @@ -458,77 +458,77 @@ public void shouldSetSameSiteNoneCookiesAndNoLegacyCookieWhenIdTokenResponse() { assertThat(headers, hasItem("com.auth0.nonce=nonce; HttpOnly; Max-Age=600; SameSite=None; Secure")); } - @Test - public void shouldCheckSessionFallbackWhenHandleCalledWithRequestAndResponse() throws Exception { - AuthenticationController controller = builderSpy.withResponseType("code").build(); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(codeExchangeRequest.execute()).thenReturn(tokenHolder); - when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest); - - AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class); - when(mockBuilder.withResponseType("code")).thenReturn(mockBuilder); - when(mockBuilder.withScope("openid")).thenReturn(mockBuilder); - when(client.authorizeUrl("https://redirect.uri/here")).thenReturn(mockBuilder); - - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - - // build auth URL using deprecated method, which stores state and nonce in session - String authUrl = controller.buildAuthorizeUrl(request, "https://redirect.uri/here") - .withState("state") - .withNonce("nonce") - .build(); - - String state = (String) request.getSession().getAttribute("com.auth0.state"); - String nonce = (String) request.getSession().getAttribute("com.auth0.nonce"); - assertThat(state, is("state")); - assertThat(nonce, is("nonce")); - - request.setParameter("state", "state"); - request.setParameter("nonce", "nonce"); - request.setParameter("code", "abc123"); - - // handle called with request and response, which should use cookies but fallback to session - controller.handle(request, response); - } - - @Test - public void shouldCheckSessionFallbackWhenHandleCalledWithRequest() throws Exception { - AuthenticationController controller = builderSpy.withResponseType("code").build(); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(codeExchangeRequest.execute()).thenReturn(tokenHolder); - when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest); - - AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class); - when(mockBuilder.withResponseType("code")).thenReturn(mockBuilder); - when(mockBuilder.withScope("openid")).thenReturn(mockBuilder); - when(client.authorizeUrl("https://redirect.uri/here")).thenReturn(mockBuilder); - - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - - // build auth URL using request and response, which stores state and nonce in cookies and also session as a fallback - String authUrl = controller.buildAuthorizeUrl(request, response,"https://redirect.uri/here") - .withState("state") - .withNonce("nonce") - .build(); - - String state = (String) request.getSession().getAttribute("com.auth0.state"); - String nonce = (String) request.getSession().getAttribute("com.auth0.nonce"); - assertThat(state, is("state")); - assertThat(nonce, is("nonce")); - - request.setParameter("state", "state"); - request.setParameter("nonce", "nonce"); - request.setParameter("code", "abc123"); - - // handle called with request, which should use session - controller.handle(request); - } +// @Test +// public void shouldCheckSessionFallbackWhenHandleCalledWithRequestAndResponse() throws Exception { +// AuthenticationController controller = builderSpy.withResponseType("code").build(); +// +// TokenRequest codeExchangeRequest = mock(TokenRequest.class); +// TokenHolder tokenHolder = mock(TokenHolder.class); +// when(codeExchangeRequest.execute()).thenReturn(tokenHolder); +// when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest); +// +// AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class); +// when(mockBuilder.withResponseType("code")).thenReturn(mockBuilder); +// when(mockBuilder.withScope("openid")).thenReturn(mockBuilder); +// when(client.authorizeUrl("https://redirect.uri/here")).thenReturn(mockBuilder); +// +// MockHttpServletRequest request = new MockHttpServletRequest(); +// MockHttpServletResponse response = new MockHttpServletResponse(); +// +// // build auth URL using deprecated method, which stores state and nonce in session +// String authUrl = controller.buildAuthorizeUrl(request, "https://redirect.uri/here") +// .withState("state") +// .withNonce("nonce") +// .build(); +// +// String state = (String) request.getSession().getAttribute("com.auth0.state"); +// String nonce = (String) request.getSession().getAttribute("com.auth0.nonce"); +// assertThat(state, is("state")); +// assertThat(nonce, is("nonce")); +// +// request.setParameter("state", "state"); +// request.setParameter("nonce", "nonce"); +// request.setParameter("code", "abc123"); +// +// // handle called with request and response, which should use cookies but fallback to session +// controller.handle(request, response); +// } + +// @Test +// public void shouldCheckSessionFallbackWhenHandleCalledWithRequest() throws Exception { +// AuthenticationController controller = builderSpy.withResponseType("code").build(); +// +// TokenRequest codeExchangeRequest = mock(TokenRequest.class); +// TokenHolder tokenHolder = mock(TokenHolder.class); +// when(codeExchangeRequest.execute()).thenReturn(tokenHolder); +// when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest); +// +// AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class); +// when(mockBuilder.withResponseType("code")).thenReturn(mockBuilder); +// when(mockBuilder.withScope("openid")).thenReturn(mockBuilder); +// when(client.authorizeUrl("https://redirect.uri/here")).thenReturn(mockBuilder); +// +// MockHttpServletRequest request = new MockHttpServletRequest(); +// MockHttpServletResponse response = new MockHttpServletResponse(); +// +// // build auth URL using request and response, which stores state and nonce in cookies and also session as a fallback +// String authUrl = controller.buildAuthorizeUrl(request, response,"https://redirect.uri/here") +// .withState("state") +// .withNonce("nonce") +// .build(); +// +// String state = (String) request.getSession().getAttribute("com.auth0.state"); +// String nonce = (String) request.getSession().getAttribute("com.auth0.nonce"); +// assertThat(state, is("state")); +// assertThat(nonce, is("nonce")); +// +// request.setParameter("state", "state"); +// request.setParameter("nonce", "nonce"); +// request.setParameter("code", "abc123"); +// +// // handle called with request, which should use session +// controller.handle(request); +// } @Test public void shouldAllowOrganizationParameter() { diff --git a/src/test/java/com/auth0/AuthorizeUrlTest.java b/src/test/java/com/auth0/AuthorizeUrlTest.java index 5818265..8380c9c 100644 --- a/src/test/java/com/auth0/AuthorizeUrlTest.java +++ b/src/test/java/com/auth0/AuthorizeUrlTest.java @@ -244,67 +244,67 @@ public void shouldThrowWhenChangingTheNonceUsingCustomParameterSetter() { assertEquals("Please, use the dedicated methods for setting the 'nonce' and 'state' parameters.", e.getMessage()); } - @Test - public void shouldGetAuthorizeUrlFromPAR() throws Exception { - AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); - Request requestMock = mock(Request.class); - - when(requestMock.execute()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", 90)); - - authAPIStub.pushedAuthorizationResponseRequest = requestMock; - String url = new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") - .fromPushedAuthorizationRequest(); - - assertThat(url, is("https://domain.com/authorize?client_id=clientId&request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2")); - } - - @Test - public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsNull() throws Exception { - AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); - Request requestMock = mock(Request.class); - when(requestMock.execute()).thenReturn(new PushedAuthorizationResponse(null, 90)); - - authAPIStub.pushedAuthorizationResponseRequest = requestMock; - - InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { - new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") - .fromPushedAuthorizationRequest(); - }); - - assertThat(exception.getMessage(), is("The PAR request returned a missing or empty request_uri value")); - } - - @Test - public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsEmpty() throws Exception { - AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); - Request requestMock = mock(Request.class); - when(requestMock.execute()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", null)); - - authAPIStub.pushedAuthorizationResponseRequest = requestMock; - - InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { - new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") - .fromPushedAuthorizationRequest(); - }); - - assertThat(exception.getMessage(), is("The PAR request returned a missing expires_in value")); - } - - @Test - public void fromPushedAuthorizationRequestThrowsWhenExpiresInIsNull() throws Exception { - AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); - Request requestMock = mock(Request.class); - when(requestMock.execute()).thenReturn(new PushedAuthorizationResponse(null, 90)); - - authAPIStub.pushedAuthorizationResponseRequest = requestMock; - - InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { - new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") - .fromPushedAuthorizationRequest(); - }); - - assertThat(exception.getMessage(), is("The PAR request returned a missing or empty request_uri value")); - } +// @Test +// public void shouldGetAuthorizeUrlFromPAR() throws Exception { +// AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); +// Request requestMock = mock(Request.class); +// +// when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", 90)); +// +// authAPIStub.pushedAuthorizationResponseRequest = requestMock; +// String url = new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") +// .fromPushedAuthorizationRequest(); +// +// assertThat(url, is("https://domain.com/authorize?client_id=clientId&request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2")); +// } + +// @Test +// public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsNull() throws Exception { +// AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); +// Request requestMock = mock(Request.class); +// when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse(null, 90)); +// +// authAPIStub.pushedAuthorizationResponseRequest = requestMock; +// +// InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { +// new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") +// .fromPushedAuthorizationRequest(); +// }); +// +// assertThat(exception.getMessage(), is("The PAR request returned a missing or empty request_uri value")); +// } + +// @Test +// public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsEmpty() throws Exception { +// AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); +// Request requestMock = mock(Request.class); +// when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", null)); +// +// authAPIStub.pushedAuthorizationResponseRequest = requestMock; +// +// InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { +// new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") +// .fromPushedAuthorizationRequest(); +// }); +// +// assertThat(exception.getMessage(), is("The PAR request returned a missing expires_in value")); +// } + +// @Test +// public void fromPushedAuthorizationRequestThrowsWhenExpiresInIsNull() throws Exception { +// AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); +// Request requestMock = mock(Request.class); +// when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse(null, 90)); +// +// authAPIStub.pushedAuthorizationResponseRequest = requestMock; +// +// InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { +// new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") +// .fromPushedAuthorizationRequest(); +// }); +// +// assertThat(exception.getMessage(), is("The PAR request returned a missing or empty request_uri value")); +// } @Test public void fromPushedAuthorizationRequestThrowsWhenRequestThrows() throws Exception { diff --git a/src/test/java/com/auth0/RequestProcessorTest.java b/src/test/java/com/auth0/RequestProcessorTest.java index 7ffcf60..cd44cd0 100644 --- a/src/test/java/com/auth0/RequestProcessorTest.java +++ b/src/test/java/com/auth0/RequestProcessorTest.java @@ -226,242 +226,242 @@ public void shouldThrowOnProcessIfCodeRequestFailsToExecuteCodeExchange() throws assertEquals("An error occurred while exchanging the authorization code.", e.getMessage()); } - @Test - public void shouldThrowOnProcessIfCodeRequestSucceedsButDoesNotPassIdTokenVerification() throws Exception { - doThrow(TokenValidationException.class).when(tokenVerifier).verify(eq("backIdToken"), eq(verifyOptions)); - - Map params = new HashMap<>(); - params.put("code", "abc123"); - params.put("state", "1234"); - MockHttpServletRequest request = getRequest(params); - request.setCookies(new Cookie("com.auth0.state", "1234")); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(tokenHolder.getIdToken()).thenReturn("backIdToken"); - when(codeExchangeRequest.execute()).thenReturn(tokenHolder); - when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); - - RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) - .withIdTokenVerifier(tokenVerifier) - .build(); - IdentityVerificationException e = assertThrows(IdentityVerificationException.class, () -> handler.process(request, response)); - assertThat(e, IdentityVerificationExceptionMatcher.hasCode("a0.invalid_jwt_error")); - assertEquals("An error occurred while trying to verify the ID Token.", e.getMessage()); - - } - - @Test - public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerification() throws Exception { - doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); - - Map params = new HashMap<>(); - params.put("code", "abc123"); - params.put("state", "1234"); - params.put("id_token", "frontIdToken"); - params.put("expires_in", "8400"); - params.put("token_type", "frontTokenType"); - MockHttpServletRequest request = getRequest(params); - request.setCookies(new Cookie("com.auth0.state", "1234")); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(tokenHolder.getIdToken()).thenReturn("backIdToken"); - when(tokenHolder.getExpiresIn()).thenReturn(4800L); - when(tokenHolder.getTokenType()).thenReturn("backTokenType"); - when(codeExchangeRequest.execute()).thenReturn(tokenHolder); - when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); - - RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) - .withIdTokenVerifier(tokenVerifier) - .build(); - Tokens tokens = handler.process(request, response); - - //Should not verify the ID Token twice - verify(tokenVerifier).verify("frontIdToken", verifyOptions); - verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); - verifyNoMoreInteractions(tokenVerifier); - - assertThat(tokens, is(notNullValue())); - assertThat(tokens.getIdToken(), is("frontIdToken")); - assertThat(tokens.getType(), is("frontTokenType")); - assertThat(tokens.getExpiresIn(), is(8400L)); - } - - @Test - public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingSessionStorage() throws Exception { - doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); - - Map params = new HashMap<>(); - params.put("code", "abc123"); - params.put("state", "1234"); - params.put("id_token", "frontIdToken"); - params.put("expires_in", "8400"); - params.put("token_type", "frontTokenType"); - MockHttpServletRequest request = getRequest(params); - request.getSession().setAttribute("com.auth0.state", "1234"); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(tokenHolder.getIdToken()).thenReturn("backIdToken"); - when(tokenHolder.getExpiresIn()).thenReturn(4800L); - when(tokenHolder.getTokenType()).thenReturn("backTokenType"); - when(codeExchangeRequest.execute()).thenReturn(tokenHolder); - when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); - - RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) - .withIdTokenVerifier(tokenVerifier) - .build(); - Tokens tokens = handler.process(request, response); - - //Should not verify the ID Token twice - verify(tokenVerifier).verify("frontIdToken", verifyOptions); - verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); - verifyNoMoreInteractions(tokenVerifier); - - assertThat(tokens, is(notNullValue())); - assertThat(tokens.getIdToken(), is("frontIdToken")); - assertThat(tokens.getType(), is("frontTokenType")); - assertThat(tokens.getExpiresIn(), is(8400L)); - } - - @Test - public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingSessionStorageWithNullSession() throws Exception { - doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); - - Map params = new HashMap<>(); - params.put("code", "abc123"); - params.put("state", "1234"); - params.put("id_token", "frontIdToken"); - params.put("expires_in", "8400"); - params.put("token_type", "frontTokenType"); - MockHttpServletRequest request = getRequest(params); - request.getSession().setAttribute("com.auth0.state", "1234"); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(tokenHolder.getIdToken()).thenReturn("backIdToken"); - when(tokenHolder.getExpiresIn()).thenReturn(4800L); - when(tokenHolder.getTokenType()).thenReturn("backTokenType"); - when(codeExchangeRequest.execute()).thenReturn(tokenHolder); - when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); - - RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) - .withIdTokenVerifier(tokenVerifier) - .build(); - Tokens tokens = handler.process(request, null); - - //Should not verify the ID Token twice - verify(tokenVerifier).verify("frontIdToken", verifyOptions); - verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); - verifyNoMoreInteractions(tokenVerifier); - - assertThat(tokens, is(notNullValue())); - assertThat(tokens.getIdToken(), is("frontIdToken")); - assertThat(tokens.getType(), is("frontTokenType")); - assertThat(tokens.getExpiresIn(), is(8400L)); - } - - @Test - public void shouldReturnTokensOnProcessIfTokenIdTokenCodeRequestPassesIdTokenVerification() throws Exception { - doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); - - Map params = new HashMap<>(); - params.put("code", "abc123"); - params.put("state", "1234"); - params.put("id_token", "frontIdToken"); - params.put("access_token", "frontAccessToken"); - params.put("expires_in", "8400"); - params.put("token_type", "frontTokenType"); - MockHttpServletRequest request = getRequest(params); - request.setCookies(new Cookie("com.auth0.state", "1234")); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(tokenHolder.getIdToken()).thenReturn("backIdToken"); - when(tokenHolder.getAccessToken()).thenReturn("backAccessToken"); - when(tokenHolder.getRefreshToken()).thenReturn("backRefreshToken"); - when(tokenHolder.getExpiresIn()).thenReturn(4800L); - when(tokenHolder.getTokenType()).thenReturn("backTokenType"); - when(codeExchangeRequest.execute()).thenReturn(tokenHolder); - when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); - - RequestProcessor handler = new RequestProcessor.Builder(client, "id_token token code", verifyOptions) - .withIdTokenVerifier(tokenVerifier) - .build(); - Tokens tokens = handler.process(request, response); - - //Should not verify the ID Token twice - verify(tokenVerifier).verify("frontIdToken", verifyOptions); - verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); - verifyNoMoreInteractions(tokenVerifier); - - assertThat(tokens, is(notNullValue())); - assertThat(tokens.getIdToken(), is("frontIdToken")); - assertThat(tokens.getAccessToken(), is("backAccessToken")); - assertThat(tokens.getRefreshToken(), is("backRefreshToken")); - assertThat(tokens.getExpiresIn(), is(4800L)); - assertThat(tokens.getType(), is("backTokenType")); - } - - @Test - public void shouldReturnTokensOnProcessIfCodeRequestPassesIdTokenVerification() throws Exception { - doNothing().when(tokenVerifier).verify(eq("backIdToken"), eq(verifyOptions)); - - Map params = new HashMap<>(); - params.put("code", "abc123"); - params.put("state", "1234"); - MockHttpServletRequest request = getRequest(params); - request.setCookies(new Cookie("com.auth0.state", "1234")); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(tokenHolder.getIdToken()).thenReturn("backIdToken"); - when(tokenHolder.getAccessToken()).thenReturn("backAccessToken"); - when(tokenHolder.getRefreshToken()).thenReturn("backRefreshToken"); - when(codeExchangeRequest.execute()).thenReturn(tokenHolder); - when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); - - RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) - .withIdTokenVerifier(tokenVerifier) - .build(); - Tokens tokens = handler.process(request, response); - - verify(tokenVerifier).verify("backIdToken", verifyOptions); - verifyNoMoreInteractions(tokenVerifier); - - assertThat(tokens, is(notNullValue())); - assertThat(tokens.getIdToken(), is("backIdToken")); - assertThat(tokens.getAccessToken(), is("backAccessToken")); - assertThat(tokens.getRefreshToken(), is("backRefreshToken")); - } - - @Test - public void shouldReturnEmptyTokensWhenCodeRequestReturnsNoTokens() throws Exception { - Map params = new HashMap<>(); - params.put("code", "abc123"); - params.put("state", "1234"); - MockHttpServletRequest request = getRequest(params); - request.setCookies(new Cookie("com.auth0.state", "1234")); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(codeExchangeRequest.execute()).thenReturn(tokenHolder); - when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); - - RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) - .withIdTokenVerifier(tokenVerifier) - .build(); - Tokens tokens = handler.process(request, response); - - verifyNoMoreInteractions(tokenVerifier); - - assertThat(tokens, is(notNullValue())); - - assertThat(tokens.getIdToken(), is(nullValue())); - assertThat(tokens.getAccessToken(), is(nullValue())); - assertThat(tokens.getRefreshToken(), is(nullValue())); - } +// @Test +// public void shouldThrowOnProcessIfCodeRequestSucceedsButDoesNotPassIdTokenVerification() throws Exception { +// doThrow(TokenValidationException.class).when(tokenVerifier).verify(eq("backIdToken"), eq(verifyOptions)); +// +// Map params = new HashMap<>(); +// params.put("code", "abc123"); +// params.put("state", "1234"); +// MockHttpServletRequest request = getRequest(params); +// request.setCookies(new Cookie("com.auth0.state", "1234")); +// +// TokenRequest codeExchangeRequest = mock(TokenRequest.class); +// TokenHolder tokenHolder = mock(TokenHolder.class); +// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); +// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); +// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); +// +// RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) +// .withIdTokenVerifier(tokenVerifier) +// .build(); +// IdentityVerificationException e = assertThrows(IdentityVerificationException.class, () -> handler.process(request, response)); +// assertThat(e, IdentityVerificationExceptionMatcher.hasCode("a0.invalid_jwt_error")); +// assertEquals("An error occurred while trying to verify the ID Token.", e.getMessage()); +// +// } + +// @Test +// public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerification() throws Exception { +// doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); +// +// Map params = new HashMap<>(); +// params.put("code", "abc123"); +// params.put("state", "1234"); +// params.put("id_token", "frontIdToken"); +// params.put("expires_in", "8400"); +// params.put("token_type", "frontTokenType"); +// MockHttpServletRequest request = getRequest(params); +// request.setCookies(new Cookie("com.auth0.state", "1234")); +// +// TokenRequest codeExchangeRequest = mock(TokenRequest.class); +// TokenHolder tokenHolder = mock(TokenHolder.class); +// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); +// when(tokenHolder.getExpiresIn()).thenReturn(4800L); +// when(tokenHolder.getTokenType()).thenReturn("backTokenType"); +// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); +// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); +// +// RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) +// .withIdTokenVerifier(tokenVerifier) +// .build(); +// Tokens tokens = handler.process(request, response); +// +// //Should not verify the ID Token twice +// verify(tokenVerifier).verify("frontIdToken", verifyOptions); +// verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); +// verifyNoMoreInteractions(tokenVerifier); +// +// assertThat(tokens, is(notNullValue())); +// assertThat(tokens.getIdToken(), is("frontIdToken")); +// assertThat(tokens.getType(), is("frontTokenType")); +// assertThat(tokens.getExpiresIn(), is(8400L)); +// } + +// @Test +// public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingSessionStorage() throws Exception { +// doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); +// +// Map params = new HashMap<>(); +// params.put("code", "abc123"); +// params.put("state", "1234"); +// params.put("id_token", "frontIdToken"); +// params.put("expires_in", "8400"); +// params.put("token_type", "frontTokenType"); +// MockHttpServletRequest request = getRequest(params); +// request.getSession().setAttribute("com.auth0.state", "1234"); +// +// TokenRequest codeExchangeRequest = mock(TokenRequest.class); +// TokenHolder tokenHolder = mock(TokenHolder.class); +// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); +// when(tokenHolder.getExpiresIn()).thenReturn(4800L); +// when(tokenHolder.getTokenType()).thenReturn("backTokenType"); +// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); +// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); +// +// RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) +// .withIdTokenVerifier(tokenVerifier) +// .build(); +// Tokens tokens = handler.process(request, response); +// +// //Should not verify the ID Token twice +// verify(tokenVerifier).verify("frontIdToken", verifyOptions); +// verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); +// verifyNoMoreInteractions(tokenVerifier); +// +// assertThat(tokens, is(notNullValue())); +// assertThat(tokens.getIdToken(), is("frontIdToken")); +// assertThat(tokens.getType(), is("frontTokenType")); +// assertThat(tokens.getExpiresIn(), is(8400L)); +// } + +// @Test +// public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingSessionStorageWithNullSession() throws Exception { +// doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); +// +// Map params = new HashMap<>(); +// params.put("code", "abc123"); +// params.put("state", "1234"); +// params.put("id_token", "frontIdToken"); +// params.put("expires_in", "8400"); +// params.put("token_type", "frontTokenType"); +// MockHttpServletRequest request = getRequest(params); +// request.getSession().setAttribute("com.auth0.state", "1234"); +// +// TokenRequest codeExchangeRequest = mock(TokenRequest.class); +// TokenHolder tokenHolder = mock(TokenHolder.class); +// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); +// when(tokenHolder.getExpiresIn()).thenReturn(4800L); +// when(tokenHolder.getTokenType()).thenReturn("backTokenType"); +// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); +// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); +// +// RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) +// .withIdTokenVerifier(tokenVerifier) +// .build(); +// Tokens tokens = handler.process(request, null); +// +// //Should not verify the ID Token twice +// verify(tokenVerifier).verify("frontIdToken", verifyOptions); +// verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); +// verifyNoMoreInteractions(tokenVerifier); +// +// assertThat(tokens, is(notNullValue())); +// assertThat(tokens.getIdToken(), is("frontIdToken")); +// assertThat(tokens.getType(), is("frontTokenType")); +// assertThat(tokens.getExpiresIn(), is(8400L)); +// } + +// @Test +// public void shouldReturnTokensOnProcessIfTokenIdTokenCodeRequestPassesIdTokenVerification() throws Exception { +// doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); +// +// Map params = new HashMap<>(); +// params.put("code", "abc123"); +// params.put("state", "1234"); +// params.put("id_token", "frontIdToken"); +// params.put("access_token", "frontAccessToken"); +// params.put("expires_in", "8400"); +// params.put("token_type", "frontTokenType"); +// MockHttpServletRequest request = getRequest(params); +// request.setCookies(new Cookie("com.auth0.state", "1234")); +// +// TokenRequest codeExchangeRequest = mock(TokenRequest.class); +// TokenHolder tokenHolder = mock(TokenHolder.class); +// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); +// when(tokenHolder.getAccessToken()).thenReturn("backAccessToken"); +// when(tokenHolder.getRefreshToken()).thenReturn("backRefreshToken"); +// when(tokenHolder.getExpiresIn()).thenReturn(4800L); +// when(tokenHolder.getTokenType()).thenReturn("backTokenType"); +// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); +// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); +// +// RequestProcessor handler = new RequestProcessor.Builder(client, "id_token token code", verifyOptions) +// .withIdTokenVerifier(tokenVerifier) +// .build(); +// Tokens tokens = handler.process(request, response); +// +// //Should not verify the ID Token twice +// verify(tokenVerifier).verify("frontIdToken", verifyOptions); +// verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); +// verifyNoMoreInteractions(tokenVerifier); +// +// assertThat(tokens, is(notNullValue())); +// assertThat(tokens.getIdToken(), is("frontIdToken")); +// assertThat(tokens.getAccessToken(), is("backAccessToken")); +// assertThat(tokens.getRefreshToken(), is("backRefreshToken")); +// assertThat(tokens.getExpiresIn(), is(4800L)); +// assertThat(tokens.getType(), is("backTokenType")); +// } + +// @Test +// public void shouldReturnTokensOnProcessIfCodeRequestPassesIdTokenVerification() throws Exception { +// doNothing().when(tokenVerifier).verify(eq("backIdToken"), eq(verifyOptions)); +// +// Map params = new HashMap<>(); +// params.put("code", "abc123"); +// params.put("state", "1234"); +// MockHttpServletRequest request = getRequest(params); +// request.setCookies(new Cookie("com.auth0.state", "1234")); +// +// TokenRequest codeExchangeRequest = mock(TokenRequest.class); +// TokenHolder tokenHolder = mock(TokenHolder.class); +// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); +// when(tokenHolder.getAccessToken()).thenReturn("backAccessToken"); +// when(tokenHolder.getRefreshToken()).thenReturn("backRefreshToken"); +// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); +// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); +// +// RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) +// .withIdTokenVerifier(tokenVerifier) +// .build(); +// Tokens tokens = handler.process(request, response); +// +// verify(tokenVerifier).verify("backIdToken", verifyOptions); +// verifyNoMoreInteractions(tokenVerifier); +// +// assertThat(tokens, is(notNullValue())); +// assertThat(tokens.getIdToken(), is("backIdToken")); +// assertThat(tokens.getAccessToken(), is("backAccessToken")); +// assertThat(tokens.getRefreshToken(), is("backRefreshToken")); +// } + +// @Test +// public void shouldReturnEmptyTokensWhenCodeRequestReturnsNoTokens() throws Exception { +// Map params = new HashMap<>(); +// params.put("code", "abc123"); +// params.put("state", "1234"); +// MockHttpServletRequest request = getRequest(params); +// request.setCookies(new Cookie("com.auth0.state", "1234")); +// +// TokenRequest codeExchangeRequest = mock(TokenRequest.class); +// TokenHolder tokenHolder = mock(TokenHolder.class); +// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); +// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); +// +// RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) +// .withIdTokenVerifier(tokenVerifier) +// .build(); +// Tokens tokens = handler.process(request, response); +// +// verifyNoMoreInteractions(tokenVerifier); +// +// assertThat(tokens, is(notNullValue())); +// +// assertThat(tokens.getIdToken(), is(nullValue())); +// assertThat(tokens.getAccessToken(), is(nullValue())); +// assertThat(tokens.getRefreshToken(), is(nullValue())); +// } @Test public void shouldBuildAuthorizeUrl() { From dc25fc6457354527b9a5c157e681e64209f21440 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Thu, 16 Jan 2025 12:50:33 +0530 Subject: [PATCH 02/13] fixed test cases --- build.gradle | 2 +- .../auth0/AuthenticationControllerTest.java | 24 - src/test/java/com/auth0/AuthorizeUrlTest.java | 136 ++--- .../java/com/auth0/RequestProcessorTest.java | 487 +++++++++--------- 4 files changed, 322 insertions(+), 327 deletions(-) diff --git a/build.gradle b/build.gradle index 4e3ab2e..3e3ebdc 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ oss { repository 'auth0-java-mvc-common' organization 'auth0' description 'Java library that simplifies the use of Auth0 for server-side MVC web apps' - baselineCompareVersion '1.5.0' +// baselineCompareVersion '1.5.0' skipAssertSigningConfiguration true developers { diff --git a/src/test/java/com/auth0/AuthenticationControllerTest.java b/src/test/java/com/auth0/AuthenticationControllerTest.java index 55e7a54..10be941 100644 --- a/src/test/java/com/auth0/AuthenticationControllerTest.java +++ b/src/test/java/com/auth0/AuthenticationControllerTest.java @@ -1,12 +1,7 @@ package com.auth0; -import com.auth0.client.HttpOptions; import com.auth0.client.auth.AuthAPI; -import com.auth0.client.auth.AuthorizeUrlBuilder; -import com.auth0.json.auth.TokenHolder; import com.auth0.jwk.JwkProvider; -import com.auth0.net.Telemetry; -import com.auth0.net.TokenRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -80,25 +75,6 @@ public void setUp() { // // } // -// @Test -// public void shouldCreateAuthAPIClientWithCustomHttpOptions() { -// HttpOptions options = new HttpOptions(); -// options.setConnectTimeout(5); -// options.setReadTimeout(6); -// -// ArgumentCaptor captor = ArgumentCaptor.forClass(HttpOptions.class); -// AuthenticationController.Builder spy = spy(AuthenticationController.newBuilder("domain", "clientId", "clientSecret") -// .withHttpOptions(options)); -// -// spy.build(); -// verify(spy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), captor.capture()); -// -// HttpOptions actual = captor.getValue(); -// assertThat(actual, is(notNullValue())); -// assertThat(actual.getConnectTimeout(), is(5)); -// assertThat(actual.getReadTimeout(), is(6)); -// } - // @Test // public void shouldDisableTelemetry() { // AuthenticationController controller = builderSpy.build(); diff --git a/src/test/java/com/auth0/AuthorizeUrlTest.java b/src/test/java/com/auth0/AuthorizeUrlTest.java index 8380c9c..bbecc56 100644 --- a/src/test/java/com/auth0/AuthorizeUrlTest.java +++ b/src/test/java/com/auth0/AuthorizeUrlTest.java @@ -1,10 +1,10 @@ package com.auth0; -import com.auth0.client.HttpOptions; import com.auth0.client.auth.AuthAPI; import com.auth0.exception.Auth0Exception; import com.auth0.json.auth.PushedAuthorizationResponse; import com.auth0.net.Request; +import com.auth0.net.Response; import okhttp3.HttpUrl; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -244,67 +244,75 @@ public void shouldThrowWhenChangingTheNonceUsingCustomParameterSetter() { assertEquals("Please, use the dedicated methods for setting the 'nonce' and 'state' parameters.", e.getMessage()); } -// @Test -// public void shouldGetAuthorizeUrlFromPAR() throws Exception { -// AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); -// Request requestMock = mock(Request.class); -// -// when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", 90)); -// -// authAPIStub.pushedAuthorizationResponseRequest = requestMock; -// String url = new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") -// .fromPushedAuthorizationRequest(); -// -// assertThat(url, is("https://domain.com/authorize?client_id=clientId&request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2")); -// } - -// @Test -// public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsNull() throws Exception { -// AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); -// Request requestMock = mock(Request.class); -// when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse(null, 90)); -// -// authAPIStub.pushedAuthorizationResponseRequest = requestMock; -// -// InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { -// new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") -// .fromPushedAuthorizationRequest(); -// }); -// -// assertThat(exception.getMessage(), is("The PAR request returned a missing or empty request_uri value")); -// } - -// @Test -// public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsEmpty() throws Exception { -// AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); -// Request requestMock = mock(Request.class); -// when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", null)); -// -// authAPIStub.pushedAuthorizationResponseRequest = requestMock; -// -// InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { -// new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") -// .fromPushedAuthorizationRequest(); -// }); -// -// assertThat(exception.getMessage(), is("The PAR request returned a missing expires_in value")); -// } - -// @Test -// public void fromPushedAuthorizationRequestThrowsWhenExpiresInIsNull() throws Exception { -// AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); -// Request requestMock = mock(Request.class); -// when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse(null, 90)); -// -// authAPIStub.pushedAuthorizationResponseRequest = requestMock; -// -// InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { -// new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") -// .fromPushedAuthorizationRequest(); -// }); -// -// assertThat(exception.getMessage(), is("The PAR request returned a missing or empty request_uri value")); -// } + @Test + public void shouldGetAuthorizeUrlFromPAR() throws Exception { + AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); + Request requestMock = mock(Request.class); + + Response pushedAuthorizationResponseResponse = mock(Response.class); + when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse); + when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", 90)); + + authAPIStub.pushedAuthorizationResponseRequest = requestMock; + String url = new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") + .fromPushedAuthorizationRequest(); + + assertThat(url, is("https://domain.com/authorize?client_id=clientId&request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2")); + } + + @Test + public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsNull() throws Exception { + AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); + Request requestMock = mock(Request.class); + Response pushedAuthorizationResponseResponse = mock(Response.class); + when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse); + when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse(null, 90)); + + authAPIStub.pushedAuthorizationResponseRequest = requestMock; + + InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { + new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") + .fromPushedAuthorizationRequest(); + }); + + assertThat(exception.getMessage(), is("The PAR request returned a missing or empty request_uri value")); + } + + @Test + public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsEmpty() throws Exception { + AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); + Request requestMock = mock(Request.class); + Response pushedAuthorizationResponseResponse = mock(Response.class); + when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse); + when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", null)); + + authAPIStub.pushedAuthorizationResponseRequest = requestMock; + + InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { + new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") + .fromPushedAuthorizationRequest(); + }); + + assertThat(exception.getMessage(), is("The PAR request returned a missing expires_in value")); + } + + @Test + public void fromPushedAuthorizationRequestThrowsWhenExpiresInIsNull() throws Exception { + AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); + Request requestMock = mock(Request.class); + Response pushedAuthorizationResponseResponse = mock(Response.class); + when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse); + when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse(null, 90)); + + authAPIStub.pushedAuthorizationResponseRequest = requestMock; + + InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { + new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") + .fromPushedAuthorizationRequest(); + }); + + assertThat(exception.getMessage(), is("The PAR request returned a missing or empty request_uri value")); + } @Test public void fromPushedAuthorizationRequestThrowsWhenRequestThrows() throws Exception { @@ -329,10 +337,6 @@ static class AuthAPIStub extends AuthAPI { Request pushedAuthorizationResponseRequest; - public AuthAPIStub(String domain, String clientId, String clientSecret, HttpOptions options) { - super(domain, clientId, clientSecret, options); - } - public AuthAPIStub(String domain, String clientId, String clientSecret) { super(domain, clientId, clientSecret); } diff --git a/src/test/java/com/auth0/RequestProcessorTest.java b/src/test/java/com/auth0/RequestProcessorTest.java index cd44cd0..281ff17 100644 --- a/src/test/java/com/auth0/RequestProcessorTest.java +++ b/src/test/java/com/auth0/RequestProcessorTest.java @@ -3,6 +3,7 @@ import com.auth0.client.auth.AuthAPI; import com.auth0.exception.Auth0Exception; import com.auth0.json.auth.TokenHolder; +import com.auth0.net.Response; import com.auth0.net.TokenRequest; import org.hamcrest.CoreMatchers; import org.junit.jupiter.api.BeforeEach; @@ -226,242 +227,256 @@ public void shouldThrowOnProcessIfCodeRequestFailsToExecuteCodeExchange() throws assertEquals("An error occurred while exchanging the authorization code.", e.getMessage()); } -// @Test -// public void shouldThrowOnProcessIfCodeRequestSucceedsButDoesNotPassIdTokenVerification() throws Exception { -// doThrow(TokenValidationException.class).when(tokenVerifier).verify(eq("backIdToken"), eq(verifyOptions)); -// -// Map params = new HashMap<>(); -// params.put("code", "abc123"); -// params.put("state", "1234"); -// MockHttpServletRequest request = getRequest(params); -// request.setCookies(new Cookie("com.auth0.state", "1234")); -// -// TokenRequest codeExchangeRequest = mock(TokenRequest.class); -// TokenHolder tokenHolder = mock(TokenHolder.class); -// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); -// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); -// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); -// -// RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) -// .withIdTokenVerifier(tokenVerifier) -// .build(); -// IdentityVerificationException e = assertThrows(IdentityVerificationException.class, () -> handler.process(request, response)); -// assertThat(e, IdentityVerificationExceptionMatcher.hasCode("a0.invalid_jwt_error")); -// assertEquals("An error occurred while trying to verify the ID Token.", e.getMessage()); -// -// } - -// @Test -// public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerification() throws Exception { -// doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); -// -// Map params = new HashMap<>(); -// params.put("code", "abc123"); -// params.put("state", "1234"); -// params.put("id_token", "frontIdToken"); -// params.put("expires_in", "8400"); -// params.put("token_type", "frontTokenType"); -// MockHttpServletRequest request = getRequest(params); -// request.setCookies(new Cookie("com.auth0.state", "1234")); -// -// TokenRequest codeExchangeRequest = mock(TokenRequest.class); -// TokenHolder tokenHolder = mock(TokenHolder.class); -// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); -// when(tokenHolder.getExpiresIn()).thenReturn(4800L); -// when(tokenHolder.getTokenType()).thenReturn("backTokenType"); -// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); -// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); -// -// RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) -// .withIdTokenVerifier(tokenVerifier) -// .build(); -// Tokens tokens = handler.process(request, response); -// -// //Should not verify the ID Token twice -// verify(tokenVerifier).verify("frontIdToken", verifyOptions); -// verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); -// verifyNoMoreInteractions(tokenVerifier); -// -// assertThat(tokens, is(notNullValue())); -// assertThat(tokens.getIdToken(), is("frontIdToken")); -// assertThat(tokens.getType(), is("frontTokenType")); -// assertThat(tokens.getExpiresIn(), is(8400L)); -// } - -// @Test -// public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingSessionStorage() throws Exception { -// doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); -// -// Map params = new HashMap<>(); -// params.put("code", "abc123"); -// params.put("state", "1234"); -// params.put("id_token", "frontIdToken"); -// params.put("expires_in", "8400"); -// params.put("token_type", "frontTokenType"); -// MockHttpServletRequest request = getRequest(params); -// request.getSession().setAttribute("com.auth0.state", "1234"); -// -// TokenRequest codeExchangeRequest = mock(TokenRequest.class); -// TokenHolder tokenHolder = mock(TokenHolder.class); -// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); -// when(tokenHolder.getExpiresIn()).thenReturn(4800L); -// when(tokenHolder.getTokenType()).thenReturn("backTokenType"); -// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); -// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); -// -// RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) -// .withIdTokenVerifier(tokenVerifier) -// .build(); -// Tokens tokens = handler.process(request, response); -// -// //Should not verify the ID Token twice -// verify(tokenVerifier).verify("frontIdToken", verifyOptions); -// verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); -// verifyNoMoreInteractions(tokenVerifier); -// -// assertThat(tokens, is(notNullValue())); -// assertThat(tokens.getIdToken(), is("frontIdToken")); -// assertThat(tokens.getType(), is("frontTokenType")); -// assertThat(tokens.getExpiresIn(), is(8400L)); -// } - -// @Test -// public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingSessionStorageWithNullSession() throws Exception { -// doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); -// -// Map params = new HashMap<>(); -// params.put("code", "abc123"); -// params.put("state", "1234"); -// params.put("id_token", "frontIdToken"); -// params.put("expires_in", "8400"); -// params.put("token_type", "frontTokenType"); -// MockHttpServletRequest request = getRequest(params); -// request.getSession().setAttribute("com.auth0.state", "1234"); -// -// TokenRequest codeExchangeRequest = mock(TokenRequest.class); -// TokenHolder tokenHolder = mock(TokenHolder.class); -// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); -// when(tokenHolder.getExpiresIn()).thenReturn(4800L); -// when(tokenHolder.getTokenType()).thenReturn("backTokenType"); -// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); -// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); -// -// RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) -// .withIdTokenVerifier(tokenVerifier) -// .build(); -// Tokens tokens = handler.process(request, null); -// -// //Should not verify the ID Token twice -// verify(tokenVerifier).verify("frontIdToken", verifyOptions); -// verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); -// verifyNoMoreInteractions(tokenVerifier); -// -// assertThat(tokens, is(notNullValue())); -// assertThat(tokens.getIdToken(), is("frontIdToken")); -// assertThat(tokens.getType(), is("frontTokenType")); -// assertThat(tokens.getExpiresIn(), is(8400L)); -// } - -// @Test -// public void shouldReturnTokensOnProcessIfTokenIdTokenCodeRequestPassesIdTokenVerification() throws Exception { -// doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); -// -// Map params = new HashMap<>(); -// params.put("code", "abc123"); -// params.put("state", "1234"); -// params.put("id_token", "frontIdToken"); -// params.put("access_token", "frontAccessToken"); -// params.put("expires_in", "8400"); -// params.put("token_type", "frontTokenType"); -// MockHttpServletRequest request = getRequest(params); -// request.setCookies(new Cookie("com.auth0.state", "1234")); -// -// TokenRequest codeExchangeRequest = mock(TokenRequest.class); -// TokenHolder tokenHolder = mock(TokenHolder.class); -// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); -// when(tokenHolder.getAccessToken()).thenReturn("backAccessToken"); -// when(tokenHolder.getRefreshToken()).thenReturn("backRefreshToken"); -// when(tokenHolder.getExpiresIn()).thenReturn(4800L); -// when(tokenHolder.getTokenType()).thenReturn("backTokenType"); -// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); -// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); -// -// RequestProcessor handler = new RequestProcessor.Builder(client, "id_token token code", verifyOptions) -// .withIdTokenVerifier(tokenVerifier) -// .build(); -// Tokens tokens = handler.process(request, response); -// -// //Should not verify the ID Token twice -// verify(tokenVerifier).verify("frontIdToken", verifyOptions); -// verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); -// verifyNoMoreInteractions(tokenVerifier); -// -// assertThat(tokens, is(notNullValue())); -// assertThat(tokens.getIdToken(), is("frontIdToken")); -// assertThat(tokens.getAccessToken(), is("backAccessToken")); -// assertThat(tokens.getRefreshToken(), is("backRefreshToken")); -// assertThat(tokens.getExpiresIn(), is(4800L)); -// assertThat(tokens.getType(), is("backTokenType")); -// } - -// @Test -// public void shouldReturnTokensOnProcessIfCodeRequestPassesIdTokenVerification() throws Exception { -// doNothing().when(tokenVerifier).verify(eq("backIdToken"), eq(verifyOptions)); -// -// Map params = new HashMap<>(); -// params.put("code", "abc123"); -// params.put("state", "1234"); -// MockHttpServletRequest request = getRequest(params); -// request.setCookies(new Cookie("com.auth0.state", "1234")); -// -// TokenRequest codeExchangeRequest = mock(TokenRequest.class); -// TokenHolder tokenHolder = mock(TokenHolder.class); -// when(tokenHolder.getIdToken()).thenReturn("backIdToken"); -// when(tokenHolder.getAccessToken()).thenReturn("backAccessToken"); -// when(tokenHolder.getRefreshToken()).thenReturn("backRefreshToken"); -// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); -// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); -// -// RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) -// .withIdTokenVerifier(tokenVerifier) -// .build(); -// Tokens tokens = handler.process(request, response); -// -// verify(tokenVerifier).verify("backIdToken", verifyOptions); -// verifyNoMoreInteractions(tokenVerifier); -// -// assertThat(tokens, is(notNullValue())); -// assertThat(tokens.getIdToken(), is("backIdToken")); -// assertThat(tokens.getAccessToken(), is("backAccessToken")); -// assertThat(tokens.getRefreshToken(), is("backRefreshToken")); -// } - -// @Test -// public void shouldReturnEmptyTokensWhenCodeRequestReturnsNoTokens() throws Exception { -// Map params = new HashMap<>(); -// params.put("code", "abc123"); -// params.put("state", "1234"); -// MockHttpServletRequest request = getRequest(params); -// request.setCookies(new Cookie("com.auth0.state", "1234")); -// -// TokenRequest codeExchangeRequest = mock(TokenRequest.class); -// TokenHolder tokenHolder = mock(TokenHolder.class); -// when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); -// when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); -// -// RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) -// .withIdTokenVerifier(tokenVerifier) -// .build(); -// Tokens tokens = handler.process(request, response); -// -// verifyNoMoreInteractions(tokenVerifier); -// -// assertThat(tokens, is(notNullValue())); -// -// assertThat(tokens.getIdToken(), is(nullValue())); -// assertThat(tokens.getAccessToken(), is(nullValue())); -// assertThat(tokens.getRefreshToken(), is(nullValue())); -// } + @Test + public void shouldThrowOnProcessIfCodeRequestSucceedsButDoesNotPassIdTokenVerification() throws Exception { + doThrow(TokenValidationException.class).when(tokenVerifier).verify(eq("backIdToken"), eq(verifyOptions)); + + Map params = new HashMap<>(); + params.put("code", "abc123"); + params.put("state", "1234"); + MockHttpServletRequest request = getRequest(params); + request.setCookies(new Cookie("com.auth0.state", "1234")); + + TokenRequest codeExchangeRequest = mock(TokenRequest.class); + Response tokenResponse = mock(Response.class); + TokenHolder tokenHolder = mock(TokenHolder.class); + when(tokenHolder.getIdToken()).thenReturn("backIdToken"); + when(codeExchangeRequest.execute()).thenReturn(tokenResponse); + when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); + when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); + + RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) + .withIdTokenVerifier(tokenVerifier) + .build(); + IdentityVerificationException e = assertThrows(IdentityVerificationException.class, () -> handler.process(request, response)); + assertThat(e, IdentityVerificationExceptionMatcher.hasCode("a0.invalid_jwt_error")); + assertEquals("An error occurred while trying to verify the ID Token.", e.getMessage()); + + } + + @Test + public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerification() throws Exception { + doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); + + Map params = new HashMap<>(); + params.put("code", "abc123"); + params.put("state", "1234"); + params.put("id_token", "frontIdToken"); + params.put("expires_in", "8400"); + params.put("token_type", "frontTokenType"); + MockHttpServletRequest request = getRequest(params); + request.setCookies(new Cookie("com.auth0.state", "1234")); + + TokenRequest codeExchangeRequest = mock(TokenRequest.class); + TokenHolder tokenHolder = mock(TokenHolder.class); + Response tokenResponse = mock(Response.class); + when(tokenHolder.getIdToken()).thenReturn("backIdToken"); + when(tokenHolder.getExpiresIn()).thenReturn(4800L); + when(tokenHolder.getTokenType()).thenReturn("backTokenType"); + when(codeExchangeRequest.execute()).thenReturn(tokenResponse); + when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); + when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); + + RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) + .withIdTokenVerifier(tokenVerifier) + .build(); + Tokens tokens = handler.process(request, response); + + //Should not verify the ID Token twice + verify(tokenVerifier).verify("frontIdToken", verifyOptions); + verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); + verifyNoMoreInteractions(tokenVerifier); + + assertThat(tokens, is(notNullValue())); + assertThat(tokens.getIdToken(), is("frontIdToken")); + assertThat(tokens.getType(), is("frontTokenType")); + assertThat(tokens.getExpiresIn(), is(8400L)); + } + + @Test + public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingSessionStorage() throws Exception { + doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); + + Map params = new HashMap<>(); + params.put("code", "abc123"); + params.put("state", "1234"); + params.put("id_token", "frontIdToken"); + params.put("expires_in", "8400"); + params.put("token_type", "frontTokenType"); + MockHttpServletRequest request = getRequest(params); + request.getSession().setAttribute("com.auth0.state", "1234"); + + TokenRequest codeExchangeRequest = mock(TokenRequest.class); + TokenHolder tokenHolder = mock(TokenHolder.class); + Response tokenResponse = mock(Response.class); + when(tokenHolder.getIdToken()).thenReturn("backIdToken"); + when(tokenHolder.getExpiresIn()).thenReturn(4800L); + when(tokenHolder.getTokenType()).thenReturn("backTokenType"); + when(codeExchangeRequest.execute()).thenReturn(tokenResponse); + when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); + when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); + + RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) + .withIdTokenVerifier(tokenVerifier) + .build(); + Tokens tokens = handler.process(request, response); + + //Should not verify the ID Token twice + verify(tokenVerifier).verify("frontIdToken", verifyOptions); + verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); + verifyNoMoreInteractions(tokenVerifier); + + assertThat(tokens, is(notNullValue())); + assertThat(tokens.getIdToken(), is("frontIdToken")); + assertThat(tokens.getType(), is("frontTokenType")); + assertThat(tokens.getExpiresIn(), is(8400L)); + } + + @Test + public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingSessionStorageWithNullSession() throws Exception { + doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); + + Map params = new HashMap<>(); + params.put("code", "abc123"); + params.put("state", "1234"); + params.put("id_token", "frontIdToken"); + params.put("expires_in", "8400"); + params.put("token_type", "frontTokenType"); + MockHttpServletRequest request = getRequest(params); + request.getSession().setAttribute("com.auth0.state", "1234"); + + TokenRequest codeExchangeRequest = mock(TokenRequest.class); + TokenHolder tokenHolder = mock(TokenHolder.class); + Response tokenResponse = mock(Response.class); + when(tokenHolder.getIdToken()).thenReturn("backIdToken"); + when(tokenHolder.getExpiresIn()).thenReturn(4800L); + when(tokenHolder.getTokenType()).thenReturn("backTokenType"); + when(codeExchangeRequest.execute()).thenReturn(tokenResponse); + when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); + when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); + + RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) + .withIdTokenVerifier(tokenVerifier) + .build(); + Tokens tokens = handler.process(request, null); + + //Should not verify the ID Token twice + verify(tokenVerifier).verify("frontIdToken", verifyOptions); + verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); + verifyNoMoreInteractions(tokenVerifier); + + assertThat(tokens, is(notNullValue())); + assertThat(tokens.getIdToken(), is("frontIdToken")); + assertThat(tokens.getType(), is("frontTokenType")); + assertThat(tokens.getExpiresIn(), is(8400L)); + } + + @Test + public void shouldReturnTokensOnProcessIfTokenIdTokenCodeRequestPassesIdTokenVerification() throws Exception { + doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); + + Map params = new HashMap<>(); + params.put("code", "abc123"); + params.put("state", "1234"); + params.put("id_token", "frontIdToken"); + params.put("access_token", "frontAccessToken"); + params.put("expires_in", "8400"); + params.put("token_type", "frontTokenType"); + MockHttpServletRequest request = getRequest(params); + request.setCookies(new Cookie("com.auth0.state", "1234")); + + TokenRequest codeExchangeRequest = mock(TokenRequest.class); + TokenHolder tokenHolder = mock(TokenHolder.class); + Response tokenResponse = mock(Response.class); + when(tokenHolder.getIdToken()).thenReturn("backIdToken"); + when(tokenHolder.getAccessToken()).thenReturn("backAccessToken"); + when(tokenHolder.getRefreshToken()).thenReturn("backRefreshToken"); + when(tokenHolder.getExpiresIn()).thenReturn(4800L); + when(tokenHolder.getTokenType()).thenReturn("backTokenType"); + when(codeExchangeRequest.execute()).thenReturn(tokenResponse); + when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); + when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); + + RequestProcessor handler = new RequestProcessor.Builder(client, "id_token token code", verifyOptions) + .withIdTokenVerifier(tokenVerifier) + .build(); + Tokens tokens = handler.process(request, response); + + //Should not verify the ID Token twice + verify(tokenVerifier).verify("frontIdToken", verifyOptions); + verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); + verifyNoMoreInteractions(tokenVerifier); + + assertThat(tokens, is(notNullValue())); + assertThat(tokens.getIdToken(), is("frontIdToken")); + assertThat(tokens.getAccessToken(), is("backAccessToken")); + assertThat(tokens.getRefreshToken(), is("backRefreshToken")); + assertThat(tokens.getExpiresIn(), is(4800L)); + assertThat(tokens.getType(), is("backTokenType")); + } + + @Test + public void shouldReturnTokensOnProcessIfCodeRequestPassesIdTokenVerification() throws Exception { + doNothing().when(tokenVerifier).verify(eq("backIdToken"), eq(verifyOptions)); + + Map params = new HashMap<>(); + params.put("code", "abc123"); + params.put("state", "1234"); + MockHttpServletRequest request = getRequest(params); + request.setCookies(new Cookie("com.auth0.state", "1234")); + + TokenRequest codeExchangeRequest = mock(TokenRequest.class); + TokenHolder tokenHolder = mock(TokenHolder.class); + Response tokenResponse = mock(Response.class); + when(tokenHolder.getIdToken()).thenReturn("backIdToken"); + when(tokenHolder.getAccessToken()).thenReturn("backAccessToken"); + when(tokenHolder.getRefreshToken()).thenReturn("backRefreshToken"); + when(codeExchangeRequest.execute()).thenReturn(tokenResponse); + when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); + when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); + + RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) + .withIdTokenVerifier(tokenVerifier) + .build(); + Tokens tokens = handler.process(request, response); + + verify(tokenVerifier).verify("backIdToken", verifyOptions); + verifyNoMoreInteractions(tokenVerifier); + + assertThat(tokens, is(notNullValue())); + assertThat(tokens.getIdToken(), is("backIdToken")); + assertThat(tokens.getAccessToken(), is("backAccessToken")); + assertThat(tokens.getRefreshToken(), is("backRefreshToken")); + } + + @Test + public void shouldReturnEmptyTokensWhenCodeRequestReturnsNoTokens() throws Exception { + Map params = new HashMap<>(); + params.put("code", "abc123"); + params.put("state", "1234"); + MockHttpServletRequest request = getRequest(params); + request.setCookies(new Cookie("com.auth0.state", "1234")); + + TokenRequest codeExchangeRequest = mock(TokenRequest.class); + TokenHolder tokenHolder = mock(TokenHolder.class); + Response tokenResponse = mock(Response.class); + when(codeExchangeRequest.execute()).thenReturn(tokenResponse); + when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); + when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); + + RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) + .withIdTokenVerifier(tokenVerifier) + .build(); + Tokens tokens = handler.process(request, response); + + verifyNoMoreInteractions(tokenVerifier); + + assertThat(tokens, is(notNullValue())); + + assertThat(tokens.getIdToken(), is(nullValue())); + assertThat(tokens.getAccessToken(), is(nullValue())); + assertThat(tokens.getRefreshToken(), is(nullValue())); + } @Test public void shouldBuildAuthorizeUrl() { From 61d5087fbdfb728bc4c1673b71ca63f7ea68a7fa Mon Sep 17 00:00:00 2001 From: tanya732 Date: Thu, 30 Jan 2025 15:33:37 +0530 Subject: [PATCH 03/13] commented app diff task --- build.gradle | 60 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/build.gradle b/build.gradle index 47632fa..5791291 100644 --- a/build.gradle +++ b/build.gradle @@ -47,40 +47,40 @@ project.afterEvaluate { } } - project.configure(project) { - def baselineVersion = project.ext.baselineCompareVersion - task('apiDiff', type: JapicmpTask, dependsOn: 'jar') { - oldClasspath.from(files(getBaselineJar(project, baselineVersion))) - newClasspath.from(files(jar.archiveFile)) - onlyModified = true - failOnModification = true - ignoreMissingClasses = true - htmlOutputFile = file("$buildDir/reports/apiDiff/apiDiff.html") - txtOutputFile = file("$buildDir/reports/apiDiff/apiDiff.txt") - doLast { - project.logger.quiet("Comparing against baseline version ${baselineVersion}") - } - } - } +// project.configure(project) { +// def baselineVersion = project.ext.baselineCompareVersion +// task('apiDiff', type: JapicmpTask, dependsOn: 'jar') { +// oldClasspath.from(files(getBaselineJar(project, baselineVersion))) +// newClasspath.from(files(jar.archiveFile)) +// onlyModified = true +// failOnModification = true +// ignoreMissingClasses = true +// htmlOutputFile = file("$buildDir/reports/apiDiff/apiDiff.html") +// txtOutputFile = file("$buildDir/reports/apiDiff/apiDiff.txt") +// doLast { +// project.logger.quiet("Comparing against baseline version ${baselineVersion}") +// } +// } +// } } -private static File getBaselineJar(Project project, String baselineVersion) { - // Use detached configuration: https://github.com/square/okhttp/blob/master/build.gradle#L270 - def group = project.group - try { - def baseline = "${project.group}:${project.name}:$baselineVersion" - project.group = 'virtual_group_for_japicmp' - def dependency = project.dependencies.create(baseline + "@jar") - return project.configurations.detachedConfiguration(dependency).files.find { - it.name == "${project.name}-${baselineVersion}.jar" - } - } finally { - project.group = group - } -} +//private static File getBaselineJar(Project project, String baselineVersion) { +// // Use detached configuration: https://github.com/square/okhttp/blob/master/build.gradle#L270 +// def group = project.group +// try { +// def baseline = "${project.group}:${project.name}:$baselineVersion" +// project.group = 'virtual_group_for_japicmp' +// def dependency = project.dependencies.create(baseline + "@jar") +// return project.configurations.detachedConfiguration(dependency).files.find { +// it.name == "${project.name}-${baselineVersion}.jar" +// } +// } finally { +// project.group = group +// } +//} ext { - baselineCompareVersion = '1.5.0' + //baselineCompareVersion = '1.5.0' testInJavaVersions = [8, 11, 17, 21] } From 7aefa90024040452bbfd3dc0733fe8b1d9119b56 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Thu, 30 Jan 2025 15:37:43 +0530 Subject: [PATCH 04/13] temporarily removed api diff task --- .github/workflows/build-and-test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 25155e8..5d43230 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -17,7 +17,8 @@ jobs: java-version: 8 - uses: gradle/gradle-build-action@a4cf152f482c7ca97ef56ead29bf08bcd953284c with: - arguments: assemble apiDiff check jacocoTestReport --continue --console=plain +# arguments: assemble apiDiff check jacocoTestReport --continue --console=plain + arguments: assemble check jacocoTestReport --continue --console=plain - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d with: flags: unittests From dc086da2e200922774ab286e6cfcc949c7762a50 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Fri, 31 Jan 2025 15:00:18 +0530 Subject: [PATCH 05/13] upgraded java-jwt plugin --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5791291..8d8b25f 100644 --- a/build.gradle +++ b/build.gradle @@ -126,7 +126,7 @@ dependencies { implementation 'commons-codec:commons-codec:1.15' api 'com.auth0:auth0:1.45.1' - api 'com.auth0:java-jwt:3.19.4' + api 'com.auth0:java-jwt:4.5.0' api 'com.auth0:jwks-rsa:0.22.1' testImplementation 'org.bouncycastle:bcprov-jdk15on:1.64' From 2ee0da88c9d41e1f24f297d3c58d5a87b4569d4c Mon Sep 17 00:00:00 2001 From: tanya732 Date: Fri, 28 Feb 2025 07:44:35 +0530 Subject: [PATCH 06/13] updated the artifact version to v4 --- .github/workflows/build-and-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 5d43230..b480018 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -22,7 +22,7 @@ jobs: - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d with: flags: unittests - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: Reports path: lib/build/reports From d5aef0918d6d8e6123feead6755d6f849f288a08 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Fri, 21 Mar 2025 09:21:32 +0530 Subject: [PATCH 07/13] upgraded other dependencies --- build.gradle | 15 +++++++------- .../java/com/auth0/SignatureVerifierTest.java | 20 +++++++++++++------ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/build.gradle b/build.gradle index 8d8b25f..c19ad8d 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { dependencies { // https://github.com/melix/japicmp-gradle-plugin/issues/36 - classpath 'com.google.guava:guava:31.1-jre' + classpath 'com.google.guava:guava:32.0.1-jre' } } @@ -121,21 +121,20 @@ test { dependencies { implementation 'javax.servlet:javax.servlet-api:3.1.0' - implementation 'org.apache.commons:commons-lang3:3.12.0' - implementation 'com.google.guava:guava-annotations:r03' + implementation 'org.apache.commons:commons-lang3:3.13.0' + implementation 'com.google.guava:guava:32.0.1-jre' implementation 'commons-codec:commons-codec:1.15' api 'com.auth0:auth0:1.45.1' api 'com.auth0:java-jwt:4.5.0' api 'com.auth0:jwks-rsa:0.22.1' - testImplementation 'org.bouncycastle:bcprov-jdk15on:1.64' - testImplementation 'org.hamcrest:java-hamcrest:2.0.0.0' - testImplementation 'org.hamcrest:hamcrest-core:1.3' - testImplementation 'org.mockito:mockito-core:2.8.9' + testImplementation 'org.hamcrest:hamcrest:2.2' + testImplementation 'org.mockito:mockito-core:4.8.1' testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1' testImplementation 'org.springframework:spring-test:4.3.14.RELEASE' - testImplementation 'com.squareup.okhttp3:okhttp:4.11.0' + testImplementation 'com.squareup.okhttp3:okhttp:4.12.0' + testImplementation "com.squareup.okio:okio:3.5.0" } apply from: rootProject.file('gradle/maven-publish.gradle') diff --git a/src/test/java/com/auth0/SignatureVerifierTest.java b/src/test/java/com/auth0/SignatureVerifierTest.java index 326387f..b0b6678 100644 --- a/src/test/java/com/auth0/SignatureVerifierTest.java +++ b/src/test/java/com/auth0/SignatureVerifierTest.java @@ -4,9 +4,9 @@ import com.auth0.jwk.JwkException; import com.auth0.jwk.JwkProvider; import com.auth0.jwt.interfaces.DecodedJWT; -import org.bouncycastle.util.io.pem.PemReader; import org.junit.jupiter.api.Test; +import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; @@ -18,6 +18,7 @@ import java.security.interfaces.RSAPublicKey; import java.security.spec.EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; import java.util.Scanner; import static org.hamcrest.CoreMatchers.notNullValue; @@ -146,7 +147,7 @@ private JwkProvider getRSProvider(String rsaPath) throws Exception { private static RSAPublicKey readPublicKeyFromFile(final String path) throws IOException { Scanner scanner = null; - PemReader pemReader = null; + BufferedReader reader = null; try { scanner = new Scanner(Paths.get(path)); if (scanner.hasNextLine() && scanner.nextLine().startsWith("-----BEGIN CERTIFICATE-----")) { @@ -157,8 +158,15 @@ private static RSAPublicKey readPublicKeyFromFile(final String path) throws IOEx fs.close(); return (RSAPublicKey) key; } else { - pemReader = new PemReader(new FileReader(path)); - byte[] keyBytes = pemReader.readPemObject().getContent(); + reader = new BufferedReader(new FileReader(path)); + StringBuilder pemContent = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + if (!line.startsWith("-----BEGIN") && !line.startsWith("-----END")) { + pemContent.append(line); + } + } + byte[] keyBytes = Base64.getDecoder().decode(pemContent.toString()); KeyFactory kf = KeyFactory.getInstance("RSA"); EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); return (RSAPublicKey) kf.generatePublic(keySpec); @@ -169,8 +177,8 @@ private static RSAPublicKey readPublicKeyFromFile(final String path) throws IOEx if (scanner != null) { scanner.close(); } - if (pemReader != null) { - pemReader.close(); + if (reader != null) { + reader.close(); } } } From d8dd0656eb1fa892c2f251331a760cbdcab697a5 Mon Sep 17 00:00:00 2001 From: Tareq Kirresh Date: Fri, 16 May 2025 21:36:13 +0300 Subject: [PATCH 08/13] Updated to JDK 21, gradle 8, fixed tests --- build.gradle | 36 ++++++++----------- gradle/maven-publish.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../com/auth0/AuthenticationController.java | 8 ++--- src/main/java/com/auth0/AuthorizeUrl.java | 6 ++-- src/main/java/com/auth0/RandomStorage.java | 4 +-- src/main/java/com/auth0/RequestProcessor.java | 4 +-- src/main/java/com/auth0/SessionUtils.java | 4 +-- .../java/com/auth0/TransientCookieStore.java | 6 ++-- .../auth0/AuthenticationControllerTest.java | 24 ++++++------- src/test/java/com/auth0/AuthorizeUrlTest.java | 23 ++++++------ .../java/com/auth0/RequestProcessorTest.java | 4 +-- .../com/auth0/TransientCookieStoreTest.java | 31 ++++++++-------- 13 files changed, 73 insertions(+), 81 deletions(-) diff --git a/build.gradle b/build.gradle index 47632fa..0a46a0c 100644 --- a/build.gradle +++ b/build.gradle @@ -84,31 +84,22 @@ ext { testInJavaVersions = [8, 11, 17, 21] } +jacoco { + toolVersion = "0.8.13" +} + + jacocoTestReport { reports { - xml.enabled = true - html.enabled = true + xml.required = true + html.required = true } } -java { - toolchain { - languageVersion = JavaLanguageVersion.of(8) - } - // Needed because of broken gradle metadata, see https://github.com/google/guava/issues/6612#issuecomment-1614992368 - sourceSets.all { - configurations.getByName(runtimeClasspathConfigurationName) { - attributes.attribute(Attribute.of("org.gradle.jvm.environment", String), "standard-jvm") - } - configurations.getByName(compileClasspathConfigurationName) { - attributes.attribute(Attribute.of("org.gradle.jvm.environment", String), "standard-jvm") - } - } -} -compileJava { - sourceCompatibility '1.8' - targetCompatibility '1.8' +java { + sourceCompatibility '21' + targetCompatibility '21' } test { @@ -120,7 +111,7 @@ test { } dependencies { - implementation 'javax.servlet:javax.servlet-api:3.1.0' + implementation 'jakarta.servlet:jakarta.servlet-api:6.0.0' implementation 'org.apache.commons:commons-lang3:3.12.0' implementation 'com.google.guava:guava-annotations:r03' implementation 'commons-codec:commons-codec:1.15' @@ -132,9 +123,10 @@ dependencies { testImplementation 'org.bouncycastle:bcprov-jdk15on:1.64' testImplementation 'org.hamcrest:java-hamcrest:2.0.0.0' testImplementation 'org.hamcrest:hamcrest-core:1.3' - testImplementation 'org.mockito:mockito-core:2.8.9' + testImplementation 'org.mockito:mockito-core:4.11.0' testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1' - testImplementation 'org.springframework:spring-test:4.3.14.RELEASE' + testImplementation 'org.springframework:spring-test:6.0.14' + testImplementation 'org.springframework:spring-web:6.0.14' testImplementation 'com.squareup.okhttp3:okhttp:4.11.0' } diff --git a/gradle/maven-publish.gradle b/gradle/maven-publish.gradle index 206a581..e882793 100644 --- a/gradle/maven-publish.gradle +++ b/gradle/maven-publish.gradle @@ -13,7 +13,7 @@ task('javadocJar', type: Jar, dependsOn: javadoc) { tasks.withType(Javadoc).configureEach { javadocTool = javaToolchains.javadocToolFor { // Use latest JDK for javadoc generation - languageVersion = JavaLanguageVersion.of(17) + languageVersion = JavaLanguageVersion.of(21) } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6499169..e1adfb4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/auth0/AuthenticationController.java b/src/main/java/com/auth0/AuthenticationController.java index 1aed380..4dc825f 100644 --- a/src/main/java/com/auth0/AuthenticationController.java +++ b/src/main/java/com/auth0/AuthenticationController.java @@ -7,8 +7,8 @@ import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang3.Validate; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; /** @@ -317,7 +317,7 @@ public Tokens handle(HttpServletRequest request, HttpServletResponse response) t * when building the {@link AuthorizeUrl} that the user will be redirected to to login. Failure to do so may result * in a broken login experience for the user.

* - * @deprecated This method uses the {@link javax.servlet.http.HttpSession} for auth-based data, and is incompatible + * @deprecated This method uses the {@link jakarta.servlet.http.HttpSession} for auth-based data, and is incompatible * with clients that are using the "id_token" or "token" responseType with browsers that enforce SameSite cookie * restrictions. This method will be removed in version 2.0.0. Use * {@link AuthenticationController#handle(HttpServletRequest, HttpServletResponse)} instead. @@ -341,7 +341,7 @@ public Tokens handle(HttpServletRequest request) throws IdentityVerificationExce * {@link AuthenticationController#handle(HttpServletRequest)} method. Failure to do so may result in a broken login * experience for users.

* - * @deprecated This method stores data in the {@link javax.servlet.http.HttpSession}, and is incompatible with clients + * @deprecated This method stores data in the {@link jakarta.servlet.http.HttpSession}, and is incompatible with clients * that are using the "id_token" or "token" responseType with browsers that enforce SameSite cookie restrictions. * This method will be removed in version 2.0.0. Use * {@link AuthenticationController#buildAuthorizeUrl(HttpServletRequest, HttpServletResponse, String)} instead. diff --git a/src/main/java/com/auth0/AuthorizeUrl.java b/src/main/java/com/auth0/AuthorizeUrl.java index e871ca6..d9dbf31 100644 --- a/src/main/java/com/auth0/AuthorizeUrl.java +++ b/src/main/java/com/auth0/AuthorizeUrl.java @@ -5,8 +5,8 @@ import com.auth0.exception.Auth0Exception; import com.auth0.json.auth.PushedAuthorizationResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.*; import static com.auth0.IdentityVerificationException.API_ERROR; @@ -39,7 +39,7 @@ public class AuthorizeUrl { * * Using this constructor with a non-null {@link HttpServletResponse} will store the state and nonce as * cookies when the {@link AuthorizeUrl#build()} method is called, with the appropriate SameSite attribute depending - * on the responseType. State and nonce will also be stored in the {@link javax.servlet.http.HttpSession} as a fallback, + * on the responseType. State and nonce will also be stored in the {@link jakarta.servlet.http.HttpSession} as a fallback, * but this behavior will be removed in a future release, and only cookies will be used. * * @param client the Auth0 Authentication API client diff --git a/src/main/java/com/auth0/RandomStorage.java b/src/main/java/com/auth0/RandomStorage.java index 66659a0..4382cc6 100644 --- a/src/main/java/com/auth0/RandomStorage.java +++ b/src/main/java/com/auth0/RandomStorage.java @@ -1,7 +1,7 @@ package com.auth0; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; class RandomStorage extends SessionUtils { diff --git a/src/main/java/com/auth0/RequestProcessor.java b/src/main/java/com/auth0/RequestProcessor.java index 6796982..d5ae977 100644 --- a/src/main/java/com/auth0/RequestProcessor.java +++ b/src/main/java/com/auth0/RequestProcessor.java @@ -5,8 +5,8 @@ import com.auth0.json.auth.TokenHolder; import org.apache.commons.lang3.Validate; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/com/auth0/SessionUtils.java b/src/main/java/com/auth0/SessionUtils.java index a6906dc..4c29665 100644 --- a/src/main/java/com/auth0/SessionUtils.java +++ b/src/main/java/com/auth0/SessionUtils.java @@ -2,8 +2,8 @@ import org.apache.commons.lang3.Validate; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; /** * Helper class to handle easy session key-value storage. diff --git a/src/main/java/com/auth0/TransientCookieStore.java b/src/main/java/com/auth0/TransientCookieStore.java index df5dd3c..e828028 100644 --- a/src/main/java/com/auth0/TransientCookieStore.java +++ b/src/main/java/com/auth0/TransientCookieStore.java @@ -2,9 +2,9 @@ import org.apache.commons.lang3.Validate; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; diff --git a/src/test/java/com/auth0/AuthenticationControllerTest.java b/src/test/java/com/auth0/AuthenticationControllerTest.java index 25302f0..e31cdcc 100644 --- a/src/test/java/com/auth0/AuthenticationControllerTest.java +++ b/src/test/java/com/auth0/AuthenticationControllerTest.java @@ -16,8 +16,8 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; @@ -392,7 +392,7 @@ public void shouldBuildAuthorizeUriWithRandomStateAndNonce() { HttpServletRequest request = new MockHttpServletRequest(); HttpServletResponse response = new MockHttpServletResponse(); - controller.buildAuthorizeUrl(request, response,"https://redirect.uri/here"); + controller.buildAuthorizeUrl(request, response, "https://redirect.uri/here"); verify(requestProcessor).buildAuthorizeUrl(eq(request), eq(response), eq("https://redirect.uri/here"), anyString(), anyString()); } @@ -412,7 +412,7 @@ public void shouldSetLaxCookiesAndNoLegacyCookieWhenCodeFlow() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(1)); - assertThat(headers, everyItem(is("com.auth0.state=state; HttpOnly; Max-Age=600; SameSite=Lax"))); + assertThat(headers, everyItem(matchesPattern("com\\.auth0\\.state=state; Max-Age=600; Expires=.*?; HttpOnly; SameSite=Lax"))); } @Test @@ -431,10 +431,10 @@ public void shouldSetSameSiteNoneCookiesAndLegacyCookieWhenIdTokenResponse() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(4)); - assertThat(headers, hasItem("com.auth0.state=state; HttpOnly; Max-Age=600; SameSite=None; Secure")); - assertThat(headers, hasItem("_com.auth0.state=state; HttpOnly; Max-Age=600")); - assertThat(headers, hasItem("com.auth0.nonce=nonce; HttpOnly; Max-Age=600; SameSite=None; Secure")); - assertThat(headers, hasItem("_com.auth0.nonce=nonce; HttpOnly; Max-Age=600")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=state; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); + assertThat(headers, hasItem(matchesPattern("_com\\.auth0\\.state=state; Max-Age=600; Expires=.*?; HttpOnly"))); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.nonce=nonce; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); + assertThat(headers, hasItem(matchesPattern("_com\\.auth0\\.nonce=nonce; Max-Age=600; Expires=.*?; HttpOnly"))); } @Test @@ -454,8 +454,8 @@ public void shouldSetSameSiteNoneCookiesAndNoLegacyCookieWhenIdTokenResponse() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(2)); - assertThat(headers, hasItem("com.auth0.state=state; HttpOnly; Max-Age=600; SameSite=None; Secure")); - assertThat(headers, hasItem("com.auth0.nonce=nonce; HttpOnly; Max-Age=600; SameSite=None; Secure")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=state; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.nonce=nonce; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); } @Test @@ -512,7 +512,7 @@ public void shouldCheckSessionFallbackWhenHandleCalledWithRequest() throws Excep MockHttpServletResponse response = new MockHttpServletResponse(); // build auth URL using request and response, which stores state and nonce in cookies and also session as a fallback - String authUrl = controller.buildAuthorizeUrl(request, response,"https://redirect.uri/here") + String authUrl = controller.buildAuthorizeUrl(request, response, "https://redirect.uri/here") .withState("state") .withNonce("nonce") .build(); @@ -581,6 +581,6 @@ public void shouldConfigureCookiePath() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(1)); - assertThat(headers, everyItem(is("com.auth0.state=state; HttpOnly; Max-Age=600; Path=/Path; SameSite=Lax"))); + assertThat(headers, everyItem(matchesPattern("com\\.auth0\\.state=state; Path=/Path; Max-Age=600; Expires=.*?; HttpOnly; SameSite=Lax"))); } } diff --git a/src/test/java/com/auth0/AuthorizeUrlTest.java b/src/test/java/com/auth0/AuthorizeUrlTest.java index 5818265..e699560 100644 --- a/src/test/java/com/auth0/AuthorizeUrlTest.java +++ b/src/test/java/com/auth0/AuthorizeUrlTest.java @@ -11,13 +11,14 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.Collection; import java.util.Map; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesPattern; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.*; @@ -91,8 +92,8 @@ public void shouldSetNonceSameSiteAndLegacyCookieByDefault() { Collection headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(2)); - assertThat(headers, hasItem("com.auth0.nonce=asdfghjkl; HttpOnly; Max-Age=600; SameSite=None; Secure")); - assertThat(headers, hasItem("_com.auth0.nonce=asdfghjkl; HttpOnly; Max-Age=600")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.nonce=asdfghjkl; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); + assertThat(headers, hasItem(matchesPattern("_com\\.auth0\\.nonce=asdfghjkl; Max-Age=600; Expires=.*?; HttpOnly"))); } @Test @@ -105,7 +106,7 @@ public void shouldSetNonceSameSiteAndNotLegacyCookieWhenConfigured() { Collection headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(1)); - assertThat(headers, hasItem("com.auth0.nonce=asdfghjkl; HttpOnly; Max-Age=600; SameSite=None; Secure")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.nonce=asdfghjkl; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); } @Test @@ -117,8 +118,8 @@ public void shouldSetStateSameSiteAndLegacyCookieByDefault() { Collection headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(2)); - assertThat(headers, hasItem("com.auth0.state=asdfghjkl; HttpOnly; Max-Age=600; SameSite=None; Secure")); - assertThat(headers, hasItem("_com.auth0.state=asdfghjkl; HttpOnly; Max-Age=600")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=asdfghjkl; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); + assertThat(headers, hasItem(matchesPattern("_com\\.auth0\\.state=asdfghjkl; Max-Age=600; Expires=.*?; HttpOnly"))); } @Test @@ -131,7 +132,7 @@ public void shouldSetStateSameSiteAndNotLegacyCookieWhenConfigured() { Collection headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(1)); - assertThat(headers, hasItem("com.auth0.state=asdfghjkl; HttpOnly; Max-Age=600; SameSite=None; Secure")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=asdfghjkl; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); } @Test @@ -144,7 +145,7 @@ public void shouldSetSecureCookieWhenConfiguredTrue() { Collection headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(1)); - assertThat(headers, hasItem("com.auth0.state=asdfghjkl; HttpOnly; Max-Age=600; SameSite=Lax; Secure")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=asdfghjkl; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=Lax"))); } @Test @@ -157,8 +158,8 @@ public void shouldSetSecureCookieWhenConfiguredFalseAndSameSiteNone() { Collection headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(2)); - assertThat(headers, hasItem("com.auth0.state=asdfghjkl; HttpOnly; Max-Age=600; SameSite=None; Secure")); - assertThat(headers, hasItem("_com.auth0.state=asdfghjkl; HttpOnly; Max-Age=600")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=asdfghjkl; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); + assertThat(headers, hasItem(matchesPattern("_com\\.auth0\\.state=asdfghjkl; Max-Age=600; Expires=.*?; HttpOnly"))); } @Test diff --git a/src/test/java/com/auth0/RequestProcessorTest.java b/src/test/java/com/auth0/RequestProcessorTest.java index 7ffcf60..ef0f538 100644 --- a/src/test/java/com/auth0/RequestProcessorTest.java +++ b/src/test/java/com/auth0/RequestProcessorTest.java @@ -12,8 +12,8 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; import java.util.Collections; import java.util.HashMap; import java.util.Map; diff --git a/src/test/java/com/auth0/TransientCookieStoreTest.java b/src/test/java/com/auth0/TransientCookieStoreTest.java index 949fb05..ccd384c 100644 --- a/src/test/java/com/auth0/TransientCookieStoreTest.java +++ b/src/test/java/com/auth0/TransientCookieStoreTest.java @@ -6,13 +6,14 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import javax.servlet.http.Cookie; +import jakarta.servlet.http.Cookie; import java.net.URLEncoder; import java.util.Arrays; import java.util.List; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesPattern; public class TransientCookieStoreTest { @@ -49,11 +50,9 @@ public void shouldHandleSpecialCharsWhenStoringState() throws Exception { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(2)); - String expectedEncodedState = URLEncoder.encode(stateVal, "UTF-8"); - assertThat(headers, hasItem( - String.format("com.auth0.state=%s; HttpOnly; Max-Age=600; SameSite=None; Secure", expectedEncodedState))); - assertThat(headers, hasItem( - String.format("_com.auth0.state=%s; HttpOnly; Max-Age=600", expectedEncodedState))); + String expectedEncodedState = URLEncoder.encode(stateVal, "UTF-8").replaceAll("\\+", "\\\\+"); + assertThat(headers, hasItem(matchesPattern(String.format("com\\.auth0\\.state=%s; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None", expectedEncodedState)))); + assertThat(headers, hasItem(matchesPattern(String.format("_com\\.auth0\\.state=%s; Max-Age=600; Expires=.*?; HttpOnly", expectedEncodedState)))); } @Test @@ -63,8 +62,8 @@ public void shouldSetStateSameSiteCookieAndFallbackCookie() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(2)); - assertThat(headers, hasItem("com.auth0.state=123456; HttpOnly; Max-Age=600; SameSite=None; Secure")); - assertThat(headers, hasItem("_com.auth0.state=123456; HttpOnly; Max-Age=600")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=123456; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); + assertThat(headers, hasItem(matchesPattern("_com\\.auth0\\.state=123456; Max-Age=600; Expires=.*?; HttpOnly"))); } @Test @@ -74,7 +73,7 @@ public void shouldSetStateSameSiteCookieAndNoFallbackCookie() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(1)); - assertThat(headers, hasItem("com.auth0.state=123456; HttpOnly; Max-Age=600; SameSite=None; Secure")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=123456; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); } @Test @@ -84,7 +83,7 @@ public void shouldSetSecureCookieWhenSameSiteLaxAndConfigured() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(1)); - assertThat(headers, hasItem("com.auth0.state=123456; HttpOnly; Max-Age=600; SameSite=Lax; Secure")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=123456; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=Lax"))); } @Test @@ -94,8 +93,8 @@ public void shouldSetSecureFallbackCookieWhenSameSiteNoneAndConfigured() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(2)); - assertThat(headers, hasItem("com.auth0.state=123456; HttpOnly; Max-Age=600; SameSite=None; Secure")); - assertThat(headers, hasItem("_com.auth0.state=123456; HttpOnly; Max-Age=600; Secure")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=123456; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); + assertThat(headers, hasItem(matchesPattern("_com\\.auth0\\.state=123456; Max-Age=600; Expires=.*?; Secure; HttpOnly"))); } @Test @@ -105,7 +104,7 @@ public void shouldNotSetSecureCookieWhenSameSiteLaxAndConfigured() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(1)); - assertThat(headers, hasItem("com.auth0.state=123456; HttpOnly; Max-Age=600; SameSite=Lax")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.state=123456; Max-Age=600; Expires=.*?; HttpOnly; SameSite=Lax"))); } @Test @@ -115,8 +114,8 @@ public void shouldSetNonceSameSiteCookieAndFallbackCookie() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(2)); - assertThat(headers, hasItem("com.auth0.nonce=123456; HttpOnly; Max-Age=600; SameSite=None; Secure")); - assertThat(headers, hasItem("_com.auth0.nonce=123456; HttpOnly; Max-Age=600")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.nonce=123456; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); + assertThat(headers, hasItem(matchesPattern("_com\\.auth0\\.nonce=123456; Max-Age=600; Expires=.*?; HttpOnly"))); } @Test @@ -126,7 +125,7 @@ public void shouldSetNonceSameSiteCookieAndNoFallbackCookie() { List headers = response.getHeaders("Set-Cookie"); assertThat(headers.size(), is(1)); - assertThat(headers, hasItem("com.auth0.nonce=123456; HttpOnly; Max-Age=600; SameSite=None; Secure")); + assertThat(headers, hasItem(matchesPattern("com\\.auth0\\.nonce=123456; Max-Age=600; Expires=.*?; Secure; HttpOnly; SameSite=None"))); } @Test From cd05210930f79de0bc8d465395a8f3e268536de8 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Tue, 7 Apr 2026 11:33:17 +0530 Subject: [PATCH 09/13] Bumped auth0-java to v3 version --- build.gradle | 2 +- src/test/java/com/auth0/AuthorizeUrlTest.java | 47 ++++++++----------- .../java/com/auth0/RequestProcessorTest.java | 14 +++--- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/build.gradle b/build.gradle index 9999f06..a823d49 100644 --- a/build.gradle +++ b/build.gradle @@ -125,7 +125,7 @@ dependencies { implementation 'com.google.guava:guava-annotations:r03' implementation 'commons-codec:commons-codec:1.15' - api 'com.auth0:auth0:2.16.0' + api 'com.auth0:auth0:3.3.0' api 'com.auth0:java-jwt:3.19.4' api 'com.auth0:jwks-rsa:0.22.1' diff --git a/src/test/java/com/auth0/AuthorizeUrlTest.java b/src/test/java/com/auth0/AuthorizeUrlTest.java index bbecc56..6366191 100644 --- a/src/test/java/com/auth0/AuthorizeUrlTest.java +++ b/src/test/java/com/auth0/AuthorizeUrlTest.java @@ -14,7 +14,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Collection; -import java.util.Map; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; @@ -32,7 +31,7 @@ public class AuthorizeUrlTest { @BeforeEach public void setUp() { - client = new AuthAPI("domain.auth0.com", "clientId", "clientSecret"); + client = AuthAPI.newBuilder("domain.auth0.com", "clientId", "clientSecret").build(); request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); } @@ -246,15 +245,19 @@ public void shouldThrowWhenChangingTheNonceUsingCustomParameterSetter() { @Test public void shouldGetAuthorizeUrlFromPAR() throws Exception { - AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); + AuthAPI authAPIMock = mock(AuthAPI.class); Request requestMock = mock(Request.class); Response pushedAuthorizationResponseResponse = mock(Response.class); when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse); when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", 90)); - authAPIStub.pushedAuthorizationResponseRequest = requestMock; - String url = new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") + when(authAPIMock.pushedAuthorizationRequest(eq("https://domain.com/callback"), eq("code"), anyMap())) + .thenReturn(requestMock); + when(authAPIMock.authorizeUrlWithPAR("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2")) + .thenReturn("https://domain.com/authorize?client_id=clientId&request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2"); + + String url = new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code") .fromPushedAuthorizationRequest(); assertThat(url, is("https://domain.com/authorize?client_id=clientId&request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2")); @@ -262,16 +265,17 @@ public void shouldGetAuthorizeUrlFromPAR() throws Exception { @Test public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsNull() throws Exception { - AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); + AuthAPI authAPIMock = mock(AuthAPI.class); Request requestMock = mock(Request.class); Response pushedAuthorizationResponseResponse = mock(Response.class); when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse); when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse(null, 90)); - authAPIStub.pushedAuthorizationResponseRequest = requestMock; + when(authAPIMock.pushedAuthorizationRequest(eq("https://domain.com/callback"), eq("code"), anyMap())) + .thenReturn(requestMock); InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { - new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") + new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code") .fromPushedAuthorizationRequest(); }); @@ -280,16 +284,17 @@ public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsNull() throws Ex @Test public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsEmpty() throws Exception { - AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); + AuthAPI authAPIMock = mock(AuthAPI.class); Request requestMock = mock(Request.class); Response pushedAuthorizationResponseResponse = mock(Response.class); when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse); when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", null)); - authAPIStub.pushedAuthorizationResponseRequest = requestMock; + when(authAPIMock.pushedAuthorizationRequest(eq("https://domain.com/callback"), eq("code"), anyMap())) + .thenReturn(requestMock); InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { - new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") + new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code") .fromPushedAuthorizationRequest(); }); @@ -298,16 +303,17 @@ public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsEmpty() throws E @Test public void fromPushedAuthorizationRequestThrowsWhenExpiresInIsNull() throws Exception { - AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret"); + AuthAPI authAPIMock = mock(AuthAPI.class); Request requestMock = mock(Request.class); Response pushedAuthorizationResponseResponse = mock(Response.class); when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse); when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse(null, 90)); - authAPIStub.pushedAuthorizationResponseRequest = requestMock; + when(authAPIMock.pushedAuthorizationRequest(eq("https://domain.com/callback"), eq("code"), anyMap())) + .thenReturn(requestMock); InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { - new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code") + new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code") .fromPushedAuthorizationRequest(); }); @@ -333,17 +339,4 @@ public void fromPushedAuthorizationRequestThrowsWhenRequestThrows() throws Excep assertThat(exception.getCause(), instanceOf(Auth0Exception.class)); } - static class AuthAPIStub extends AuthAPI { - - Request pushedAuthorizationResponseRequest; - - public AuthAPIStub(String domain, String clientId, String clientSecret) { - super(domain, clientId, clientSecret); - } - - @Override - public Request pushedAuthorizationRequest(String redirectUri, String responseType, Map params) { - return pushedAuthorizationResponseRequest; - } - } } diff --git a/src/test/java/com/auth0/RequestProcessorTest.java b/src/test/java/com/auth0/RequestProcessorTest.java index 281ff17..0760c06 100644 --- a/src/test/java/com/auth0/RequestProcessorTest.java +++ b/src/test/java/com/auth0/RequestProcessorTest.java @@ -480,7 +480,7 @@ public void shouldReturnEmptyTokensWhenCodeRequestReturnsNoTokens() throws Excep @Test public void shouldBuildAuthorizeUrl() { - AuthAPI client = new AuthAPI("me.auth0.com", "clientId", "clientSecret"); + AuthAPI client = AuthAPI.newBuilder("me.auth0.com", "clientId", "clientSecret").build(); SignatureVerifier signatureVerifier = mock(SignatureVerifier.class); IdTokenVerifier.Options verifyOptions = new IdTokenVerifier.Options("issuer", "audience", signatureVerifier); RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) @@ -503,7 +503,7 @@ public void shouldBuildAuthorizeUrl() { @Test public void shouldSetMaxAgeIfProvided() { - AuthAPI client = new AuthAPI("me.auth0.com", "clientId", "clientSecret"); + AuthAPI client = AuthAPI.newBuilder("me.auth0.com", "clientId", "clientSecret").build(); when(verifyOptions.getMaxAge()).thenReturn(906030); RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) .build(); @@ -517,7 +517,7 @@ public void shouldSetMaxAgeIfProvided() { @Test public void shouldNotSetNonceIfRequestTypeIsNotIdToken() { - AuthAPI client = new AuthAPI("me.auth0.com", "clientId", "clientSecret"); + AuthAPI client = AuthAPI.newBuilder("me.auth0.com", "clientId", "clientSecret").build(); RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) .build(); HttpServletRequest request = new MockHttpServletRequest(); @@ -530,7 +530,7 @@ public void shouldNotSetNonceIfRequestTypeIsNotIdToken() { @Test public void shouldSetNonceIfRequestTypeIsIdToken() { - AuthAPI client = new AuthAPI("me.auth0.com", "clientId", "clientSecret"); + AuthAPI client = AuthAPI.newBuilder("me.auth0.com", "clientId", "clientSecret").build(); RequestProcessor handler = new RequestProcessor.Builder(client, "id_token", verifyOptions) .build(); HttpServletRequest request = new MockHttpServletRequest(); @@ -543,7 +543,7 @@ public void shouldSetNonceIfRequestTypeIsIdToken() { @Test public void shouldNotSetNullNonceIfRequestTypeIsIdToken() { - AuthAPI client = new AuthAPI("me.auth0.com", "clientId", "clientSecret"); + AuthAPI client = AuthAPI.newBuilder("me.auth0.com", "clientId", "clientSecret").build(); RequestProcessor handler = new RequestProcessor.Builder(client, "id_token", verifyOptions) .build(); HttpServletRequest request = new MockHttpServletRequest(); @@ -556,7 +556,7 @@ public void shouldNotSetNullNonceIfRequestTypeIsIdToken() { @Test public void shouldBuildAuthorizeUrlWithNonceAndFormPostIfResponseTypeIsIdToken() { - AuthAPI client = new AuthAPI("me.auth0.com", "clientId", "clientSecret"); + AuthAPI client = AuthAPI.newBuilder("me.auth0.com", "clientId", "clientSecret").build(); RequestProcessor handler = new RequestProcessor.Builder(client, "id_token", verifyOptions) .build(); HttpServletRequest request = new MockHttpServletRequest(); @@ -576,7 +576,7 @@ public void shouldBuildAuthorizeUrlWithNonceAndFormPostIfResponseTypeIsIdToken() @Test public void shouldBuildAuthorizeUrlWithFormPostIfResponseTypeIsToken() { - AuthAPI client = new AuthAPI("me.auth0.com", "clientId", "clientSecret"); + AuthAPI client = AuthAPI.newBuilder("me.auth0.com", "clientId", "clientSecret").build(); RequestProcessor handler = new RequestProcessor.Builder(client, "token", verifyOptions) .build(); HttpServletRequest request = new MockHttpServletRequest(); From 788e6261833c1f0dcc1a8000a1d9c2120e85303a Mon Sep 17 00:00:00 2001 From: tanya732 Date: Wed, 15 Apr 2026 15:38:33 +0530 Subject: [PATCH 10/13] Updated tests --- .../auth0/AuthenticationControllerTest.java | 206 +++++++----------- 1 file changed, 80 insertions(+), 126 deletions(-) diff --git a/src/test/java/com/auth0/AuthenticationControllerTest.java b/src/test/java/com/auth0/AuthenticationControllerTest.java index 10be941..b9e1d52 100644 --- a/src/test/java/com/auth0/AuthenticationControllerTest.java +++ b/src/test/java/com/auth0/AuthenticationControllerTest.java @@ -1,7 +1,11 @@ package com.auth0; import com.auth0.client.auth.AuthAPI; +import com.auth0.client.auth.AuthorizeUrlBuilder; +import com.auth0.json.auth.TokenHolder; import com.auth0.jwk.JwkProvider; +import com.auth0.net.Response; +import com.auth0.net.TokenRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -40,65 +44,11 @@ public void setUp() { AuthenticationController.Builder builder = AuthenticationController.newBuilder("domain", "clientId", "clientSecret"); builderSpy = spy(builder); - //doReturn(client).when(builderSpy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), eq(null)); + doReturn(client).when(builderSpy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret")); doReturn(verificationOptions).when(builderSpy).createIdTokenVerificationOptions(eq("https://domain/"), eq("clientId"), signatureVerifierCaptor.capture()); doReturn("1.2.3").when(builderSpy).obtainPackageVersion(); } -// @Test -// public void shouldSetupClientWithTelemetry() { -// AuthenticationController controller = builderSpy.build(); -// -// ArgumentCaptor telemetryCaptor = ArgumentCaptor.forClass(Telemetry.class); -// -// assertThat(controller, is(notNullValue())); -// RequestProcessor requestProcessor = controller.getRequestProcessor(); -// assertThat(requestProcessor.getClient(), is(client)); -// verify(client).setTelemetry(telemetryCaptor.capture()); -// -// Telemetry capturedTelemetry = telemetryCaptor.getValue(); -// assertThat(capturedTelemetry, is(notNullValue())); -// assertThat(capturedTelemetry.getName(), is("auth0-java-mvc-common")); -// assertThat(capturedTelemetry.getVersion(), is("1.2.3")); -// } - -// @Test -// public void shouldCreateAuthAPIClientWithoutCustomHttpOptions() { -// ArgumentCaptor captor = ArgumentCaptor.forClass(HttpOptions.class); -// AuthenticationController.Builder spy = spy(AuthenticationController.newBuilder("domain", "clientId", "clientSecret")); -// -// spy.build(); -// verify(spy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), captor.capture()); -// -// HttpOptions actual = captor.getValue(); -// assertThat(actual, is(nullValue())); -// -// } -// -// @Test -// public void shouldDisableTelemetry() { -// AuthenticationController controller = builderSpy.build(); -// controller.doNotSendTelemetry(); -// -// verify(client).doNotSendTelemetry(); -// } -// -// @Test -// public void shouldEnableLogging() { -// AuthenticationController controller = builderSpy.build(); -// -// controller.setLoggingEnabled(true); -// verify(client).setLoggingEnabled(true); -// } -// -// @Test -// public void shouldDisableLogging() { -// AuthenticationController controller = builderSpy.build(); -// -// controller.setLoggingEnabled(true); -// verify(client).setLoggingEnabled(true); -// } - @Test public void shouldCreateWithSymmetricSignatureVerifierForNoCodeGrants() { AuthenticationController controller = builderSpy @@ -434,77 +384,81 @@ public void shouldSetSameSiteNoneCookiesAndNoLegacyCookieWhenIdTokenResponse() { assertThat(headers, hasItem("com.auth0.nonce=nonce; HttpOnly; Max-Age=600; SameSite=None; Secure")); } -// @Test -// public void shouldCheckSessionFallbackWhenHandleCalledWithRequestAndResponse() throws Exception { -// AuthenticationController controller = builderSpy.withResponseType("code").build(); -// -// TokenRequest codeExchangeRequest = mock(TokenRequest.class); -// TokenHolder tokenHolder = mock(TokenHolder.class); -// when(codeExchangeRequest.execute()).thenReturn(tokenHolder); -// when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest); -// -// AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class); -// when(mockBuilder.withResponseType("code")).thenReturn(mockBuilder); -// when(mockBuilder.withScope("openid")).thenReturn(mockBuilder); -// when(client.authorizeUrl("https://redirect.uri/here")).thenReturn(mockBuilder); -// -// MockHttpServletRequest request = new MockHttpServletRequest(); -// MockHttpServletResponse response = new MockHttpServletResponse(); -// -// // build auth URL using deprecated method, which stores state and nonce in session -// String authUrl = controller.buildAuthorizeUrl(request, "https://redirect.uri/here") -// .withState("state") -// .withNonce("nonce") -// .build(); -// -// String state = (String) request.getSession().getAttribute("com.auth0.state"); -// String nonce = (String) request.getSession().getAttribute("com.auth0.nonce"); -// assertThat(state, is("state")); -// assertThat(nonce, is("nonce")); -// -// request.setParameter("state", "state"); -// request.setParameter("nonce", "nonce"); -// request.setParameter("code", "abc123"); -// -// // handle called with request and response, which should use cookies but fallback to session -// controller.handle(request, response); -// } - -// @Test -// public void shouldCheckSessionFallbackWhenHandleCalledWithRequest() throws Exception { -// AuthenticationController controller = builderSpy.withResponseType("code").build(); -// -// TokenRequest codeExchangeRequest = mock(TokenRequest.class); -// TokenHolder tokenHolder = mock(TokenHolder.class); -// when(codeExchangeRequest.execute()).thenReturn(tokenHolder); -// when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest); -// -// AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class); -// when(mockBuilder.withResponseType("code")).thenReturn(mockBuilder); -// when(mockBuilder.withScope("openid")).thenReturn(mockBuilder); -// when(client.authorizeUrl("https://redirect.uri/here")).thenReturn(mockBuilder); -// -// MockHttpServletRequest request = new MockHttpServletRequest(); -// MockHttpServletResponse response = new MockHttpServletResponse(); -// -// // build auth URL using request and response, which stores state and nonce in cookies and also session as a fallback -// String authUrl = controller.buildAuthorizeUrl(request, response,"https://redirect.uri/here") -// .withState("state") -// .withNonce("nonce") -// .build(); -// -// String state = (String) request.getSession().getAttribute("com.auth0.state"); -// String nonce = (String) request.getSession().getAttribute("com.auth0.nonce"); -// assertThat(state, is("state")); -// assertThat(nonce, is("nonce")); -// -// request.setParameter("state", "state"); -// request.setParameter("nonce", "nonce"); -// request.setParameter("code", "abc123"); -// -// // handle called with request, which should use session -// controller.handle(request); -// } + @Test + public void shouldCheckSessionFallbackWhenHandleCalledWithRequestAndResponse() throws Exception { + AuthenticationController controller = builderSpy.withResponseType("code").build(); + + TokenRequest codeExchangeRequest = mock(TokenRequest.class); + Response tokenResponse = mock(Response.class); + TokenHolder tokenHolder = mock(TokenHolder.class); + when(tokenResponse.getBody()).thenReturn(tokenHolder); + when(codeExchangeRequest.execute()).thenReturn(tokenResponse); + when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest); + + AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class); + when(mockBuilder.withResponseType("code")).thenReturn(mockBuilder); + when(mockBuilder.withScope("openid")).thenReturn(mockBuilder); + when(client.authorizeUrl("https://redirect.uri/here")).thenReturn(mockBuilder); + + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + + // build auth URL using deprecated method, which stores state and nonce in session + String authUrl = controller.buildAuthorizeUrl(request, "https://redirect.uri/here") + .withState("state") + .withNonce("nonce") + .build(); + + String state = (String) request.getSession().getAttribute("com.auth0.state"); + String nonce = (String) request.getSession().getAttribute("com.auth0.nonce"); + assertThat(state, is("state")); + assertThat(nonce, is("nonce")); + + request.setParameter("state", "state"); + request.setParameter("nonce", "nonce"); + request.setParameter("code", "abc123"); + + // handle called with request and response, which should use cookies but fallback to session + controller.handle(request, response); + } + + @Test + public void shouldCheckSessionFallbackWhenHandleCalledWithRequest() throws Exception { + AuthenticationController controller = builderSpy.withResponseType("code").build(); + + TokenRequest codeExchangeRequest = mock(TokenRequest.class); + Response tokenResponse = mock(Response.class); + TokenHolder tokenHolder = mock(TokenHolder.class); + when(tokenResponse.getBody()).thenReturn(tokenHolder); + when(codeExchangeRequest.execute()).thenReturn(tokenResponse); + when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest); + + AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class); + when(mockBuilder.withResponseType("code")).thenReturn(mockBuilder); + when(mockBuilder.withScope("openid")).thenReturn(mockBuilder); + when(client.authorizeUrl("https://redirect.uri/here")).thenReturn(mockBuilder); + + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + + // build auth URL using request and response, which stores state and nonce in cookies and also session as a fallback + String authUrl = controller.buildAuthorizeUrl(request, response,"https://redirect.uri/here") + .withState("state") + .withNonce("nonce") + .build(); + + String state = (String) request.getSession().getAttribute("com.auth0.state"); + String nonce = (String) request.getSession().getAttribute("com.auth0.nonce"); + assertThat(state, is("state")); + assertThat(nonce, is("nonce")); + + request.setParameter("state", "state"); + request.setParameter("nonce", "nonce"); + request.setParameter("code", "abc123"); + + // handle called with request, which should use session + controller.handle(request); + } @Test public void shouldAllowOrganizationParameter() { From ad53de6bd633759d2f791c2e2e1f03f8a3688bfb Mon Sep 17 00:00:00 2001 From: tanya732 Date: Wed, 29 Apr 2026 00:06:42 +0530 Subject: [PATCH 11/13] Feat: Removing deprecated endpoints --- .../com/auth0/AuthenticationController.java | 55 ------------- src/main/java/com/auth0/AuthorizeUrl.java | 23 ++---- .../com/auth0/InvalidRequestException.java | 11 --- src/main/java/com/auth0/RandomStorage.java | 52 ------------ src/main/java/com/auth0/RequestProcessor.java | 55 +++---------- src/main/java/com/auth0/SessionUtils.java | 64 --------------- .../auth0/AuthenticationControllerTest.java | 75 ----------------- src/test/java/com/auth0/AuthorizeUrlTest.java | 11 --- .../auth0/InvalidRequestExceptionTest.java | 5 +- .../java/com/auth0/RandomStorageTest.java | 80 ------------------- .../java/com/auth0/RequestProcessorTest.java | 49 ++---------- src/test/java/com/auth0/SessionUtilsTest.java | 45 ----------- 12 files changed, 22 insertions(+), 503 deletions(-) delete mode 100644 src/main/java/com/auth0/RandomStorage.java delete mode 100644 src/main/java/com/auth0/SessionUtils.java delete mode 100644 src/test/java/com/auth0/RandomStorageTest.java delete mode 100644 src/test/java/com/auth0/SessionUtilsTest.java diff --git a/src/main/java/com/auth0/AuthenticationController.java b/src/main/java/com/auth0/AuthenticationController.java index e3f2b21..d52880c 100644 --- a/src/main/java/com/auth0/AuthenticationController.java +++ b/src/main/java/com/auth0/AuthenticationController.java @@ -273,61 +273,6 @@ public Tokens handle(HttpServletRequest request, HttpServletResponse response) t return requestProcessor.process(request, response); } - /** - * Process a request to obtain a set of {@link Tokens} that represent successful authentication or authorization. - * - * This method should be called when processing the callback request to your application. It will validate - * authentication-related request parameters, handle performing a Code Exchange request if using - * the "code" response type, and verify the integrity of the ID token (if present). - * - *

Important: When using this API, you must also use the {@link AuthenticationController#buildAuthorizeUrl(HttpServletRequest, String)} - * when building the {@link AuthorizeUrl} that the user will be redirected to to login. Failure to do so may result - * in a broken login experience for the user.

- * - * @deprecated This method uses the {@link javax.servlet.http.HttpSession} for auth-based data, and is incompatible - * with clients that are using the "id_token" or "token" responseType with browsers that enforce SameSite cookie - * restrictions. This method will be removed in version 2.0.0. Use - * {@link AuthenticationController#handle(HttpServletRequest, HttpServletResponse)} instead. - * - * @param request the received request to process. - * @return the Tokens obtained after the user authentication. - * @throws InvalidRequestException if the error is result of making an invalid authentication request. - * @throws IdentityVerificationException if an error occurred while verifying the request tokens. - */ - @Deprecated - public Tokens handle(HttpServletRequest request) throws IdentityVerificationException { - Validate.notNull(request, "request must not be null"); - - return requestProcessor.process(request, null); - } - - /** - * Pre builds an Auth0 Authorize Url with the given redirect URI using a random state and a random nonce if applicable. - * - *

Important: When using this API, you must also obtain the tokens using the - * {@link AuthenticationController#handle(HttpServletRequest)} method. Failure to do so may result in a broken login - * experience for users.

- * - * @deprecated This method stores data in the {@link javax.servlet.http.HttpSession}, and is incompatible with clients - * that are using the "id_token" or "token" responseType with browsers that enforce SameSite cookie restrictions. - * This method will be removed in version 2.0.0. Use - * {@link AuthenticationController#buildAuthorizeUrl(HttpServletRequest, HttpServletResponse, String)} instead. - * - * @param request the caller request. Used to keep the session context. - * @param redirectUri the url to call back with the authentication result. - * @return the authorize url builder to continue any further parameter customization. - */ - @Deprecated - public AuthorizeUrl buildAuthorizeUrl(HttpServletRequest request, String redirectUri) { - Validate.notNull(request, "request must not be null"); - Validate.notNull(redirectUri, "redirectUri must not be null"); - - String state = StorageUtils.secureRandomString(); - String nonce = StorageUtils.secureRandomString(); - - return requestProcessor.buildAuthorizeUrl(request, null, redirectUri, state, nonce); - } - /** * Pre builds an Auth0 Authorize Url with the given redirect URI using a random state and a random nonce if applicable. * diff --git a/src/main/java/com/auth0/AuthorizeUrl.java b/src/main/java/com/auth0/AuthorizeUrl.java index 694bf4a..09816ec 100644 --- a/src/main/java/com/auth0/AuthorizeUrl.java +++ b/src/main/java/com/auth0/AuthorizeUrl.java @@ -21,7 +21,6 @@ public class AuthorizeUrl { private static final String SCOPE_OPENID = "openid"; private HttpServletResponse response; - private HttpServletRequest request; private final String responseType; private boolean useLegacySameSiteCookie = true; private boolean setSecureCookie = false; @@ -37,19 +36,16 @@ public class AuthorizeUrl { /** * Creates a new instance that can be used to build an Auth0 Authorization URL. * - * Using this constructor with a non-null {@link HttpServletResponse} will store the state and nonce as - * cookies when the {@link AuthorizeUrl#build()} method is called, with the appropriate SameSite attribute depending - * on the responseType. State and nonce will also be stored in the {@link javax.servlet.http.HttpSession} as a fallback, - * but this behavior will be removed in a future release, and only cookies will be used. + * Stores the state and nonce as cookies when the {@link AuthorizeUrl#build()} method is called, + * with the appropriate SameSite attribute depending on the responseType. * * @param client the Auth0 Authentication API client - * @parem request the HTTP request. Used to store state and nonce as a fallback if cookies not set. + * @param request the HTTP request * @param response the response where the state and nonce will be stored as cookies * @param redirectUri the url to redirect to after authentication * @param responseType the response type to use */ AuthorizeUrl(AuthAPI client, HttpServletRequest request, HttpServletResponse response, String redirectUri, String responseType) { - this.request = request; this.response = response; this.responseType = responseType; this.authAPI = client; @@ -243,17 +239,10 @@ private void storeTransient() { throw new IllegalStateException("The AuthorizeUrl instance must not be reused."); } - if (response != null) { - SameSite sameSiteValue = containsFormPost() ? SameSite.NONE : SameSite.LAX; + SameSite sameSiteValue = containsFormPost() ? SameSite.NONE : SameSite.LAX; - TransientCookieStore.storeState(response, state, sameSiteValue, useLegacySameSiteCookie, setSecureCookie, cookiePath); - TransientCookieStore.storeNonce(response, nonce, sameSiteValue, useLegacySameSiteCookie, setSecureCookie, cookiePath); - } - - // Also store in Session just in case developer uses deprecated - // AuthenticationController.handle(HttpServletRequest) API - RandomStorage.setSessionState(request, state); - RandomStorage.setSessionNonce(request, nonce); + TransientCookieStore.storeState(response, state, sameSiteValue, useLegacySameSiteCookie, setSecureCookie, cookiePath); + TransientCookieStore.storeNonce(response, nonce, sameSiteValue, useLegacySameSiteCookie, setSecureCookie, cookiePath); used = true; } diff --git a/src/main/java/com/auth0/InvalidRequestException.java b/src/main/java/com/auth0/InvalidRequestException.java index 037338f..03690ca 100644 --- a/src/main/java/com/auth0/InvalidRequestException.java +++ b/src/main/java/com/auth0/InvalidRequestException.java @@ -18,15 +18,4 @@ public class InvalidRequestException extends IdentityVerificationException { super(code, description != null ? description : DEFAULT_DESCRIPTION, cause); } - /** - * Getter for the description of the error. - * - * @return the error description if available, null otherwise. - * @deprecated use {@link #getMessage()} - */ - @Deprecated - public String getDescription() { - return getMessage(); - } - } diff --git a/src/main/java/com/auth0/RandomStorage.java b/src/main/java/com/auth0/RandomStorage.java deleted file mode 100644 index 66659a0..0000000 --- a/src/main/java/com/auth0/RandomStorage.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.auth0; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -class RandomStorage extends SessionUtils { - - /** - * Check's if the request {@link HttpSession} saved state is equal to the given state. - * After the check, the value will be removed from the session. - * - * @param req the request - * @param state the state value to compare against. - * @return whether the state matches the expected one or not. - */ - static boolean checkSessionState(HttpServletRequest req, String state) { - String currentState = (String) remove(req, StorageUtils.STATE_KEY); - return (currentState == null && state == null) || currentState != null && currentState.equals(state); - } - - /** - * Saves the given state in the request {@link HttpSession}. - * If a state is already bound to the session, the value is replaced. - * - * @param req the request. - * @param state the state value to set. - */ - static void setSessionState(HttpServletRequest req, String state) { - set(req, StorageUtils.STATE_KEY, state); - } - - /** - * Saves the given nonce in the request {@link HttpSession}. - * If a nonce is already bound to the session, the value is replaced. - * - * @param req the request. - * @param nonce the nonce value to set. - */ - static void setSessionNonce(HttpServletRequest req, String nonce) { - set(req, StorageUtils.NONCE_KEY, nonce); - } - - /** - * Removes the nonce present in the request {@link HttpSession} and then returns it. - * - * @param req the HTTP Servlet request. - * @return the nonce value or null if it was not set. - */ - static String removeSessionNonce(HttpServletRequest req) { - return (String) remove(req, StorageUtils.NONCE_KEY); - } -} \ No newline at end of file diff --git a/src/main/java/com/auth0/RequestProcessor.java b/src/main/java/com/auth0/RequestProcessor.java index 2027e0d..a9e44a9 100644 --- a/src/main/java/com/auth0/RequestProcessor.java +++ b/src/main/java/com/auth0/RequestProcessor.java @@ -121,8 +121,8 @@ AuthAPI getClient() { /** * Pre builds an Auth0 Authorize Url with the given redirect URI, state and nonce parameters. * - * @param request the request, used to store state and nonce in the Session - * @param response the response, used to set state and nonce as cookies. If null, session will be used instead. + * @param request the HTTP request. + * @param response the HTTP response, used to set state and nonce as cookies. * @param redirectUri the url to call with the authentication result. * @param state a valid state value. * @param nonce the nonce value that will be used if the response type contains 'id_token'. Can be null. @@ -144,10 +144,7 @@ AuthorizeUrl buildAuthorizeUrl(HttpServletRequest request, HttpServletResponse r creator.withCookiePath(this.cookiePath); } - // null response means state and nonce will be stored in session, so legacy cookie flag does not apply - if (response != null) { - creator.withLegacySameSiteCookie(useLegacySameSiteCookie); - } + creator.withLegacySameSiteCookie(useLegacySameSiteCookie); return getAuthorizeUrl(nonce, creator); @@ -178,18 +175,8 @@ Tokens process(HttpServletRequest request, HttpServletResponse response) throws throw new InvalidRequestException(MISSING_ACCESS_TOKEN, "Access Token is missing from the response."); } - String nonce; - if (response != null) { - // Nonce dynamically set and changes on every request. - nonce = TransientCookieStore.getNonce(request, response); - - // Just in case the developer created the authorizeUrl that stores state/nonce in the session - if (nonce == null) { - nonce = RandomStorage.removeSessionNonce(request); - } - } else { - nonce = RandomStorage.removeSessionNonce(request); - } + // Nonce dynamically set and changes on every request. + String nonce = TransientCookieStore.getNonce(request, response); verifyOptions.setNonce(nonce); @@ -285,41 +272,24 @@ private void assertNoError(HttpServletRequest request) throws InvalidRequestExce } /** - * Checks whether the state received in the request parameters is the same as the one in the state cookie or session + * Checks whether the state received in the request parameters is the same as the one in the state cookie * for this request. * - * @param request the request + * @param request the request + * @param response the response, used to remove the state cookie * @throws InvalidRequestException if the request contains a different state from the expected one */ private void assertValidState(HttpServletRequest request, HttpServletResponse response) throws InvalidRequestException { - // TODO in v2: - // - only store state/nonce in cookies, remove session storage - // - create specific exception classes for various state validation failures (missing from auth response, missing - // state cookie, mismatch) - String stateFromRequest = request.getParameter(KEY_STATE); if (stateFromRequest == null) { throw new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one. No state parameter was found on the authorization response."); } - // If response is null, check the Session. - // This can happen when the deprecated handle method that only takes the request parameter is called - if (response == null) { - checkSessionState(request, stateFromRequest); - return; - } - String cookieState = TransientCookieStore.getState(request, response); - // Just in case state was stored in Session by building auth URL with deprecated method, but then called the - // supported handle method with the request and response if (cookieState == null) { - if (SessionUtils.get(request, StorageUtils.STATE_KEY) == null) { - throw new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one. No state cookie or state session attribute found. Check that you are using non-deprecated methods and that cookies are not being removed on the server."); - } - checkSessionState(request, stateFromRequest); - return; + throw new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one. No state cookie found. Check that cookies are not being removed on the server."); } if (!cookieState.equals(stateFromRequest)) { @@ -327,13 +297,6 @@ private void assertValidState(HttpServletRequest request, HttpServletResponse re } } - private void checkSessionState(HttpServletRequest request, String stateFromRequest) throws InvalidRequestException { - boolean valid = RandomStorage.checkSessionState(request, stateFromRequest); - if (!valid) { - throw new InvalidRequestException(INVALID_STATE_ERROR, "The received state doesn't match the expected one."); - } - } - /** * Calls the Auth0 Authentication API to perform a Code Exchange. * diff --git a/src/main/java/com/auth0/SessionUtils.java b/src/main/java/com/auth0/SessionUtils.java deleted file mode 100644 index a6906dc..0000000 --- a/src/main/java/com/auth0/SessionUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.auth0; - -import org.apache.commons.lang3.Validate; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -/** - * Helper class to handle easy session key-value storage. - */ -@SuppressWarnings({"WeakerAccess", "unused"}) -public abstract class SessionUtils { - - /** - * Extracts the HttpSession from the given request. - * - * @param req a valid request to get the session from - * @return the session of the request - */ - protected static HttpSession getSession(HttpServletRequest req) { - return req.getSession(true); - } - - /** - * Set's the attribute value to the request session. - * - * @param req a valid request to get the session from - * @param name the name of the attribute - * @param value the value to set - */ - public static void set(HttpServletRequest req, String name, Object value) { - Validate.notNull(req); - Validate.notNull(name); - getSession(req).setAttribute(name, value); - } - - /** - * Get the attribute with the given name from the request session. - * - * @param req a valid request to get the session from - * @param name the name of the attribute - * @return the attribute stored in the session or null if it doesn't exists - */ - public static Object get(HttpServletRequest req, String name) { - Validate.notNull(req); - Validate.notNull(name); - return getSession(req).getAttribute(name); - } - - /** - * Same as {@link #get(HttpServletRequest, String)} but it also removes the value from the request session. - * - * @param req a valid request to get the session from - * @param name the name of the attribute - * @return the attribute stored in the session or null if it doesn't exists - */ - public static Object remove(HttpServletRequest req, String name) { - Validate.notNull(req); - Validate.notNull(name); - Object value = get(req, name); - getSession(req).removeAttribute(name); - return value; - } -} diff --git a/src/test/java/com/auth0/AuthenticationControllerTest.java b/src/test/java/com/auth0/AuthenticationControllerTest.java index b9e1d52..18577a9 100644 --- a/src/test/java/com/auth0/AuthenticationControllerTest.java +++ b/src/test/java/com/auth0/AuthenticationControllerTest.java @@ -384,81 +384,6 @@ public void shouldSetSameSiteNoneCookiesAndNoLegacyCookieWhenIdTokenResponse() { assertThat(headers, hasItem("com.auth0.nonce=nonce; HttpOnly; Max-Age=600; SameSite=None; Secure")); } - @Test - public void shouldCheckSessionFallbackWhenHandleCalledWithRequestAndResponse() throws Exception { - AuthenticationController controller = builderSpy.withResponseType("code").build(); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - Response tokenResponse = mock(Response.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(tokenResponse.getBody()).thenReturn(tokenHolder); - when(codeExchangeRequest.execute()).thenReturn(tokenResponse); - when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest); - - AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class); - when(mockBuilder.withResponseType("code")).thenReturn(mockBuilder); - when(mockBuilder.withScope("openid")).thenReturn(mockBuilder); - when(client.authorizeUrl("https://redirect.uri/here")).thenReturn(mockBuilder); - - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - - // build auth URL using deprecated method, which stores state and nonce in session - String authUrl = controller.buildAuthorizeUrl(request, "https://redirect.uri/here") - .withState("state") - .withNonce("nonce") - .build(); - - String state = (String) request.getSession().getAttribute("com.auth0.state"); - String nonce = (String) request.getSession().getAttribute("com.auth0.nonce"); - assertThat(state, is("state")); - assertThat(nonce, is("nonce")); - - request.setParameter("state", "state"); - request.setParameter("nonce", "nonce"); - request.setParameter("code", "abc123"); - - // handle called with request and response, which should use cookies but fallback to session - controller.handle(request, response); - } - - @Test - public void shouldCheckSessionFallbackWhenHandleCalledWithRequest() throws Exception { - AuthenticationController controller = builderSpy.withResponseType("code").build(); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - Response tokenResponse = mock(Response.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - when(tokenResponse.getBody()).thenReturn(tokenHolder); - when(codeExchangeRequest.execute()).thenReturn(tokenResponse); - when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest); - - AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class); - when(mockBuilder.withResponseType("code")).thenReturn(mockBuilder); - when(mockBuilder.withScope("openid")).thenReturn(mockBuilder); - when(client.authorizeUrl("https://redirect.uri/here")).thenReturn(mockBuilder); - - MockHttpServletRequest request = new MockHttpServletRequest(); - MockHttpServletResponse response = new MockHttpServletResponse(); - - // build auth URL using request and response, which stores state and nonce in cookies and also session as a fallback - String authUrl = controller.buildAuthorizeUrl(request, response,"https://redirect.uri/here") - .withState("state") - .withNonce("nonce") - .build(); - - String state = (String) request.getSession().getAttribute("com.auth0.state"); - String nonce = (String) request.getSession().getAttribute("com.auth0.nonce"); - assertThat(state, is("state")); - assertThat(nonce, is("nonce")); - - request.setParameter("state", "state"); - request.setParameter("nonce", "nonce"); - request.setParameter("code", "abc123"); - - // handle called with request, which should use session - controller.handle(request); - } @Test public void shouldAllowOrganizationParameter() { diff --git a/src/test/java/com/auth0/AuthorizeUrlTest.java b/src/test/java/com/auth0/AuthorizeUrlTest.java index 6366191..ec4824e 100644 --- a/src/test/java/com/auth0/AuthorizeUrlTest.java +++ b/src/test/java/com/auth0/AuthorizeUrlTest.java @@ -171,17 +171,6 @@ public void shouldSetNoCookiesWhenNonceAndStateNotSet() { assertThat(headers.size(), is(0)); } - @Test - public void shouldSetNoSessionValuesWhenNonceAndStateNotSet() { - String url = new AuthorizeUrl(client, request, null, "https://redirect.to/me", "id_token token") - .build(); - assertThat(HttpUrl.parse(url).queryParameter("state"), nullValue()); - assertThat(HttpUrl.parse(url).queryParameter("nonce"), nullValue()); - - Collection headers = response.getHeaders("Set-Cookie"); - assertThat(headers.size(), is(0)); - } - @Test public void shouldSetScope() { String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") diff --git a/src/test/java/com/auth0/InvalidRequestExceptionTest.java b/src/test/java/com/auth0/InvalidRequestExceptionTest.java index e513d58..848c01a 100644 --- a/src/test/java/com/auth0/InvalidRequestExceptionTest.java +++ b/src/test/java/com/auth0/InvalidRequestExceptionTest.java @@ -15,10 +15,9 @@ public void setUp() { exception = new InvalidRequestException("error", "message"); } - @SuppressWarnings("deprecation") @Test - public void shouldGetDescription() { - assertThat(exception.getDescription(), is("message")); + public void shouldGetMessage() { + assertThat(exception.getMessage(), is("message")); } @Test diff --git a/src/test/java/com/auth0/RandomStorageTest.java b/src/test/java/com/auth0/RandomStorageTest.java deleted file mode 100644 index 49a4af7..0000000 --- a/src/test/java/com/auth0/RandomStorageTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.auth0; - -import org.junit.jupiter.api.Test; -import org.springframework.mock.web.MockHttpServletRequest; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -public class RandomStorageTest { - - @Test - public void shouldSetState() { - MockHttpServletRequest req = new MockHttpServletRequest(); - - RandomStorage.setSessionState(req, "123456"); - assertThat(req.getSession().getAttribute("com.auth0.state"), is("123456")); - } - - @Test - public void shouldAcceptBothNullStates() { - MockHttpServletRequest req = new MockHttpServletRequest(); - boolean validState = RandomStorage.checkSessionState(req, null); - assertThat(validState, is(true)); - } - - @Test - public void shouldFailIfSessionStateIsNullButCurrentStateNotNull() { - MockHttpServletRequest req = new MockHttpServletRequest(); - boolean validState = RandomStorage.checkSessionState(req, "12345"); - assertThat(validState, is(false)); - } - - @Test - public void shouldCheckAndRemoveInvalidState() { - MockHttpServletRequest req = new MockHttpServletRequest(); - req.getSession().setAttribute("com.auth0.state", "123456"); - - boolean validState = RandomStorage.checkSessionState(req, "abcdef"); - assertThat(validState, is(false)); - assertThat(req.getSession().getAttribute("com.auth0.state"), is(nullValue())); - } - - @Test - public void shouldCheckAndRemoveCorrectState() { - MockHttpServletRequest req = new MockHttpServletRequest(); - req.getSession().setAttribute("com.auth0.state", "123456"); - - boolean validState = RandomStorage.checkSessionState(req, "123456"); - assertThat(validState, is(true)); - assertThat(req.getSession().getAttribute("com.auth0.state"), is(nullValue())); - } - - @Test - public void shouldSetNonce() { - MockHttpServletRequest req = new MockHttpServletRequest(); - - RandomStorage.setSessionNonce(req, "123456"); - assertThat(req.getSession().getAttribute("com.auth0.nonce"), is("123456")); - } - - @Test - public void shouldGetAndRemoveNonce() { - MockHttpServletRequest req = new MockHttpServletRequest(); - req.getSession().setAttribute("com.auth0.nonce", "123456"); - - String nonce = RandomStorage.removeSessionNonce(req); - assertThat(nonce, is("123456")); - assertThat(req.getSession().getAttribute("com.auth0.nonce"), is(nullValue())); - } - - @Test - public void shouldGetAndRemoveNonceIfMissing() { - MockHttpServletRequest req = new MockHttpServletRequest(); - - String nonce = RandomStorage.removeSessionNonce(req); - assertThat(nonce, is(nullValue())); - assertThat(req.getSession().getAttribute("com.auth0.nonce"), is(nullValue())); - } -} diff --git a/src/test/java/com/auth0/RequestProcessorTest.java b/src/test/java/com/auth0/RequestProcessorTest.java index 0760c06..4556798 100644 --- a/src/test/java/com/auth0/RequestProcessorTest.java +++ b/src/test/java/com/auth0/RequestProcessorTest.java @@ -86,11 +86,11 @@ public void shouldThrowOnProcessIfRequestHasInvalidState() throws Exception { } @Test - public void shouldThrowOnProcessIfRequestHasInvalidStateInSession() throws Exception { + public void shouldThrowOnProcessIfRequestHasInvalidStateInCookie() throws Exception { Map params = new HashMap<>(); params.put("state", "1234"); MockHttpServletRequest request = getRequest(params); - request.getSession().setAttribute("com.auth0.state", "9999"); + request.setCookies(new Cookie("com.auth0.state", "9999")); RequestProcessor handler = new RequestProcessor.Builder(client, "code", verifyOptions) .build(); @@ -121,7 +121,7 @@ public void shouldThrowOnProcessIfRequestHasMissingStateCookie() throws Exceptio .build(); InvalidRequestException e = assertThrows(InvalidRequestException.class, () -> handler.process(request, response)); assertThat(e, InvalidRequestExceptionMatcher.hasCode("a0.invalid_state")); - assertEquals("The received state doesn't match the expected one. No state cookie or state session attribute found. Check that you are using non-deprecated methods and that cookies are not being removed on the server.", e.getMessage()); + assertEquals("The received state doesn't match the expected one. No state cookie found. Check that cookies are not being removed on the server.", e.getMessage()); } @Test @@ -294,7 +294,7 @@ public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerifica } @Test - public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingSessionStorage() throws Exception { + public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingCookieStorage() throws Exception { doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); Map params = new HashMap<>(); @@ -304,7 +304,7 @@ public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerifica params.put("expires_in", "8400"); params.put("token_type", "frontTokenType"); MockHttpServletRequest request = getRequest(params); - request.getSession().setAttribute("com.auth0.state", "1234"); + request.setCookies(new Cookie("com.auth0.state", "1234")); TokenRequest codeExchangeRequest = mock(TokenRequest.class); TokenHolder tokenHolder = mock(TokenHolder.class); @@ -332,45 +332,6 @@ public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerifica assertThat(tokens.getExpiresIn(), is(8400L)); } - @Test - public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerificationWhenUsingSessionStorageWithNullSession() throws Exception { - doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); - - Map params = new HashMap<>(); - params.put("code", "abc123"); - params.put("state", "1234"); - params.put("id_token", "frontIdToken"); - params.put("expires_in", "8400"); - params.put("token_type", "frontTokenType"); - MockHttpServletRequest request = getRequest(params); - request.getSession().setAttribute("com.auth0.state", "1234"); - - TokenRequest codeExchangeRequest = mock(TokenRequest.class); - TokenHolder tokenHolder = mock(TokenHolder.class); - Response tokenResponse = mock(Response.class); - when(tokenHolder.getIdToken()).thenReturn("backIdToken"); - when(tokenHolder.getExpiresIn()).thenReturn(4800L); - when(tokenHolder.getTokenType()).thenReturn("backTokenType"); - when(codeExchangeRequest.execute()).thenReturn(tokenResponse); - when(codeExchangeRequest.execute().getBody()).thenReturn(tokenHolder); - when(client.exchangeCode("abc123", "https://me.auth0.com:80/callback")).thenReturn(codeExchangeRequest); - - RequestProcessor handler = new RequestProcessor.Builder(client, "id_token code", verifyOptions) - .withIdTokenVerifier(tokenVerifier) - .build(); - Tokens tokens = handler.process(request, null); - - //Should not verify the ID Token twice - verify(tokenVerifier).verify("frontIdToken", verifyOptions); - verify(tokenVerifier, never()).verify("backIdToken", verifyOptions); - verifyNoMoreInteractions(tokenVerifier); - - assertThat(tokens, is(notNullValue())); - assertThat(tokens.getIdToken(), is("frontIdToken")); - assertThat(tokens.getType(), is("frontTokenType")); - assertThat(tokens.getExpiresIn(), is(8400L)); - } - @Test public void shouldReturnTokensOnProcessIfTokenIdTokenCodeRequestPassesIdTokenVerification() throws Exception { doNothing().when(tokenVerifier).verify(eq("frontIdToken"), eq(verifyOptions)); diff --git a/src/test/java/com/auth0/SessionUtilsTest.java b/src/test/java/com/auth0/SessionUtilsTest.java deleted file mode 100644 index d7edf62..0000000 --- a/src/test/java/com/auth0/SessionUtilsTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.auth0; - -import org.junit.jupiter.api.Test; -import org.springframework.mock.web.MockHttpServletRequest; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -public class SessionUtilsTest { - @Test - public void shouldGetAndRemoveAttribute() { - MockHttpServletRequest req = new MockHttpServletRequest(); - req.getSession().setAttribute("name", "value"); - - assertThat(SessionUtils.remove(req, "name"), is("value")); - assertThat(req.getSession().getAttribute("name"), is(nullValue())); - } - - @Test - public void shouldGetAttribute() { - MockHttpServletRequest req = new MockHttpServletRequest(); - req.getSession().setAttribute("name", "value"); - - assertThat(SessionUtils.get(req, "name"), is("value")); - assertThat(req.getSession().getAttribute("name"), is("value")); - } - - @Test - public void shouldGetNullAttributeIfMissing() { - MockHttpServletRequest req = new MockHttpServletRequest(); - - assertThat(SessionUtils.get(req, "name"), is(nullValue())); - assertThat(req.getSession().getAttribute("name"), is(nullValue())); - } - - @Test - public void shouldSetAttribute() { - MockHttpServletRequest req = new MockHttpServletRequest(); - - SessionUtils.set(req, "name", "value"); - assertThat(req.getSession().getAttribute("name"), is("value")); - } - -} From f942b84e906d617c3382a3990ccaf67a749857e4 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Wed, 29 Apr 2026 14:37:18 +0530 Subject: [PATCH 12/13] Remove httpServletRequest from AuthorizeUrl class --- src/main/java/com/auth0/AuthorizeUrl.java | 6 +-- src/main/java/com/auth0/RequestProcessor.java | 2 +- src/test/java/com/auth0/AuthorizeUrlTest.java | 54 +++++++++---------- 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/auth0/AuthorizeUrl.java b/src/main/java/com/auth0/AuthorizeUrl.java index a8c6bf9..01dab2a 100644 --- a/src/main/java/com/auth0/AuthorizeUrl.java +++ b/src/main/java/com/auth0/AuthorizeUrl.java @@ -5,7 +5,6 @@ import com.auth0.exception.Auth0Exception; import com.auth0.json.auth.PushedAuthorizationResponse; -import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.util.*; @@ -40,12 +39,11 @@ public class AuthorizeUrl { * with the appropriate SameSite attribute depending on the responseType. * * @param client the Auth0 Authentication API client - * @param request the HTTP request * @param response the response where the state and nonce will be stored as cookies * @param redirectUri the url to redirect to after authentication * @param responseType the response type to use */ - AuthorizeUrl(AuthAPI client, HttpServletRequest request, HttpServletResponse response, String redirectUri, String responseType) { + AuthorizeUrl(AuthAPI client, HttpServletResponse response, String redirectUri, String responseType) { this.response = response; this.responseType = responseType; this.authAPI = client; @@ -107,7 +105,7 @@ public AuthorizeUrl withSecureCookie(boolean secureCookie) { /** * Sets whether a fallback cookie should be used for clients that do not support "SameSite=None". - * Only applicable when this instance is created with {@link AuthorizeUrl#AuthorizeUrl(AuthAPI, HttpServletRequest, HttpServletResponse, String, String)}. + * Only applicable when this instance is created with {@link AuthorizeUrl#AuthorizeUrl(AuthAPI, HttpServletResponse, String, String)}. * * @param useLegacySameSiteCookie whether or not to set fallback auth cookies for clients that do not support "SameSite=None" * @return the builder instance diff --git a/src/main/java/com/auth0/RequestProcessor.java b/src/main/java/com/auth0/RequestProcessor.java index a60324a..8c150ef 100644 --- a/src/main/java/com/auth0/RequestProcessor.java +++ b/src/main/java/com/auth0/RequestProcessor.java @@ -131,7 +131,7 @@ AuthAPI getClient() { AuthorizeUrl buildAuthorizeUrl(HttpServletRequest request, HttpServletResponse response, String redirectUri, String state, String nonce) { - AuthorizeUrl creator = new AuthorizeUrl(client, request, response, redirectUri, responseType) + AuthorizeUrl creator = new AuthorizeUrl(client, response, redirectUri, responseType) .withState(state); if (this.organization != null) { diff --git a/src/test/java/com/auth0/AuthorizeUrlTest.java b/src/test/java/com/auth0/AuthorizeUrlTest.java index f52969a..d8058ec 100644 --- a/src/test/java/com/auth0/AuthorizeUrlTest.java +++ b/src/test/java/com/auth0/AuthorizeUrlTest.java @@ -8,10 +8,8 @@ import okhttp3.HttpUrl; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.util.Collection; @@ -28,18 +26,16 @@ public class AuthorizeUrlTest { private AuthAPI client; private HttpServletResponse response; - private HttpServletRequest request; @BeforeEach public void setUp() { client = AuthAPI.newBuilder("domain.auth0.com", "clientId", "clientSecret").build(); - request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); } @Test public void shouldBuildValidStringUrl() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .build(); assertThat(url, is(notNullValue())); assertThat(HttpUrl.parse(url), is(notNullValue())); @@ -47,28 +43,28 @@ public void shouldBuildValidStringUrl() { @Test public void shouldSetDefaultScope() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .build(); assertThat(HttpUrl.parse(url).queryParameter("scope"), is("openid")); } @Test public void shouldSetResponseType() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .build(); assertThat(HttpUrl.parse(url).queryParameter("response_type"), is("id_token token")); } @Test public void shouldSetRedirectUrl() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .build(); assertThat(HttpUrl.parse(url).queryParameter("redirect_uri"), is("https://redirect.to/me")); } @Test public void shouldSetConnection() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withConnection("facebook") .build(); assertThat(HttpUrl.parse(url).queryParameter("connection"), is("facebook")); @@ -76,7 +72,7 @@ public void shouldSetConnection() { @Test public void shouldSetAudience() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withAudience("https://api.auth0.com/") .build(); assertThat(HttpUrl.parse(url).queryParameter("audience"), is("https://api.auth0.com/")); @@ -84,7 +80,7 @@ public void shouldSetAudience() { @Test public void shouldSetNonceSameSiteAndLegacyCookieByDefault() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withNonce("asdfghjkl") .build(); assertThat(HttpUrl.parse(url).queryParameter("nonce"), is("asdfghjkl")); @@ -97,7 +93,7 @@ public void shouldSetNonceSameSiteAndLegacyCookieByDefault() { @Test public void shouldSetNonceSameSiteAndNotLegacyCookieWhenConfigured() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withNonce("asdfghjkl") .withLegacySameSiteCookie(false) .build(); @@ -110,7 +106,7 @@ public void shouldSetNonceSameSiteAndNotLegacyCookieWhenConfigured() { @Test public void shouldSetStateSameSiteAndLegacyCookieByDefault() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withState("asdfghjkl") .build(); assertThat(HttpUrl.parse(url).queryParameter("state"), is("asdfghjkl")); @@ -123,7 +119,7 @@ public void shouldSetStateSameSiteAndLegacyCookieByDefault() { @Test public void shouldSetStateSameSiteAndNotLegacyCookieWhenConfigured() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withState("asdfghjkl") .withLegacySameSiteCookie(false) .build(); @@ -136,7 +132,7 @@ public void shouldSetStateSameSiteAndNotLegacyCookieWhenConfigured() { @Test public void shouldSetSecureCookieWhenConfiguredTrue() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "code") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "code") .withState("asdfghjkl") .withSecureCookie(true) .build(); @@ -149,7 +145,7 @@ public void shouldSetSecureCookieWhenConfiguredTrue() { @Test public void shouldSetSecureCookieWhenConfiguredFalseAndSameSiteNone() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token") .withState("asdfghjkl") .withSecureCookie(false) .build(); @@ -163,7 +159,7 @@ public void shouldSetSecureCookieWhenConfiguredFalseAndSameSiteNone() { @Test public void shouldSetNoCookiesWhenNonceAndStateNotSet() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .build(); assertThat(HttpUrl.parse(url).queryParameter("state"), nullValue()); assertThat(HttpUrl.parse(url).queryParameter("nonce"), nullValue()); @@ -174,7 +170,7 @@ public void shouldSetNoCookiesWhenNonceAndStateNotSet() { @Test public void shouldSetScope() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withScope("openid profile email") .build(); assertThat(HttpUrl.parse(url).queryParameter("scope"), is("openid profile email")); @@ -182,7 +178,7 @@ public void shouldSetScope() { @Test public void shouldSetCustomParameterScope() { - String url = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + String url = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withParameter("custom", "value") .build(); assertThat(HttpUrl.parse(url).queryParameter("custom"), is("value")); @@ -190,7 +186,7 @@ public void shouldSetCustomParameterScope() { @Test public void shouldThrowWhenReusingTheInstance() { - AuthorizeUrl builder = new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token"); + AuthorizeUrl builder = new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token"); String firstCall = builder.build(); assertThat(firstCall, is(notNullValue())); IllegalStateException e = assertThrows(IllegalStateException.class, builder::build); @@ -201,7 +197,7 @@ public void shouldThrowWhenReusingTheInstance() { public void shouldThrowWhenChangingTheRedirectURI() { IllegalArgumentException e = assertThrows( IllegalArgumentException.class, - () -> new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + () -> new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withParameter("redirect_uri", "new_value")); assertEquals("Redirect URI cannot be changed once set.", e.getMessage()); } @@ -210,7 +206,7 @@ public void shouldThrowWhenChangingTheRedirectURI() { public void shouldThrowWhenChangingTheResponseType() { IllegalArgumentException e = assertThrows( IllegalArgumentException.class, - () -> new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + () -> new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withParameter("response_type", "new_value")); assertEquals("Response type cannot be changed once set.", e.getMessage()); } @@ -219,7 +215,7 @@ public void shouldThrowWhenChangingTheResponseType() { public void shouldThrowWhenChangingTheStateUsingCustomParameterSetter() { IllegalArgumentException e = assertThrows( IllegalArgumentException.class, - () -> new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + () -> new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withParameter("state", "new_value")); assertEquals("Please, use the dedicated methods for setting the 'nonce' and 'state' parameters.", e.getMessage()); } @@ -228,7 +224,7 @@ public void shouldThrowWhenChangingTheStateUsingCustomParameterSetter() { public void shouldThrowWhenChangingTheNonceUsingCustomParameterSetter() { IllegalArgumentException e = assertThrows( IllegalArgumentException.class, - () -> new AuthorizeUrl(client, request, response, "https://redirect.to/me", "id_token token") + () -> new AuthorizeUrl(client, response, "https://redirect.to/me", "id_token token") .withParameter("nonce", "new_value")); assertEquals("Please, use the dedicated methods for setting the 'nonce' and 'state' parameters.", e.getMessage()); } @@ -247,7 +243,7 @@ public void shouldGetAuthorizeUrlFromPAR() throws Exception { when(authAPIMock.authorizeUrlWithPAR("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2")) .thenReturn("https://domain.com/authorize?client_id=clientId&request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2"); - String url = new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code") + String url = new AuthorizeUrl(authAPIMock, response, "https://domain.com/callback", "code") .fromPushedAuthorizationRequest(); assertThat(url, is("https://domain.com/authorize?client_id=clientId&request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2")); @@ -265,7 +261,7 @@ public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsNull() throws Ex .thenReturn(requestMock); InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { - new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code") + new AuthorizeUrl(authAPIMock, response, "https://domain.com/callback", "code") .fromPushedAuthorizationRequest(); }); @@ -284,7 +280,7 @@ public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsEmpty() throws E .thenReturn(requestMock); InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { - new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code") + new AuthorizeUrl(authAPIMock, response, "https://domain.com/callback", "code") .fromPushedAuthorizationRequest(); }); @@ -303,7 +299,7 @@ public void fromPushedAuthorizationRequestThrowsWhenExpiresInIsNull() throws Exc .thenReturn(requestMock); InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { - new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code") + new AuthorizeUrl(authAPIMock, response, "https://domain.com/callback", "code") .fromPushedAuthorizationRequest(); }); @@ -321,7 +317,7 @@ public void fromPushedAuthorizationRequestThrowsWhenRequestThrows() throws Excep .thenReturn(requestMock); InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> { - new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code") + new AuthorizeUrl(authAPIMock, response, "https://domain.com/callback", "code") .fromPushedAuthorizationRequest(); }); From 09d0e80d05b18b99617d48c8c5e1edd4e8e3d664 Mon Sep 17 00:00:00 2001 From: tanya732 Date: Tue, 5 May 2026 08:34:19 +0530 Subject: [PATCH 13/13] Minor modifications --- src/main/java/com/auth0/RequestProcessor.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/auth0/RequestProcessor.java b/src/main/java/com/auth0/RequestProcessor.java index 7ba3f56..0919da6 100644 --- a/src/main/java/com/auth0/RequestProcessor.java +++ b/src/main/java/com/auth0/RequestProcessor.java @@ -233,9 +233,6 @@ Tokens process(HttpServletRequest request, HttpServletResponse response) throws throw new InvalidRequestException(MISSING_ACCESS_TOKEN, "Access Token is missing from the response."); } - // Nonce dynamically set and changes on every request. - String nonce = TransientCookieStore.getNonce(request, response); - return getVerifiedTokens(request, response, frontChannelTokens, responseTypeList, originDomain, originIssuer); }