/* * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. * * Copyright (c) 2014, Gluu */ package org.xdi.oxauth.ws.rs; import org.testng.annotations.Parameters; import org.testng.annotations.Test; import org.xdi.oxauth.BaseTest; import org.xdi.oxauth.client.*; import org.xdi.oxauth.model.common.AuthenticationMethod; import org.xdi.oxauth.model.common.GrantType; import org.xdi.oxauth.model.common.ResponseType; import org.xdi.oxauth.model.common.SubjectType; import org.xdi.oxauth.model.crypto.signature.RSAPublicKey; import org.xdi.oxauth.model.crypto.signature.SignatureAlgorithm; import org.xdi.oxauth.model.jws.RSASigner; import org.xdi.oxauth.model.jwt.Jwt; import org.xdi.oxauth.model.jwt.JwtClaimName; import org.xdi.oxauth.model.jwt.JwtHeaderName; import org.xdi.oxauth.model.register.ApplicationType; import org.xdi.oxauth.model.util.StringUtils; import java.util.Arrays; import java.util.List; import java.util.UUID; import static org.testng.Assert.*; import static org.xdi.oxauth.model.register.RegisterRequestParam.*; /** * Test cases for the authorization code flow (HTTP) * * @author Javier Rojas Blum * @version May 19, 2017 */ public class AuthorizationCodeFlowHttpTest extends BaseTest { /** * Test for the complete Authorization Code Flow. */ @Parameters({"userId", "userSecret", "redirectUris", "redirectUri", "sectorIdentifierUri"}) @Test public void authorizationCodeFlow( final String userId, final String userSecret, final String redirectUris, final String redirectUri, final String sectorIdentifierUri) throws Exception { showTitle("authorizationCodeFlow"); List<ResponseType> responseTypes = Arrays.asList( ResponseType.CODE, ResponseType.ID_TOKEN); List<String> scopes = Arrays.asList("openid", "profile", "address", "email", "user_name"); // 1. Register client RegisterResponse registerResponse = registerClient(redirectUris, responseTypes, scopes, sectorIdentifierUri); String clientId = registerResponse.getClientId(); String clientSecret = registerResponse.getClientSecret(); // 2. Request authorization and receive the authorization code. String nonce = UUID.randomUUID().toString(); AuthorizationResponse authorizationResponse = requestAuthorization(userId, userSecret, redirectUri, responseTypes, scopes, clientId, nonce); String scope = authorizationResponse.getScope(); String authorizationCode = authorizationResponse.getCode(); String idToken = authorizationResponse.getIdToken(); // 3. Request access token using the authorization code. TokenRequest tokenRequest = new TokenRequest(GrantType.AUTHORIZATION_CODE); tokenRequest.setCode(authorizationCode); tokenRequest.setRedirectUri(redirectUri); tokenRequest.setAuthUsername(clientId); tokenRequest.setAuthPassword(clientSecret); tokenRequest.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_BASIC); TokenClient tokenClient1 = new TokenClient(tokenEndpoint); tokenClient1.setRequest(tokenRequest); TokenResponse tokenResponse1 = tokenClient1.exec(); showClient(tokenClient1); assertEquals(tokenResponse1.getStatus(), 200, "Unexpected response code: " + tokenResponse1.getStatus()); assertNotNull(tokenResponse1.getEntity(), "The entity is null"); assertNotNull(tokenResponse1.getAccessToken(), "The access token is null"); assertNotNull(tokenResponse1.getExpiresIn(), "The expires in value is null"); assertNotNull(tokenResponse1.getTokenType(), "The token type is null"); assertNotNull(tokenResponse1.getRefreshToken(), "The refresh token is null"); String refreshToken = tokenResponse1.getRefreshToken(); // 4. Validate id_token Jwt jwt = Jwt.parse(idToken); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.TYPE)); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.ALGORITHM)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUDIENCE)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.EXPIRATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUED_AT)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.CODE_HASH)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUTHENTICATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.OX_OPENID_CONNECT_VERSION)); RSAPublicKey publicKey = JwkClient.getRSAPublicKey( jwksUri, jwt.getHeader().getClaimAsString(JwtHeaderName.KEY_ID)); RSASigner rsaSigner = new RSASigner(SignatureAlgorithm.RS256, publicKey); assertTrue(rsaSigner.validate(jwt)); // 5. Request new access token using the refresh token. TokenClient tokenClient2 = new TokenClient(tokenEndpoint); TokenResponse tokenResponse2 = tokenClient2.execRefreshToken(scope, refreshToken, clientId, clientSecret); showClient(tokenClient2); assertEquals(tokenResponse2.getStatus(), 200, "Unexpected response code: " + tokenResponse2.getStatus()); assertNotNull(tokenResponse2.getEntity(), "The entity is null"); assertNotNull(tokenResponse2.getAccessToken(), "The access token is null"); assertNotNull(tokenResponse2.getTokenType(), "The token type is null"); assertNotNull(tokenResponse2.getRefreshToken(), "The refresh token is null"); assertNotNull(tokenResponse2.getScope(), "The scope is null"); String accessToken = tokenResponse2.getAccessToken(); // 6. Request user info UserInfoClient userInfoClient = new UserInfoClient(userInfoEndpoint); UserInfoResponse userInfoResponse = userInfoClient.execUserInfo(accessToken); showClient(userInfoClient); assertEquals(userInfoResponse.getStatus(), 200, "Unexpected response code: " + userInfoResponse.getStatus()); assertNotNull(userInfoResponse.getClaim(JwtClaimName.SUBJECT_IDENTIFIER)); assertNotNull(userInfoResponse.getClaim(JwtClaimName.NAME)); assertNotNull(userInfoResponse.getClaim("user_name")); assertNull(userInfoResponse.getClaim("org_name")); assertNull(userInfoResponse.getClaim("work_phone")); } @Parameters({"userId", "userSecret", "redirectUris", "redirectUri", "sectorIdentifierUri"}) @Test public void authorizationCodeWithNotAllowedScopeFlow( final String userId, final String userSecret, final String redirectUris, final String redirectUri, final String sectorIdentifierUri) throws Exception { showTitle("authorizationCodeWithNotAllowedScopeFlow"); List<ResponseType> responseTypes = Arrays.asList( ResponseType.CODE, ResponseType.ID_TOKEN); List<String> scopes = Arrays.asList("openid", "profile", "address", "email", "user_name"); // 1. Register client RegisterResponse registerResponse = registerClient(redirectUris, responseTypes, scopes, sectorIdentifierUri); String clientId = registerResponse.getClientId(); String clientSecret = registerResponse.getClientSecret(); // 2. Request authorization and receive the authorization code. List<String> authorizationScopes = Arrays.asList("openid", "profile", "address", "email", "user_name", "mobile_phone"); String nonce = UUID.randomUUID().toString(); AuthorizationResponse authorizationResponse = requestAuthorization(userId, userSecret, redirectUri, responseTypes, authorizationScopes, clientId, nonce); String idToken = authorizationResponse.getIdToken(); String authorizationCode = authorizationResponse.getCode(); // 3. Validate id_token Jwt jwt = Jwt.parse(idToken); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.TYPE)); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.ALGORITHM)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUDIENCE)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.EXPIRATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUED_AT)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.CODE_HASH)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUTHENTICATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.OX_OPENID_CONNECT_VERSION)); // 4. Request access token TokenRequest tokenRequest = new TokenRequest(GrantType.AUTHORIZATION_CODE); tokenRequest.setCode(authorizationCode); tokenRequest.setRedirectUri(redirectUri); tokenRequest.setAuthUsername(clientId); tokenRequest.setAuthPassword(clientSecret); tokenRequest.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_BASIC); TokenClient tokenClient = new TokenClient(tokenEndpoint); tokenClient.setRequest(tokenRequest); TokenResponse tokenResponse = tokenClient.exec(); showClient(tokenClient); assertEquals(tokenResponse.getStatus(), 200, "Unexpected response code: " + tokenResponse.getStatus()); assertNotNull(tokenResponse.getEntity(), "The entity is null"); assertNotNull(tokenResponse.getAccessToken(), "The access token is null"); assertNotNull(tokenResponse.getTokenType(), "The token type is null"); assertNotNull(tokenResponse.getRefreshToken(), "The refresh token is null"); String accessToken = tokenResponse.getAccessToken(); // 5. Request user info UserInfoClient userInfoClient = new UserInfoClient(userInfoEndpoint); UserInfoResponse userInfoResponse = userInfoClient.execUserInfo(accessToken); showClient(userInfoClient); assertEquals(userInfoResponse.getStatus(), 200, "Unexpected response code: " + userInfoResponse.getStatus()); assertNotNull(userInfoResponse.getClaim(JwtClaimName.SUBJECT_IDENTIFIER)); assertNotNull(userInfoResponse.getClaim(JwtClaimName.NAME)); assertNotNull(userInfoResponse.getClaim("user_name")); assertNull(userInfoResponse.getClaim("phone_mobile_number")); } @Parameters({"userId", "userSecret", "redirectUris", "redirectUri", "sectorIdentifierUri"}) @Test public void authorizationCodeDynamicScopeFlow( final String userId, final String userSecret, final String redirectUris, final String redirectUri, final String sectorIdentifierUri) throws Exception { showTitle("authorizationCodeDynamicScopeFlow"); List<ResponseType> responseTypes = Arrays.asList( ResponseType.CODE, ResponseType.ID_TOKEN); List<String> scopes = Arrays.asList("openid", "profile", "address", "email", "user_name", "org_name", "work_phone"); // 1. Register client RegisterResponse registerResponse = registerClient(redirectUris, responseTypes, scopes, sectorIdentifierUri); String clientId = registerResponse.getClientId(); String clientSecret = registerResponse.getClientSecret(); // 2. Request authorization and receive the authorization code. String nonce = UUID.randomUUID().toString(); AuthorizationResponse authorizationResponse = requestAuthorization(userId, userSecret, redirectUri, responseTypes, scopes, clientId, nonce); String idToken = authorizationResponse.getIdToken(); String authorizationCode = authorizationResponse.getCode(); // 3. Validate id_token Jwt jwt = Jwt.parse(idToken); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.TYPE)); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.ALGORITHM)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUDIENCE)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.EXPIRATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUED_AT)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.CODE_HASH)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUTHENTICATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.OX_OPENID_CONNECT_VERSION)); // 4. Request access token TokenRequest tokenRequest = new TokenRequest(GrantType.AUTHORIZATION_CODE); tokenRequest.setCode(authorizationCode); tokenRequest.setRedirectUri(redirectUri); tokenRequest.setAuthUsername(clientId); tokenRequest.setAuthPassword(clientSecret); tokenRequest.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_BASIC); TokenClient tokenClient = new TokenClient(tokenEndpoint); tokenClient.setRequest(tokenRequest); TokenResponse tokenResponse = tokenClient.exec(); showClient(tokenClient); assertEquals(tokenResponse.getStatus(), 200, "Unexpected response code: " + tokenResponse.getStatus()); assertNotNull(tokenResponse.getEntity(), "The entity is null"); assertNotNull(tokenResponse.getAccessToken(), "The access token is null"); assertNotNull(tokenResponse.getTokenType(), "The token type is null"); assertNotNull(tokenResponse.getRefreshToken(), "The refresh token is null"); String accessToken = tokenResponse.getAccessToken(); // 5. Request user info UserInfoClient userInfoClient = new UserInfoClient(userInfoEndpoint); UserInfoResponse userInfoResponse = userInfoClient.execUserInfo(accessToken); showClient(userInfoClient); assertEquals(userInfoResponse.getStatus(), 200, "Unexpected response code: " + userInfoResponse.getStatus()); assertNotNull(userInfoResponse.getClaim(JwtClaimName.SUBJECT_IDENTIFIER)); assertNotNull(userInfoResponse.getClaim(JwtClaimName.NAME)); assertNotNull(userInfoResponse.getClaim("user_name")); assertNotNull(userInfoResponse.getClaim("org_name")); assertNotNull(userInfoResponse.getClaim("work_phone")); } @Parameters({"userId", "userSecret", "redirectUris", "redirectUri", "sectorIdentifierUri"}) @Test public void authorizationCodeFlowWithOptionalNonce( final String userId, final String userSecret, final String redirectUris, final String redirectUri, final String sectorIdentifierUri) throws Exception { showTitle("authorizationCodeFlowWithOptionalNonce"); List<ResponseType> responseTypes = Arrays.asList( ResponseType.CODE, ResponseType.ID_TOKEN); // 1. Register client RegisterRequest registerRequest = new RegisterRequest(ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris)); registerRequest.setResponseTypes(responseTypes); registerRequest.setSectorIdentifierUri(sectorIdentifierUri); RegisterClient registerClient = new RegisterClient(registrationEndpoint); registerClient.setRequest(registerRequest); RegisterResponse registerResponse = registerClient.exec(); showClient(registerClient); assertEquals(registerResponse.getStatus(), 200, "Unexpected response code: " + registerResponse.getEntity()); assertNotNull(registerResponse.getClientId()); assertNotNull(registerResponse.getClientSecret()); assertNotNull(registerResponse.getRegistrationAccessToken()); assertNotNull(registerResponse.getClientIdIssuedAt()); assertNotNull(registerResponse.getClientSecretExpiresAt()); String clientId = registerResponse.getClientId(); String clientSecret = registerResponse.getClientSecret(); // 2. Request authorization and receive the authorization code. List<String> scopes = Arrays.asList("openid", "profile", "address", "email"); String state = UUID.randomUUID().toString(); String nonce = UUID.randomUUID().toString(); AuthorizationRequest authorizationRequest = new AuthorizationRequest(responseTypes, clientId, scopes, redirectUri, nonce); authorizationRequest.setState(state); AuthorizationResponse authorizationResponse = authenticateResourceOwnerAndGrantAccess( authorizationEndpoint, authorizationRequest, userId, userSecret); assertNotNull(authorizationResponse.getLocation(), "The location is null"); assertNotNull(authorizationResponse.getCode(), "The authorization code is null"); assertNotNull(authorizationResponse.getState(), "The state is null"); assertNotNull(authorizationResponse.getScope(), "The scope is null"); String scope = authorizationResponse.getScope(); String authorizationCode = authorizationResponse.getCode(); String idToken = authorizationResponse.getIdToken(); // 3. Request access token using the authorization code. TokenRequest tokenRequest = new TokenRequest(GrantType.AUTHORIZATION_CODE); tokenRequest.setCode(authorizationCode); tokenRequest.setRedirectUri(redirectUri); tokenRequest.setAuthUsername(clientId); tokenRequest.setAuthPassword(clientSecret); tokenRequest.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_BASIC); TokenClient tokenClient1 = new TokenClient(tokenEndpoint); tokenClient1.setRequest(tokenRequest); TokenResponse tokenResponse1 = tokenClient1.exec(); showClient(tokenClient1); assertEquals(tokenResponse1.getStatus(), 200, "Unexpected response code: " + tokenResponse1.getStatus()); assertNotNull(tokenResponse1.getEntity(), "The entity is null"); assertNotNull(tokenResponse1.getAccessToken(), "The access token is null"); assertNotNull(tokenResponse1.getExpiresIn(), "The expires in value is null"); assertNotNull(tokenResponse1.getTokenType(), "The token type is null"); assertNotNull(tokenResponse1.getRefreshToken(), "The refresh token is null"); String refreshToken = tokenResponse1.getRefreshToken(); // 4. Validate id_token Jwt jwt = Jwt.parse(idToken); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.NONCE)); assertEquals(jwt.getClaims().getClaimAsString(JwtClaimName.NONCE), nonce); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.TYPE)); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.ALGORITHM)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUDIENCE)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.EXPIRATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUED_AT)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.CODE_HASH)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUTHENTICATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.OX_OPENID_CONNECT_VERSION)); RSAPublicKey publicKey = JwkClient.getRSAPublicKey( jwksUri, jwt.getHeader().getClaimAsString(JwtHeaderName.KEY_ID)); RSASigner rsaSigner = new RSASigner(SignatureAlgorithm.RS256, publicKey); assertTrue(rsaSigner.validate(jwt)); // 5. Request new access token using the refresh token. TokenClient tokenClient2 = new TokenClient(tokenEndpoint); TokenResponse tokenResponse2 = tokenClient2.execRefreshToken(scope, refreshToken, clientId, clientSecret); showClient(tokenClient2); assertEquals(tokenResponse2.getStatus(), 200, "Unexpected response code: " + tokenResponse2.getStatus()); assertNotNull(tokenResponse2.getEntity(), "The entity is null"); assertNotNull(tokenResponse2.getAccessToken(), "The access token is null"); assertNotNull(tokenResponse2.getTokenType(), "The token type is null"); assertNotNull(tokenResponse2.getRefreshToken(), "The refresh token is null"); assertNotNull(tokenResponse2.getScope(), "The scope is null"); } /** * When an authorization code is used more than once, all the tokens issued * for that authorization code must be revoked. */ @Parameters({"userId", "userSecret", "redirectUris", "redirectUri", "sectorIdentifierUri"}) @Test public void revokeTokens(final String userId, final String userSecret, final String redirectUris, final String redirectUri, final String sectorIdentifierUri) throws Exception { showTitle("revokeTokens"); List<ResponseType> responseTypes = Arrays.asList( ResponseType.CODE, ResponseType.ID_TOKEN); // 1. Register client RegisterRequest registerRequest = new RegisterRequest(ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris)); registerRequest.setResponseTypes(responseTypes); registerRequest.setSectorIdentifierUri(sectorIdentifierUri); RegisterClient registerClient = new RegisterClient(registrationEndpoint); registerClient.setRequest(registerRequest); RegisterResponse registerResponse = registerClient.exec(); showClient(registerClient); assertEquals(registerResponse.getStatus(), 200, "Unexpected response code: " + registerResponse.getEntity()); assertNotNull(registerResponse.getClientId()); assertNotNull(registerResponse.getClientSecret()); assertNotNull(registerResponse.getRegistrationAccessToken()); assertNotNull(registerResponse.getClientIdIssuedAt()); assertNotNull(registerResponse.getClientSecretExpiresAt()); String clientId = registerResponse.getClientId(); String clientSecret = registerResponse.getClientSecret(); String registrationAccessToken = registerResponse.getRegistrationAccessToken(); String registrationClientUri = registerResponse.getRegistrationClientUri(); // 2. Client read RegisterRequest readClientRequest = new RegisterRequest(registrationAccessToken); RegisterClient readClient = new RegisterClient(registrationClientUri); readClient.setRequest(readClientRequest); RegisterResponse readClientResponse = readClient.exec(); showClient(readClient); assertEquals(readClientResponse.getStatus(), 200, "Unexpected response code: " + readClientResponse.getEntity()); assertNotNull(readClientResponse.getClientId()); assertNotNull(readClientResponse.getClientSecret()); assertNotNull(readClientResponse.getClientIdIssuedAt()); assertNotNull(readClientResponse.getClientSecretExpiresAt()); assertNotNull(readClientResponse.getClaims().get(RESPONSE_TYPES.toString())); assertNotNull(readClientResponse.getClaims().get(REDIRECT_URIS.toString())); assertNotNull(readClientResponse.getClaims().get(APPLICATION_TYPE.toString())); assertNotNull(readClientResponse.getClaims().get(CLIENT_NAME.toString())); assertNotNull(readClientResponse.getClaims().get(ID_TOKEN_SIGNED_RESPONSE_ALG.toString())); assertNotNull(readClientResponse.getClaims().get("scopes")); // 3. Request authorization and receive the authorization code. List<String> scopes = Arrays.asList("openid", "profile", "address", "email"); String state = UUID.randomUUID().toString(); String nonce = UUID.randomUUID().toString(); AuthorizationRequest authorizationRequest = new AuthorizationRequest(responseTypes, clientId, scopes, redirectUri, nonce); authorizationRequest.setState(state); AuthorizationResponse authorizationResponse = authenticateResourceOwnerAndGrantAccess( authorizationEndpoint, authorizationRequest, userId, userSecret); assertNotNull(authorizationResponse.getLocation(), "The location is null"); assertNotNull(authorizationResponse.getCode(), "The authorization code is null"); assertNotNull(authorizationResponse.getState(), "The state is null"); assertNotNull(authorizationResponse.getScope(), "The scope is null"); assertNotNull(authorizationResponse.getIdToken(), "The id token is null"); String scope = authorizationResponse.getScope(); String authorizationCode = authorizationResponse.getCode(); String idToken = authorizationResponse.getIdToken(); // 4. Validate id_token Jwt jwt = Jwt.parse(idToken); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.TYPE)); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.ALGORITHM)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUDIENCE)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.EXPIRATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUED_AT)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.CODE_HASH)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUTHENTICATION_TIME)); RSAPublicKey publicKey = JwkClient.getRSAPublicKey( jwksUri, jwt.getHeader().getClaimAsString(JwtHeaderName.KEY_ID)); RSASigner rsaSigner = new RSASigner(SignatureAlgorithm.RS256, publicKey); assertTrue(rsaSigner.validate(jwt)); // 5. Request access token using the authorization code. TokenClient tokenClient1 = new TokenClient(tokenEndpoint); TokenResponse response2 = tokenClient1.execAuthorizationCode(authorizationCode, redirectUri, clientId, clientSecret); showClient(tokenClient1); assertEquals(response2.getStatus(), 200, "Unexpected response code: " + response2.getStatus()); assertNotNull(response2.getEntity(), "The entity is null"); assertNotNull(response2.getAccessToken(), "The access token is null"); assertNotNull(response2.getTokenType(), "The token type is null"); assertNotNull(response2.getRefreshToken(), "The refresh token is null"); String accessToken = response2.getAccessToken(); String refreshToken = response2.getRefreshToken(); // 6. Request access token using the same authorization code one more time. This call must fail. TokenClient tokenClient2 = new TokenClient(tokenEndpoint); TokenResponse response4 = tokenClient2.execAuthorizationCode(authorizationCode, redirectUri, clientId, clientSecret); showClient(tokenClient2); assertEquals(response4.getStatus(), 400, "Unexpected response code: " + response4.getStatus()); assertNotNull(response4.getEntity(), "The entity is null"); assertNotNull(response4.getErrorType(), "The error type is null"); assertNotNull(response4.getErrorDescription(), "The error description is null"); // 7. Request new access token using the refresh token. This call must fail too. TokenClient tokenClient3 = new TokenClient(tokenEndpoint); TokenResponse response5 = tokenClient3.execRefreshToken(scope, refreshToken, clientId, clientSecret); showClient(tokenClient3); assertEquals(response5.getStatus(), 401, "Unexpected response code: " + response5.getStatus()); assertNotNull(response5.getEntity(), "The entity is null"); assertNotNull(response5.getErrorType(), "The error type is null"); assertNotNull(response5.getErrorDescription(), "The error description is null"); // 8. Request user info should fail UserInfoClient userInfoClient = new UserInfoClient(userInfoEndpoint); UserInfoResponse response7 = userInfoClient.execUserInfo(accessToken); showClient(userInfoClient); assertEquals(response7.getStatus(), 400, "Unexpected response code: " + response7.getStatus()); assertNotNull(response7.getErrorType(), "Unexpected result: errorType not found"); assertNotNull(response7.getErrorDescription(), "Unexpected result: errorDescription not found"); } @Parameters({"userId", "userSecret", "redirectUris", "redirectUri", "sectorIdentifierUri"}) @Test public void authorizationCodeFlowLoginHint( final String userId, final String userSecret, final String redirectUris, final String redirectUri, final String sectorIdentifierUri) throws Exception { showTitle("authorizationCodeFlowLoginHint"); List<ResponseType> responseTypes = Arrays.asList( ResponseType.CODE, ResponseType.ID_TOKEN); List<String> scopes = Arrays.asList("openid", "profile", "address", "email", "user_name"); // 1. Register client RegisterResponse registerResponse = registerClient(redirectUris, responseTypes, scopes, sectorIdentifierUri); String clientId = registerResponse.getClientId(); String clientSecret = registerResponse.getClientSecret(); // 2. Request authorization and receive the authorization code. String nonce = UUID.randomUUID().toString(); String state = UUID.randomUUID().toString(); AuthorizationRequest authorizationRequest = new AuthorizationRequest(responseTypes, clientId, scopes, redirectUri, nonce); authorizationRequest.setLoginHint(userId); authorizationRequest.setState(state); AuthorizationResponse authorizationResponse = authenticateResourceOwnerAndGrantAccess( authorizationEndpoint, authorizationRequest, null, userSecret); assertNotNull(authorizationResponse.getLocation(), "The location is null"); assertNotNull(authorizationResponse.getCode(), "The authorization code is null"); assertNotNull(authorizationResponse.getState(), "The state is null"); assertNotNull(authorizationResponse.getScope(), "The scope is null"); String scope = authorizationResponse.getScope(); String authorizationCode = authorizationResponse.getCode(); String idToken = authorizationResponse.getIdToken(); // 3. Request access token using the authorization code. TokenRequest tokenRequest = new TokenRequest(GrantType.AUTHORIZATION_CODE); tokenRequest.setCode(authorizationCode); tokenRequest.setRedirectUri(redirectUri); tokenRequest.setAuthUsername(clientId); tokenRequest.setAuthPassword(clientSecret); tokenRequest.setAuthenticationMethod(AuthenticationMethod.CLIENT_SECRET_BASIC); TokenClient tokenClient1 = new TokenClient(tokenEndpoint); tokenClient1.setRequest(tokenRequest); TokenResponse tokenResponse1 = tokenClient1.exec(); showClient(tokenClient1); assertEquals(tokenResponse1.getStatus(), 200, "Unexpected response code: " + tokenResponse1.getStatus()); assertNotNull(tokenResponse1.getEntity(), "The entity is null"); assertNotNull(tokenResponse1.getAccessToken(), "The access token is null"); assertNotNull(tokenResponse1.getExpiresIn(), "The expires in value is null"); assertNotNull(tokenResponse1.getTokenType(), "The token type is null"); assertNotNull(tokenResponse1.getRefreshToken(), "The refresh token is null"); String refreshToken = tokenResponse1.getRefreshToken(); // 4. Validate id_token Jwt jwt = Jwt.parse(idToken); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.TYPE)); assertNotNull(jwt.getHeader().getClaimAsString(JwtHeaderName.ALGORITHM)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUDIENCE)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.EXPIRATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.ISSUED_AT)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.CODE_HASH)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.AUTHENTICATION_TIME)); assertNotNull(jwt.getClaims().getClaimAsString(JwtClaimName.OX_OPENID_CONNECT_VERSION)); RSAPublicKey publicKey = JwkClient.getRSAPublicKey( jwksUri, jwt.getHeader().getClaimAsString(JwtHeaderName.KEY_ID)); RSASigner rsaSigner = new RSASigner(SignatureAlgorithm.RS256, publicKey); assertTrue(rsaSigner.validate(jwt)); // 5. Request new access token using the refresh token. TokenClient tokenClient2 = new TokenClient(tokenEndpoint); TokenResponse tokenResponse2 = tokenClient2.execRefreshToken(scope, refreshToken, clientId, clientSecret); showClient(tokenClient2); assertEquals(tokenResponse2.getStatus(), 200, "Unexpected response code: " + tokenResponse2.getStatus()); assertNotNull(tokenResponse2.getEntity(), "The entity is null"); assertNotNull(tokenResponse2.getAccessToken(), "The access token is null"); assertNotNull(tokenResponse2.getTokenType(), "The token type is null"); assertNotNull(tokenResponse2.getRefreshToken(), "The refresh token is null"); assertNotNull(tokenResponse2.getScope(), "The scope is null"); String accessToken = tokenResponse2.getAccessToken(); // 6. Request user info UserInfoClient userInfoClient = new UserInfoClient(userInfoEndpoint); UserInfoResponse userInfoResponse = userInfoClient.execUserInfo(accessToken); showClient(userInfoClient); assertEquals(userInfoResponse.getStatus(), 200, "Unexpected response code: " + userInfoResponse.getStatus()); assertNotNull(userInfoResponse.getClaim(JwtClaimName.SUBJECT_IDENTIFIER)); assertNotNull(userInfoResponse.getClaim(JwtClaimName.NAME)); assertNotNull(userInfoResponse.getClaim("user_name")); assertNull(userInfoResponse.getClaim("org_name")); assertNull(userInfoResponse.getClaim("work_phone")); } private AuthorizationResponse requestAuthorization(final String userId, final String userSecret, final String redirectUri, List<ResponseType> responseTypes, List<String> scopes, String clientId, String nonce) { String state = UUID.randomUUID().toString(); AuthorizationRequest authorizationRequest = new AuthorizationRequest(responseTypes, clientId, scopes, redirectUri, nonce); authorizationRequest.setState(state); AuthorizationResponse authorizationResponse = authenticateResourceOwnerAndGrantAccess( authorizationEndpoint, authorizationRequest, userId, userSecret); assertNotNull(authorizationResponse.getLocation(), "The location is null"); assertNotNull(authorizationResponse.getCode(), "The authorization code is null"); assertNotNull(authorizationResponse.getState(), "The state is null"); assertNotNull(authorizationResponse.getScope(), "The scope is null"); return authorizationResponse; } private RegisterResponse registerClient( final String redirectUris, List<ResponseType> responseTypes, List<String> scopes, String sectorIdentifierUri) { RegisterRequest registerRequest = new RegisterRequest(ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris)); registerRequest.setResponseTypes(responseTypes); registerRequest.setScopes(scopes); registerRequest.setSubjectType(SubjectType.PAIRWISE); registerRequest.setSectorIdentifierUri(sectorIdentifierUri); RegisterClient registerClient = new RegisterClient(registrationEndpoint); registerClient.setRequest(registerRequest); RegisterResponse registerResponse = registerClient.exec(); showClient(registerClient); assertEquals(registerResponse.getStatus(), 200, "Unexpected response code: " + registerResponse.getEntity()); assertNotNull(registerResponse.getClientId()); assertNotNull(registerResponse.getClientSecret()); assertNotNull(registerResponse.getRegistrationAccessToken()); assertNotNull(registerResponse.getClientIdIssuedAt()); assertNotNull(registerResponse.getClientSecretExpiresAt()); return registerResponse; } }