Search in sources :

Example 1 with ClientType

use of com.nimbusds.oauth2.sdk.client.ClientType in project di-authentication-api by alphagov.

the class StartServiceTest method buildUserContext.

private UserContext buildUserContext(String vtrValue, boolean consentRequired, boolean cookieConsentShared, ClientType clientType, SignedJWT requestObject, boolean identityVerificationSupport, boolean isAuthenticated) {
    AuthorizationRequest authRequest;
    var clientSessionVTR = VectorOfTrust.getDefaults();
    if (Objects.nonNull(requestObject)) {
        authRequest = new AuthorizationRequest.Builder(new ResponseType(ResponseType.Value.CODE), CLIENT_ID).requestObject(requestObject).build();
    } else {
        clientSessionVTR = VectorOfTrust.parseFromAuthRequestAttribute(Collections.singletonList(vtrValue));
        authRequest = new AuthenticationRequest.Builder(new ResponseType(ResponseType.Value.CODE), SCOPES, CLIENT_ID, REDIRECT_URI).state(new State()).nonce(new Nonce()).customParameter("vtr", vtrValue).build();
    }
    var clientSession = new ClientSession(authRequest.toParameters(), LocalDateTime.now(), clientSessionVTR);
    var clientRegistry = new ClientRegistry().setClientID(CLIENT_ID.getValue()).setClientName(CLIENT_NAME).setConsentRequired(consentRequired).setCookieConsentShared(cookieConsentShared).setClientType(clientType.getValue()).setIdentityVerificationSupported(identityVerificationSupport);
    return UserContext.builder(SESSION.setAuthenticated(isAuthenticated)).withClientSession(clientSession).withClient(clientRegistry).build();
}
Also used : Nonce(com.nimbusds.openid.connect.sdk.Nonce) AuthorizationRequest(com.nimbusds.oauth2.sdk.AuthorizationRequest) State(com.nimbusds.oauth2.sdk.id.State) ClientSession(uk.gov.di.authentication.shared.entity.ClientSession) ClientRegistry(uk.gov.di.authentication.shared.entity.ClientRegistry) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest) ResponseType(com.nimbusds.oauth2.sdk.ResponseType)

Example 2 with ClientType

use of com.nimbusds.oauth2.sdk.client.ClientType in project di-authentication-api by alphagov.

the class ClientRegistrationHandlerTest method shouldReturnExpectedClientTypeInResponse.

@ParameterizedTest
@MethodSource("clientTypes")
void shouldReturnExpectedClientTypeInResponse(String clientType) throws Json.JsonException {
    when(configValidationService.validateClientRegistrationConfig(any(ClientRegistrationRequest.class))).thenReturn(Optional.empty());
    when(clientService.generateClientID()).thenReturn(new ClientID(clientId));
    var event = new APIGatewayProxyRequestEvent();
    event.setBody(format("{ \"client_name\": \"%s\", " + "\"redirect_uris\": [\"http://localhost:8080/redirect-uri\"], " + "\"contacts\": [\"joe.bloggs@test.com\"], " + "\"scopes\": [\"openid\"],  " + "\"public_key\": \"some-public-key\", " + "\"post_logout_redirect_uris\": [\"http://localhost:8080/post-logout-redirect-uri\"], " + "\"back_channel_logout_uri\": \"http://localhost:8080/back-channel-logout\", " + "\"service_type\": \"%s\", " + "\"sector_identifier_uri\": \"%s\", " + "\"subject_type\": \"%s\", " + "\"client_type\": \"%s\" }", CLIENT_NAME, MANDATORY, SECTOR_IDENTIFIER, SUBJECT_TYPE, clientType));
    var result = makeHandlerRequest(event);
    assertThat(result, hasStatus(200));
    var clientRegistrationResponseResult = objectMapper.readValue(result.getBody(), ClientRegistrationResponse.class);
    assertThat(clientRegistrationResponseResult.getClientType(), equalTo(clientType));
}
Also used : APIGatewayProxyRequestEvent(com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent) ClientID(com.nimbusds.oauth2.sdk.id.ClientID) ClientRegistrationRequest(uk.gov.di.authentication.clientregistry.entity.ClientRegistrationRequest) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 3 with ClientType

use of com.nimbusds.oauth2.sdk.client.ClientType in project di-authentication-api by alphagov.

the class RequestObjectService method validateRequestObject.

public Optional<AuthRequestError> validateRequestObject(AuthenticationRequest authRequest) {
    var clientId = authRequest.getClientID().toString();
    attachLogFieldToLogs(CLIENT_ID, clientId);
    var client = dynamoClientService.getClient(clientId).orElse(null);
    try {
        if (Objects.isNull(client)) {
            var errorMsg = "No Client found with given ClientID";
            LOG.warn(errorMsg);
            throw new RuntimeException(errorMsg);
        }
        var signedJWT = (SignedJWT) authRequest.getRequestObject();
        var signatureValid = isSignatureValid(signedJWT, client.getPublicKey());
        if (!signatureValid) {
            LOG.error("Invalid Signature on request JWT");
            throw new RuntimeException();
        }
        var jwtClaimsSet = signedJWT.getJWTClaimsSet();
        if (client.getRedirectUrls().stream().filter(Objects::nonNull).noneMatch(s -> s.equals(jwtClaimsSet.getClaim("redirect_uri")))) {
            throw new RuntimeException("Invalid Redirect URI in request JWT");
        }
        var redirectURI = URI.create((String) jwtClaimsSet.getClaim("redirect_uri"));
        if (Boolean.FALSE.equals(client.getClientType().equals(ClientType.APP.getValue()))) {
            LOG.warn("ClientType of client is not 'app'");
            return Optional.of(new AuthRequestError(OAuth2Error.UNAUTHORIZED_CLIENT, redirectURI));
        }
        if (!authRequest.getResponseType().toString().equals(ResponseType.CODE.toString())) {
            LOG.warn("Unsupported responseType included in request. Expected responseType of code");
            return Optional.of(new AuthRequestError(OAuth2Error.UNSUPPORTED_RESPONSE_TYPE, redirectURI));
        }
        if (requestContainsInvalidScopes(authRequest.getScope().toStringList(), client, false)) {
            LOG.warn("Invalid scopes in authRequest. Scopes in request: {}", authRequest.getScope().toStringList());
            return Optional.of(new AuthRequestError(OAuth2Error.INVALID_SCOPE, redirectURI));
        }
        if (Objects.isNull(jwtClaimsSet.getClaim("client_id")) || !jwtClaimsSet.getClaim("client_id").toString().equals(authRequest.getClientID().getValue())) {
            return Optional.of(new AuthRequestError(OAuth2Error.UNAUTHORIZED_CLIENT, redirectURI));
        }
        if (Objects.nonNull(jwtClaimsSet.getClaim("request")) || Objects.nonNull(jwtClaimsSet.getClaim("request_uri"))) {
            LOG.warn("request or request_uri claim should not be incldued in request JWT");
            return Optional.of(new AuthRequestError(OAuth2Error.INVALID_REQUEST, redirectURI));
        }
        if (Objects.isNull(jwtClaimsSet.getAudience()) || !jwtClaimsSet.getAudience().contains(buildURI(configurationService.getOidcApiBaseURL().orElseThrow(), "/authorize").toString())) {
            LOG.warn("Invalid or missing audience");
            return Optional.of(new AuthRequestError(OAuth2Error.ACCESS_DENIED, redirectURI));
        }
        if (Objects.isNull(jwtClaimsSet.getIssuer()) || !jwtClaimsSet.getIssuer().equals(client.getClientID())) {
            LOG.warn("Invalid or missing issuer");
            return Optional.of(new AuthRequestError(OAuth2Error.UNAUTHORIZED_CLIENT, redirectURI));
        }
        if (!ResponseType.CODE.toString().equals(jwtClaimsSet.getClaim("response_type"))) {
            LOG.warn("Unsupported responseType included in request JWT. Expected responseType of code");
            return Optional.of(new AuthRequestError(OAuth2Error.UNSUPPORTED_RESPONSE_TYPE, redirectURI));
        }
        if (Objects.isNull(jwtClaimsSet.getClaim("scope")) || requestContainsInvalidScopes(Scope.parse(jwtClaimsSet.getClaim("scope").toString()).toStringList(), client, true)) {
            LOG.warn("Invalid scopes in request JWT");
            return Optional.of(new AuthRequestError(OAuth2Error.INVALID_SCOPE, redirectURI));
        }
        if (Objects.isNull(jwtClaimsSet.getClaim("state"))) {
            LOG.warn("State is missing from authRequest");
            return Optional.of(new AuthRequestError(new ErrorObject(OAuth2Error.INVALID_REQUEST_CODE, "Request is missing state parameter"), redirectURI));
        }
    } catch (ParseException e) {
        throw new RuntimeException(e);
    }
    LOG.info("RequestObject has passed initial validation");
    return Optional.empty();
}
Also used : AuthRequestError(uk.gov.di.authentication.oidc.entity.AuthRequestError) ErrorObject(com.nimbusds.oauth2.sdk.ErrorObject) SignedJWT(com.nimbusds.jwt.SignedJWT) ParseException(java.text.ParseException)

Aggregations

APIGatewayProxyRequestEvent (com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent)1 SignedJWT (com.nimbusds.jwt.SignedJWT)1 AuthorizationRequest (com.nimbusds.oauth2.sdk.AuthorizationRequest)1 ErrorObject (com.nimbusds.oauth2.sdk.ErrorObject)1 ResponseType (com.nimbusds.oauth2.sdk.ResponseType)1 ClientID (com.nimbusds.oauth2.sdk.id.ClientID)1 State (com.nimbusds.oauth2.sdk.id.State)1 AuthenticationRequest (com.nimbusds.openid.connect.sdk.AuthenticationRequest)1 Nonce (com.nimbusds.openid.connect.sdk.Nonce)1 ParseException (java.text.ParseException)1 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)1 MethodSource (org.junit.jupiter.params.provider.MethodSource)1 ClientRegistrationRequest (uk.gov.di.authentication.clientregistry.entity.ClientRegistrationRequest)1 AuthRequestError (uk.gov.di.authentication.oidc.entity.AuthRequestError)1 ClientRegistry (uk.gov.di.authentication.shared.entity.ClientRegistry)1 ClientSession (uk.gov.di.authentication.shared.entity.ClientSession)1