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);
}
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);
}
}
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);
}
}
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));
});
}
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();
});
}
Aggregations