Search in sources :

Example 21 with Client

use of io.gravitee.am.model.oidc.Client in project gravitee-access-management by gravitee-io.

the class MFAEnrollStep method execute.

@Override
public void execute(RoutingContext routingContext, AuthenticationFlowChain flow) {
    final Client client = routingContext.get(ConstantKeys.CLIENT_CONTEXT_KEY);
    final io.gravitee.am.model.User endUser = ((User) routingContext.user().getDelegate()).getUser();
    final Session session = routingContext.session();
    var context = new MfaFilterContext(client, session, endUser);
    // Rules that makes you skip MFA enroll
    var mfaFilterChain = new MfaFilterChain(new ClientNullFilter(client), new NoFactorFilter(client.getFactors(), factorManager), new EndUserEnrolledFilter(context), new AdaptiveMfaFilter(context, ruleEngine, routingContext.request(), routingContext.data()), new StepUpAuthenticationFilter(context, ruleEngine, routingContext.request(), routingContext.data()), new RememberDeviceFilter(context), new MfaSkipFilter(context));
    mfaFilterChain.doFilter(this, flow, routingContext);
}
Also used : User(io.gravitee.am.gateway.handler.common.vertx.web.auth.user.User) MfaFilterChain(io.gravitee.am.gateway.handler.common.vertx.web.handler.impl.internal.mfa.chain.MfaFilterChain) Client(io.gravitee.am.model.oidc.Client) Session(io.vertx.reactivex.ext.web.Session)

Example 22 with Client

use of io.gravitee.am.model.oidc.Client in project gravitee-access-management by gravitee-io.

the class WebAuthnRegisterEndpoint method renderPage.

private void renderPage(RoutingContext routingContext) {
    try {
        // session validation
        if (routingContext.session() == null) {
            logger.warn("No session or session handler is missing.");
            routingContext.fail(500);
            return;
        }
        if (routingContext.user() == null) {
            logger.warn("User must be authenticated to register WebAuthn credentials.");
            routingContext.fail(401);
            return;
        }
        final MultiMap queryParams = RequestUtils.getCleanedQueryParams(routingContext.request());
        // check if user has skipped this step
        final HttpServerRequest request = routingContext.request();
        if (Boolean.parseBoolean(request.getParam(SKIP_WEBAUTHN_PARAM_KEY))) {
            queryParams.remove(SKIP_WEBAUTHN_PARAM_KEY);
            String returnURL = UriBuilderRequest.resolveProxyRequest(routingContext.request(), routingContext.get(CONTEXT_PATH) + "/oauth/authorize", queryParams, true);
            routingContext.session().put(ConstantKeys.WEBAUTHN_SKIPPED_KEY, true);
            // Now redirect back to the original url
            doRedirect(routingContext.response(), returnURL);
            return;
        }
        // prepare the context
        final Client client = routingContext.get(ConstantKeys.CLIENT_CONTEXT_KEY);
        final User user = ((io.gravitee.am.gateway.handler.common.vertx.web.auth.user.User) routingContext.user().getDelegate()).getUser();
        final UserProperties userProperties = new UserProperties(user);
        final String action = UriBuilderRequest.resolveProxyRequest(routingContext.request(), routingContext.request().path(), queryParams, true);
        final String skipAction = UriBuilderRequest.resolveProxyRequest(routingContext.request(), routingContext.request().path(), queryParams.set("skipWebAuthN", "true"), true);
        routingContext.put(ConstantKeys.ACTION_KEY, action);
        routingContext.put(ConstantKeys.SKIP_ACTION_KEY, skipAction);
        routingContext.put(ConstantKeys.USER_CONTEXT_KEY, userProperties);
        routingContext.put(ConstantKeys.PARAM_CONTEXT_KEY, Collections.singletonMap(Parameters.CLIENT_ID, client.getClientId()));
        if (domain.getWebAuthnSettings() != null && domain.getWebAuthnSettings().getAuthenticatorAttachment() != null) {
            routingContext.put(ConstantKeys.PARAM_AUTHENTICATOR_ATTACHMENT_KEY, domain.getWebAuthnSettings().getAuthenticatorAttachment().getValue());
        }
        // render the webauthn register page
        this.renderPage(routingContext, generateData(routingContext, domain, client), client, logger, "Unable to render WebAuthn register page");
    } catch (Exception ex) {
        logger.error("An error has occurred while rendering WebAuthn register page", ex);
        routingContext.fail(503);
    }
}
Also used : MultiMap(io.vertx.reactivex.core.MultiMap) User(io.gravitee.am.model.User) UserProperties(io.gravitee.am.model.safe.UserProperties) HttpServerRequest(io.vertx.reactivex.core.http.HttpServerRequest) Client(io.gravitee.am.model.oidc.Client)

Example 23 with Client

use of io.gravitee.am.model.oidc.Client in project gravitee-access-management by gravitee-io.

the class WebAuthnResponseEndpoint method handle.

@Override
public void handle(RoutingContext ctx) {
    try {
        // might throw runtime exception if there's no json or is bad formed
        final JsonObject webauthnResp = ctx.getBodyAsJson();
        // input validation
        if (isEmptyString(webauthnResp, "id") || isEmptyString(webauthnResp, "rawId") || isEmptyObject(webauthnResp, "response") || isEmptyString(webauthnResp, "type") || !"public-key".equals(webauthnResp.getString("type"))) {
            logger.debug("Response missing one or more of id/rawId/response/type fields, or type is not public-key");
            ctx.fail(400);
            return;
        }
        // session validation
        final Session session = ctx.session();
        if (ctx.session() == null) {
            logger.error("No session or session handler is missing.");
            ctx.fail(500);
            return;
        }
        final Client client = ctx.get(ConstantKeys.CLIENT_CONTEXT_KEY);
        final String userId = session.get(ConstantKeys.PASSWORDLESS_CHALLENGE_USER_ID);
        final String username = session.get(ConstantKeys.PASSWORDLESS_CHALLENGE_USERNAME_KEY);
        final String credentialId = webauthnResp.getString("id");
        // authenticate the user
        webAuthn.authenticate(// authInfo
        new WebAuthnCredentials().setOrigin(origin).setChallenge(session.get(ConstantKeys.PASSWORDLESS_CHALLENGE_KEY)).setUsername(session.get(ConstantKeys.PASSWORDLESS_CHALLENGE_USERNAME_KEY)).setWebauthn(webauthnResp), authenticate -> {
            // invalidate the challenge
            session.remove(ConstantKeys.PASSWORDLESS_CHALLENGE_KEY);
            session.remove(ConstantKeys.PASSWORDLESS_CHALLENGE_USERNAME_KEY);
            session.remove(ConstantKeys.PASSWORDLESS_CHALLENGE_USER_ID);
            if (authenticate.succeeded()) {
                // create the authentication context
                final AuthenticationContext authenticationContext = createAuthenticationContext(ctx);
                // authenticate the user
                authenticateUser(authenticationContext, client, username, h -> {
                    if (h.failed()) {
                        logger.error("An error has occurred while authenticating user {}", username, h.cause());
                        ctx.fail(401);
                        return;
                    }
                    final User user = h.result();
                    final io.gravitee.am.model.User authenticatedUser = ((io.gravitee.am.gateway.handler.common.vertx.web.auth.user.User) user).getUser();
                    // check if the authenticated user is the same as the one in session
                    if (userId == null || !userId.equals(authenticatedUser.getId())) {
                        logger.error("Invalid authenticated user {}, user in session was {}", authenticatedUser.getId(), userId);
                        ctx.fail(401);
                        return;
                    }
                    // update the credential
                    updateCredential(authenticationContext, credentialId, userId, credentialHandler -> {
                        if (credentialHandler.failed()) {
                            logger.error("An error has occurred while authenticating user {}", username, credentialHandler.cause());
                            ctx.fail(401);
                            return;
                        }
                        // save the user into the context
                        ctx.getDelegate().setUser(user);
                        ctx.session().put(ConstantKeys.PASSWORDLESS_AUTH_COMPLETED_KEY, true);
                        ctx.session().put(ConstantKeys.WEBAUTHN_CREDENTIAL_ID_CONTEXT_KEY, credentialId);
                        // Now redirect back to authorization endpoint.
                        final MultiMap queryParams = RequestUtils.getCleanedQueryParams(ctx.request());
                        final String returnURL = UriBuilderRequest.resolveProxyRequest(ctx.request(), ctx.get(CONTEXT_PATH) + "/oauth/authorize", queryParams, true);
                        ctx.response().putHeader(HttpHeaders.LOCATION, returnURL).end();
                    });
                });
            } else {
                logger.error("Unexpected exception", authenticate.cause());
                ctx.fail(authenticate.cause());
            }
        });
    } catch (IllegalArgumentException e) {
        logger.error("Unexpected exception", e);
        ctx.fail(400);
    } catch (RuntimeException e) {
        logger.error("Unexpected exception", e);
        ctx.fail(e);
    }
}
Also used : SimpleAuthenticationContext(io.gravitee.am.identityprovider.api.SimpleAuthenticationContext) AuthenticationContext(io.gravitee.am.identityprovider.api.AuthenticationContext) User(io.vertx.ext.auth.User) JsonObject(io.vertx.core.json.JsonObject) MultiMap(io.vertx.reactivex.core.MultiMap) WebAuthnCredentials(io.vertx.ext.auth.webauthn.WebAuthnCredentials) Client(io.gravitee.am.model.oidc.Client) Session(io.vertx.reactivex.ext.web.Session)

Example 24 with Client

use of io.gravitee.am.model.oidc.Client in project gravitee-access-management by gravitee-io.

the class BotDetectionHandler method handle.

@Override
public void handle(RoutingContext routingContext) {
    Client client = routingContext.get(CLIENT_CONTEXT_KEY);
    AccountSettings accountSettings = AccountSettings.getInstance(domain, client);
    if (accountSettings == null || !accountSettings.isUseBotDetection()) {
        routingContext.next();
        return;
    }
    if (StringUtils.isEmpty(accountSettings.getBotDetectionPlugin())) {
        LOGGER.error("Bot Detection enable without plugin identifier for domain '{}' and application '{}'", domain.getId(), client.getId());
        routingContext.fail(INTERNAL_SERVER_ERROR_500, new TechnicalManagementException(DEFAULT_ERROR_MSG));
        return;
    }
    final MultiMap headers = routingContext.request().headers();
    final MultiMap params = routingContext.request().params();
    BotDetectionContext context = new BotDetectionContext(accountSettings.getBotDetectionPlugin(), headers, params);
    botDetectionManager.validate(context).subscribe((isValid) -> {
        if (isValid) {
            LOGGER.debug("No bot detected for domain '{}' and client '{}'", domain.getId(), client.getId());
            routingContext.next();
        } else {
            LOGGER.warn("Bot detected for domain '{}' and client '{}'", domain.getId(), client.getId());
            routingContext.fail(BAD_REQUEST_400, new BotDetectedException(DEFAULT_ERROR_MSG));
        }
    }, (error) -> {
        LOGGER.error("BotDetection failed for domain '{}' and client '{}'", domain.getId(), client.getId(), error);
        routingContext.fail(INTERNAL_SERVER_ERROR_500, new TechnicalManagementException(DEFAULT_ERROR_MSG));
    });
}
Also used : AccountSettings(io.gravitee.am.model.account.AccountSettings) MultiMap(io.vertx.reactivex.core.MultiMap) BotDetectedException(io.gravitee.am.service.exception.BotDetectedException) BotDetectionContext(io.gravitee.am.botdetection.api.BotDetectionContext) Client(io.gravitee.am.model.oidc.Client) TechnicalManagementException(io.gravitee.am.service.exception.TechnicalManagementException)

Example 25 with Client

use of io.gravitee.am.model.oidc.Client in project gravitee-access-management by gravitee-io.

the class ClientRequestParseHandler method handle.

@Override
public void handle(RoutingContext context) {
    final String clientId = context.request().getParam(Parameters.CLIENT_ID);
    if (clientId == null || clientId.isEmpty()) {
        if (required) {
            context.fail(new InvalidRequestException("Missing parameter: client_id is required"));
        } else {
            context.next();
        }
        return;
    }
    authenticate(clientId, authHandler -> {
        if (authHandler.failed()) {
            if (continueOnError) {
                context.next();
            } else {
                context.fail(authHandler.cause());
            }
            return;
        }
        Client safeClient = new Client(authHandler.result());
        safeClient.setClientSecret(null);
        context.put(CLIENT_CONTEXT_KEY, safeClient);
        context.next();
    });
}
Also used : InvalidRequestException(io.gravitee.am.common.exception.oauth2.InvalidRequestException) Client(io.gravitee.am.model.oidc.Client)

Aggregations

Client (io.gravitee.am.model.oidc.Client)482 Test (org.junit.Test)351 User (io.gravitee.am.model.User)120 JWT (io.gravitee.am.common.jwt.JWT)81 TestObserver (io.reactivex.observers.TestObserver)71 RoutingContext (io.vertx.reactivex.ext.web.RoutingContext)46 DefaultUser (io.gravitee.am.identityprovider.api.DefaultUser)45 JWKSet (io.gravitee.am.model.oidc.JWKSet)43 ApplicationScopeSettings (io.gravitee.am.model.application.ApplicationScopeSettings)42 AuthorizationRequest (io.gravitee.am.gateway.handler.oauth2.service.request.AuthorizationRequest)41 Domain (io.gravitee.am.model.Domain)41 HttpServerRequest (io.vertx.reactivex.core.http.HttpServerRequest)40 WebClient (io.vertx.reactivex.ext.web.client.WebClient)40 Maybe (io.reactivex.Maybe)39 Single (io.reactivex.Single)38 OpenIDProviderMetadata (io.gravitee.am.gateway.handler.oidc.service.discovery.OpenIDProviderMetadata)34 Handler (io.vertx.core.Handler)31 ConstantKeys (io.gravitee.am.common.utils.ConstantKeys)29 JWTService (io.gravitee.am.gateway.handler.common.jwt.JWTService)28 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)28