@Parameters({"redirectUris", "sectorIdentifierUri", "redirectUri", "userId", "userSecret"})
  @Test // This test requires a place to publish a sector identifier JSON array of redirect URIs via
        // HTTPS
  public void requestAuthorizationCodeWithSectorIdentifier(
      final String redirectUris,
      final String sectorIdentifierUri,
      final String redirectUri,
      final String userId,
      final String userSecret)
      throws Exception {
    showTitle("requestAuthorizationCodeWithSectorIdentifier");

    List<ResponseType> responseTypes = Arrays.asList(ResponseType.CODE, ResponseType.ID_TOKEN);

    // 1. Register client with Sector Identifier URL
    RegisterRequest registerRequest =
        new RegisterRequest(
            ApplicationType.WEB, "oxAuth test app", StringUtils.spaceSeparatedToList(redirectUris));
    registerRequest.addCustomAttribute("oxAuthTrustedClient", "true");
    registerRequest.setResponseTypes(responseTypes);
    registerRequest.setSubjectType(SubjectType.PAIRWISE);
    registerRequest.setSectorIdentifierUri(sectorIdentifierUri);
    registerRequest.setTokenEndpointAuthMethod(AuthenticationMethod.CLIENT_SECRET_POST);

    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.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);
    authorizationRequest.setAuthUsername(userId);
    authorizationRequest.setAuthPassword(userSecret);
    authorizationRequest.getPrompts().add(Prompt.NONE);

    AuthorizeClient authorizeClient = new AuthorizeClient(authorizationEndpoint);
    authorizeClient.setRequest(authorizationRequest);
    AuthorizationResponse authorizationResponse = authorizeClient.exec();

    showClient(authorizeClient);
    assertEquals(
        authorizationResponse.getStatus(),
        302,
        "Unexpected response code: " + authorizationResponse.getStatus());
    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");
    assertEquals(authorizationResponse.getState(), state);

    String authorizationCode = authorizationResponse.getCode();
    String idToken = authorizationResponse.getIdToken();

    // 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.SUBJECT_IDENTIFIER));
    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));

    // 4. 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_POST);

    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.getExpiresIn(), "The expires in value 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(JwtClaimName.GIVEN_NAME));
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.FAMILY_NAME));
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.EMAIL));
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.ZONEINFO));
    assertNotNull(userInfoResponse.getClaim(JwtClaimName.LOCALE));
  }