From 4cf235c40de35aa31ee2f70527884b92badb4d3b Mon Sep 17 00:00:00 2001 From: Jim Anderson Date: Tue, 12 Dec 2023 14:39:34 -0600 Subject: [PATCH] tests for state validation --- .../java/com/auth0/RequestProcessorTest.java | 78 ++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/auth0/RequestProcessorTest.java b/src/test/java/com/auth0/RequestProcessorTest.java index aa6641c..7ffcf60 100644 --- a/src/test/java/com/auth0/RequestProcessorTest.java +++ b/src/test/java/com/auth0/RequestProcessorTest.java @@ -107,7 +107,7 @@ public void shouldThrowOnProcessIfRequestHasMissingStateParameter() throws Excep .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.", e.getMessage()); + assertEquals("The received state doesn't match the expected one. No state parameter was found on the authorization response.", e.getMessage()); } @Test @@ -120,7 +120,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.", e.getMessage()); + 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()); } @Test @@ -288,6 +288,80 @@ public void shouldReturnTokensOnProcessIfIdTokenCodeRequestPassesIdTokenVerifica 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));