use of io.gravitee.am.identityprovider.api.SimpleAuthenticationContext in project gravitee-access-management by gravitee-io.
the class UserAuthProviderImpl method authenticate.
@Override
public void authenticate(RoutingContext context, JsonObject authInfo, Handler<AsyncResult<User>> handler) {
String username = authInfo.getString(USERNAME_PARAMETER);
String password = authInfo.getString(PASSWORD_PARAMETER);
String clientId = authInfo.getString(Parameters.CLIENT_ID);
String ipAddress = authInfo.getString(Claims.ip_address);
String userAgent = authInfo.getString(Claims.user_agent);
parseClient(clientId, parseClientHandler -> {
if (parseClientHandler.failed()) {
logger.error("Authentication failure: unable to retrieve client " + clientId, parseClientHandler.cause());
handler.handle(Future.failedFuture(parseClientHandler.cause()));
return;
}
// retrieve the client (application)
final Client client = parseClientHandler.result();
// end user authentication
SimpleAuthenticationContext authenticationContext = new SimpleAuthenticationContext(new VertxHttpServerRequest(context.request().getDelegate()));
final Authentication authentication = new EndUserAuthentication(username, password, authenticationContext);
authenticationContext.set(Claims.ip_address, ipAddress);
authenticationContext.set(Claims.user_agent, userAgent);
authenticationContext.set(Claims.domain, client.getDomain());
userAuthenticationManager.authenticate(client, authentication).subscribe(user -> handler.handle(Future.succeededFuture(new io.gravitee.am.gateway.handler.common.vertx.web.auth.user.User(user))), error -> handler.handle(Future.failedFuture(error)));
});
}
use of io.gravitee.am.identityprovider.api.SimpleAuthenticationContext in project gravitee-access-management by gravitee-io.
the class LogoutEndpoint method evaluateSingleSignOut.
/**
* Check if the single sign out feature is requested, if yes return the delegated OP end session endpoint URL
* @param routingContext the routing context
* @param handler handler holding the potential delegated OP end session endpoint URL
*/
private void evaluateSingleSignOut(RoutingContext routingContext, Handler<AsyncResult<String>> handler) {
final Client client = routingContext.get(ConstantKeys.CLIENT_CONTEXT_KEY);
final User endUser = routingContext.get(ConstantKeys.USER_CONTEXT_KEY) != null ? routingContext.get(ConstantKeys.USER_CONTEXT_KEY) : (routingContext.user() != null ? ((io.gravitee.am.gateway.handler.common.vertx.web.auth.user.User) routingContext.user().getDelegate()).getUser() : null);
// if no client, continue
if (client == null) {
handler.handle(Future.succeededFuture());
return;
}
// if single sign out feature disabled, continue
if (!client.isSingleSignOut()) {
handler.handle(Future.succeededFuture());
return;
}
// if no user, continue
if (endUser == null) {
handler.handle(Future.succeededFuture());
return;
}
// generate the delegated OP logout request
final Authentication authentication = new EndUserAuthentication(endUser, null, new SimpleAuthenticationContext(new VertxHttpServerRequest(routingContext.request().getDelegate())));
identityProviderManager.get(endUser.getSource()).filter(provider -> provider instanceof SocialAuthenticationProvider).flatMap(provider -> ((SocialAuthenticationProvider) provider).signOutUrl(authentication)).flatMap(logoutRequest -> generateLogoutCallback(routingContext, endUser, logoutRequest)).subscribe(endpoint -> handler.handle(Future.succeededFuture(endpoint)), err -> {
LOGGER.warn("Unable to sign the end user out of the external OIDC '{}', only sign out of AM", client.getClientId(), err);
handler.handle(Future.succeededFuture());
}, () -> handler.handle(Future.succeededFuture()));
}
use of io.gravitee.am.identityprovider.api.SimpleAuthenticationContext in project gravitee-access-management by gravitee-io.
the class UserAuthenticationServiceImpl method loadPreAuthenticatedUser.
@Override
public Maybe<User> loadPreAuthenticatedUser(String subject, Request request) {
// find user by its technical id
return userService.findById(subject).switchIfEmpty(Maybe.error(new UserNotFoundException(subject))).flatMap(user -> isIndefinitelyLocked(user) ? Maybe.error(new AccountLockedException("User " + user.getUsername() + " is locked")) : Maybe.just(user)).flatMap(user -> identityProviderManager.get(user.getSource()).flatMap(authenticationProvider -> {
SimpleAuthenticationContext authenticationContext = new SimpleAuthenticationContext(request);
final Authentication authentication = new EndUserAuthentication(user, null, authenticationContext);
return authenticationProvider.loadPreAuthenticatedUser(authentication);
}).flatMap(idpUser -> {
// retrieve information from the idp user and update the user
Map<String, Object> additionalInformation = idpUser.getAdditionalInformation() == null ? new HashMap<>() : new HashMap<>(idpUser.getAdditionalInformation());
additionalInformation.put(SOURCE_FIELD, user.getSource());
additionalInformation.put(Parameters.CLIENT_ID, user.getClient());
((DefaultUser) idpUser).setAdditionalInformation(additionalInformation);
return update(user, idpUser, false).flatMap(userService::enhance).toMaybe();
}).switchIfEmpty(Maybe.defer(() -> userService.enhance(user).toMaybe())));
}
use of io.gravitee.am.identityprovider.api.SimpleAuthenticationContext in project gravitee-access-management by gravitee-io.
the class AuthenticationServiceImpl method onAuthenticationSuccess.
@Override
public User onAuthenticationSuccess(Authentication auth) {
final DefaultUser principal = (DefaultUser) auth.getPrincipal();
final EndUserAuthentication authentication = new EndUserAuthentication(principal.getUsername(), null, new SimpleAuthenticationContext());
Map<String, String> details = auth.getDetails() == null ? new HashMap<>() : new HashMap<>((Map<String, String>) auth.getDetails());
details.putIfAbsent(Claims.organization, Organization.DEFAULT);
String organizationId = details.get(Claims.organization);
final String source = details.get(SOURCE);
io.gravitee.am.model.User endUser = userService.findByExternalIdAndSource(ReferenceType.ORGANIZATION, organizationId, principal.getId(), source).switchIfEmpty(Maybe.defer(() -> userService.findByUsernameAndSource(ReferenceType.ORGANIZATION, organizationId, principal.getUsername(), source))).switchIfEmpty(Maybe.error(new UserNotFoundException(principal.getUsername()))).flatMapSingle(existingUser -> {
existingUser.setSource(details.get(SOURCE));
existingUser.setLoggedAt(new Date());
existingUser.setLoginsCount(existingUser.getLoginsCount() + 1);
if (existingUser.getAdditionalInformation() != null) {
existingUser.getAdditionalInformation().putAll(principal.getAdditionalInformation());
} else {
existingUser.setAdditionalInformation(new HashMap<>(principal.getAdditionalInformation()));
}
return userService.update(existingUser).flatMap(user -> updateRoles(principal, existingUser).andThen(Single.just(user)));
}).onErrorResumeNext(ex -> {
if (ex instanceof UserNotFoundException) {
final io.gravitee.am.model.User newUser = new io.gravitee.am.model.User();
newUser.setInternal(false);
newUser.setExternalId(principal.getId());
newUser.setUsername(principal.getUsername());
newUser.setSource(details.get(SOURCE));
newUser.setReferenceType(ReferenceType.ORGANIZATION);
newUser.setReferenceId(organizationId);
newUser.setLoggedAt(new Date());
newUser.setLoginsCount(1L);
newUser.setAdditionalInformation(principal.getAdditionalInformation());
return userService.create(newUser).flatMap(user -> userService.setRoles(principal, user).andThen(Single.just(user)));
}
return Single.error(ex);
}).flatMap(userService::enhance).doOnSuccess(user -> auditService.report(AuditBuilder.builder(AuthenticationAuditBuilder.class).principal(authentication).referenceType(ReferenceType.ORGANIZATION).referenceId(organizationId).user(user).ipAddress(details.get(IP_ADDRESS_KEY)).userAgent(details.get(USER_AGENT_KEY)))).blockingGet();
principal.setId(endUser.getId());
principal.setUsername(endUser.getUsername());
if (endUser.getAdditionalInformation() != null) {
principal.getAdditionalInformation().putAll(endUser.getAdditionalInformation());
}
principal.getAdditionalInformation().put(StandardClaims.SUB, endUser.getId());
principal.getAdditionalInformation().put(StandardClaims.PREFERRED_USERNAME, endUser.getUsername());
principal.getAdditionalInformation().put(Claims.organization, endUser.getReferenceId());
principal.getAdditionalInformation().put("login_count", endUser.getLoginsCount());
principal.getAdditionalInformation().computeIfAbsent(StandardClaims.EMAIL, val -> endUser.getEmail());
principal.getAdditionalInformation().computeIfAbsent(StandardClaims.NAME, val -> endUser.getDisplayName());
// set roles
Set<String> roles = endUser.getRoles() != null ? new HashSet<>(endUser.getRoles()) : new HashSet<>();
if (principal.getRoles() != null) {
roles.addAll(principal.getRoles());
}
principal.getAdditionalInformation().put(CustomClaims.ROLES, roles);
return principal;
}
use of io.gravitee.am.identityprovider.api.SimpleAuthenticationContext in project gravitee-access-management by gravitee-io.
the class CustomLogoutSuccessHandler method determineTargetUrl.
@Override
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
String logoutRedirectUrl = request.getParameter(LOGOUT_URL_PARAMETER);
if (logoutRedirectUrl != null && !logoutRedirectUrl.isEmpty()) {
setTargetUrlParameter(LOGOUT_URL_PARAMETER);
}
final Cookie[] cookies = request.getCookies();
final Optional<Cookie> authCookie = Stream.of(cookies).filter(c -> authCookieName.equals(c.getName())).findFirst();
authCookie.ifPresent(cookie -> {
try {
final String jwtStr = cookie.getValue().substring("Bearer ".length());
final JWT jwt = jwtParser.parse(jwtStr);
WebAuthenticationDetails details = new WebAuthenticationDetails(request);
// read user profile to obtain same information as login step.
// if the read fails, trace only with information available into the cookie
userService.findById(ReferenceType.ORGANIZATION, (String) jwt.get("org"), (String) jwt.getSub()).doOnSuccess(user -> auditService.report(AuditBuilder.builder(LogoutAuditBuilder.class).user(user).referenceType(ReferenceType.ORGANIZATION).referenceId((String) jwt.get("org")).ipAddress(details.getRemoteAddress()).userAgent(details.getUserAgent()))).doOnError(err -> {
logger.warn("Unable to read user information, trace logout with minimal data", err);
auditService.report(AuditBuilder.builder(LogoutAuditBuilder.class).principal(new EndUserAuthentication(jwt.get("username"), null, new SimpleAuthenticationContext())).referenceType(ReferenceType.ORGANIZATION).referenceId((String) jwt.get("org")).ipAddress(details.getRemoteAddress()).userAgent(details.getUserAgent()));
}).subscribe();
} catch (Exception e) {
logger.warn("Unable to extract information from authentication cookie", e);
}
});
return super.determineTargetUrl(request, response);
}
Aggregations