Search in sources :

Example 1 with InvalidClientException

use of io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException in project gravitee-access-management by gravitee-io.

the class ClientAssertionServiceImpl method validateSignatureWithPublicKey.

private Maybe<Client> validateSignatureWithPublicKey(JWT jwt) {
    try {
        String clientId = jwt.getJWTClaimsSet().getSubject();
        SignedJWT signedJWT = (SignedJWT) jwt;
        return this.clientSyncService.findByClientId(clientId).switchIfEmpty(Maybe.error(new InvalidClientException("Missing or invalid client"))).flatMap(client -> {
            if (client.getTokenEndpointAuthMethod() == null || ClientAuthenticationMethod.PRIVATE_KEY_JWT.equalsIgnoreCase(client.getTokenEndpointAuthMethod())) {
                return this.getClientJwkSet(client).switchIfEmpty(Maybe.error(new InvalidClientException("No jwk keys available on client"))).flatMap(jwkSet -> jwkService.getKey(jwkSet, signedJWT.getHeader().getKeyID())).switchIfEmpty(Maybe.error(new InvalidClientException("Unable to validate client, no matching key."))).flatMap(jwk -> {
                    if (jwsService.isValidSignature(signedJWT, jwk)) {
                        return Maybe.just(client);
                    }
                    return Maybe.error(new InvalidClientException("Unable to validate client, assertion signature is not valid."));
                });
            } else {
                return Maybe.error(new InvalidClientException("Invalid client: missing or unsupported authentication method"));
            }
        });
    } catch (ClassCastException | ParseException ex) {
        LOGGER.error(ex.getMessage(), ex);
        return Maybe.error(NOT_VALID);
    } catch (IllegalArgumentException ex) {
        return Maybe.error(new InvalidClientException(ex.getMessage()));
    }
}
Also used : InvalidClientException(io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException) SignedJWT(com.nimbusds.jwt.SignedJWT) ParseException(java.text.ParseException)

Example 2 with InvalidClientException

use of io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException in project gravitee-access-management by gravitee-io.

the class ClientAssertionServiceImpl method validateJWT.

/**
 * This method will parse the JWT bearer then ensure that all requested claims are set as required
 * <a href="https://tools.ietf.org/html/rfc7523#section-3">here</a>
 * @param assertion jwt as string value.
 * @return
 */
private Maybe<JWT> validateJWT(String assertion, String basePath) {
    try {
        JWT jwt = JWTParser.parse(assertion);
        String iss = jwt.getJWTClaimsSet().getIssuer();
        String sub = jwt.getJWTClaimsSet().getSubject();
        List<String> aud = jwt.getJWTClaimsSet().getAudience();
        Date exp = jwt.getJWTClaimsSet().getExpirationTime();
        if (iss == null || iss.isEmpty() || sub == null || sub.isEmpty() || aud == null || aud.isEmpty() || exp == null) {
            return Maybe.error(NOT_VALID);
        }
        if (exp.before(Date.from(Instant.now()))) {
            return Maybe.error(new InvalidClientException("assertion has expired"));
        }
        // Check audience, here we expect to have absolute token endpoint path.
        OpenIDProviderMetadata discovery = openIDDiscoveryService.getConfiguration(basePath);
        if (discovery == null || discovery.getTokenEndpoint() == null) {
            return Maybe.error(new ServerErrorException("Unable to retrieve discovery token endpoint."));
        }
        // https://tools.ietf.org/id/draft-lodderstedt-oauth-par-00.html#pushed-authorization-request-endpoint
        if (aud.stream().filter(discovery.getTokenEndpoint()::equals).count() == 0 && (discovery.getIssuer() != null && aud.stream().filter(discovery.getIssuer()::equals).count() == 0) && (discovery.getParEndpoint() != null && aud.stream().filter(discovery.getParEndpoint()::equals).count() == 0)) {
            return Maybe.error(NOT_VALID);
        }
        if (this.domain.usePlainFapiProfile() && !isSignAlgCompliantWithFapi(jwt.getHeader().getAlgorithm().getName())) {
            return Maybe.error(new InvalidClientException("JWT Assertion must be signed with PS256"));
        }
        return Maybe.just(jwt);
    } catch (ParseException pe) {
        return Maybe.error(NOT_VALID);
    }
}
Also used : JWT(com.nimbusds.jwt.JWT) SignedJWT(com.nimbusds.jwt.SignedJWT) InvalidClientException(io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException) OpenIDProviderMetadata(io.gravitee.am.gateway.handler.oidc.service.discovery.OpenIDProviderMetadata) ServerErrorException(io.gravitee.am.gateway.handler.oauth2.exception.ServerErrorException) ParseException(java.text.ParseException) Date(java.util.Date)

Example 3 with InvalidClientException

use of io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException in project gravitee-access-management by gravitee-io.

the class RevocationTokenEndpoint method handle.

@Override
public void handle(RoutingContext context) {
    // The authorization server first validates the client credentials (in
    // case of a confidential client) and then verifies whether the token
    // was issued to the client making the revocation request.  If this
    // validation fails, the request is refused and the client is informed
    // of the error by the authorization server as described below.
    Client client = context.get(ConstantKeys.CLIENT_CONTEXT_KEY);
    if (client == null) {
        throw new InvalidClientException();
    }
    revocationTokenService.revoke(createRequest(context), client).subscribe(() -> context.response().setStatusCode(200).end(), context::fail);
}
Also used : InvalidClientException(io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException) Client(io.gravitee.am.model.oidc.Client)

Example 4 with InvalidClientException

use of io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException in project gravitee-access-management by gravitee-io.

the class TokenEndpoint method handle.

@Override
public void handle(RoutingContext context) {
    // Confidential clients or other clients issued client credentials MUST
    // authenticate with the authorization server when making requests to the token endpoint.
    Client client = context.get(CLIENT_CONTEXT_KEY);
    if (client == null) {
        throw new InvalidClientException();
    }
    TokenRequest tokenRequest = tokenRequestFactory.create(context);
    // client_id is not required in the token request since the client can be authenticated via a Basic Authentication
    if (tokenRequest.getClientId() != null) {
        if (!client.getClientId().equals(tokenRequest.getClientId())) {
            throw new InvalidClientException();
        }
    } else {
        // set token request client_id with the authenticated client
        tokenRequest.setClientId(client.getClientId());
    }
    // check if client has authorized grant types
    if (client.getAuthorizedGrantTypes() == null || client.getAuthorizedGrantTypes().isEmpty()) {
        throw new InvalidClientException("Invalid client: client must at least have one grant type configured");
    }
    if (context.get(ConstantKeys.PEER_CERTIFICATE_THUMBPRINT) != null) {
        // preserve certificate thumbprint to add the information into the access token
        tokenRequest.setConfirmationMethodX5S256(context.get(ConstantKeys.PEER_CERTIFICATE_THUMBPRINT));
    }
    tokenGranter.grant(tokenRequest, client).subscribe(accessToken -> context.response().putHeader(HttpHeaders.CACHE_CONTROL, "no-store").putHeader(HttpHeaders.PRAGMA, "no-cache").putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON).end(Json.encodePrettily(accessToken)), context::fail);
}
Also used : InvalidClientException(io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException) TokenRequest(io.gravitee.am.gateway.handler.oauth2.service.request.TokenRequest) Client(io.gravitee.am.model.oidc.Client)

Example 5 with InvalidClientException

use of io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException in project gravitee-access-management by gravitee-io.

the class ClientBasicAuthProviderTest method shouldNotAuthenticateClient_badClientSecret.

@Test
public void shouldNotAuthenticateClient_badClientSecret() throws Exception {
    Client client = mock(Client.class);
    when(client.getClientId()).thenReturn("my-client-id");
    when(client.getClientSecret()).thenReturn("my-client-secret");
    HttpServerRequest httpServerRequest = mock(HttpServerRequest.class);
    HeadersMultiMap vertxHttpHeaders = new HeadersMultiMap();
    vertxHttpHeaders.add(HttpHeaders.AUTHORIZATION, "Basic bXktY2xpZW50LWlkOm15LW90aGVyLWNsaWVudC1zZWNyZXQ=");
    when(httpServerRequest.headers()).thenReturn(MultiMap.newInstance(vertxHttpHeaders));
    RoutingContext context = mock(RoutingContext.class);
    when(context.request()).thenReturn(httpServerRequest);
    CountDownLatch latch = new CountDownLatch(1);
    authProvider.handle(client, context, userAsyncResult -> {
        latch.countDown();
        Assert.assertNotNull(userAsyncResult);
        Assert.assertTrue(userAsyncResult.failed());
        Assert.assertTrue(userAsyncResult.cause() instanceof InvalidClientException);
    });
    assertTrue(latch.await(10, TimeUnit.SECONDS));
}
Also used : RoutingContext(io.vertx.reactivex.ext.web.RoutingContext) HeadersMultiMap(io.vertx.core.http.impl.headers.HeadersMultiMap) HttpServerRequest(io.vertx.reactivex.core.http.HttpServerRequest) InvalidClientException(io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException) Client(io.gravitee.am.model.oidc.Client) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Aggregations

InvalidClientException (io.gravitee.am.gateway.handler.oauth2.exception.InvalidClientException)19 Client (io.gravitee.am.model.oidc.Client)11 HttpServerRequest (io.vertx.reactivex.core.http.HttpServerRequest)6 RoutingContext (io.vertx.reactivex.ext.web.RoutingContext)6 Test (org.junit.Test)5 CountDownLatch (java.util.concurrent.CountDownLatch)4 SignedJWT (com.nimbusds.jwt.SignedJWT)3 ParseException (java.text.ParseException)3 InvalidRequestException (io.gravitee.am.common.exception.oauth2.InvalidRequestException)2 Handler (io.vertx.core.Handler)2 X509Certificate (java.security.cert.X509Certificate)2 Algorithm (com.nimbusds.jose.Algorithm)1 JOSEException (com.nimbusds.jose.JOSEException)1 JWSAlgorithm (com.nimbusds.jose.JWSAlgorithm)1 JWSVerifier (com.nimbusds.jose.JWSVerifier)1 MACVerifier (com.nimbusds.jose.crypto.MACVerifier)1 JWT (com.nimbusds.jwt.JWT)1 MethodNotAllowedException (io.gravitee.am.common.exception.oauth2.MethodNotAllowedException)1 JWT (io.gravitee.am.common.jwt.JWT)1 Parameters (io.gravitee.am.common.oauth2.Parameters)1