use of io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider 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.social.SocialAuthenticationProvider in project gravitee-access-management by gravitee-io.
the class LogoutEndpointHandlerTest method shouldInvokeExternalOIDCLogoutEndpoint_targetUrlOk.
@Test
public void shouldInvokeExternalOIDCLogoutEndpoint_targetUrlOk() throws Exception {
JWT jwt = new JWT();
jwt.setAud("client-id");
Client client = new Client();
client.setClientId("client-id");
client.setPostLogoutRedirectUris(Arrays.asList("https://dev"));
client.setSingleSignOut(true);
when(certificateManager.defaultCertificateProvider()).thenReturn(mock(CertificateProvider.class));
when(jwtService.encode(any(JWT.class), any(CertificateProvider.class))).thenReturn(Single.just("jwtstatevalue"));
when(clientSyncService.findById("client-id")).thenReturn(Maybe.empty());
when(clientSyncService.findByClientId("client-id")).thenReturn(Maybe.just(client));
final SocialAuthenticationProvider authProvider = mock(SocialAuthenticationProvider.class);
final Request req = new Request();
req.setUri("https://oidc/logout");
req.setMethod(io.gravitee.common.http.HttpMethod.GET);
when(authProvider.signOutUrl(any())).thenReturn(Maybe.just(req));
when(identityProviderManager.get(any())).thenReturn(Maybe.just(authProvider));
router.route().order(-1).handler(routingContext -> {
User endUser = new User();
endUser.setClient("client-id");
final HashMap<String, Object> additionalInformation = new HashMap<>();
additionalInformation.put(ConstantKeys.OIDC_PROVIDER_ID_TOKEN_KEY, "opidtokenvalue");
endUser.setAdditionalInformation(additionalInformation);
routingContext.put(UriBuilderRequest.CONTEXT_PATH, "/domain");
routingContext.getDelegate().setUser(new io.gravitee.am.gateway.handler.common.vertx.web.auth.user.User(endUser));
routingContext.next();
});
testRequest(HttpMethod.GET, "/logout?target_url=https%3A%2F%2Fdev", null, resp -> {
String location = resp.headers().get("location");
assertNotNull(location);
assertTrue(location.startsWith("https://oidc/logout?post_logout_redirect_uri=http://localhost:"));
assertTrue(location.endsWith("/domain/logout/callback&id_token_hint=opidtokenvalue&state=jwtstatevalue"));
}, HttpStatusCode.FOUND_302, "Found", null);
}
use of io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider in project gravitee-access-management by gravitee-io.
the class LogoutEndpointHandlerTest method shouldInvokeExternalOIDCLogoutEndpoint_targetUrl_restriction_mismatch.
@Test
public void shouldInvokeExternalOIDCLogoutEndpoint_targetUrl_restriction_mismatch() throws Exception {
JWT jwt = new JWT();
jwt.setAud("client-id");
Client client = new Client();
client.setClientId("client-id");
client.setPostLogoutRedirectUris(Arrays.asList("https://dev"));
client.setSingleSignOut(true);
when(certificateManager.defaultCertificateProvider()).thenReturn(mock(CertificateProvider.class));
when(jwtService.encode(any(JWT.class), any(CertificateProvider.class))).thenReturn(Single.just("jwtstatevalue"));
when(clientSyncService.findById("client-id")).thenReturn(Maybe.empty());
when(clientSyncService.findByClientId("client-id")).thenReturn(Maybe.just(client));
final SocialAuthenticationProvider authProvider = mock(SocialAuthenticationProvider.class);
final Request req = new Request();
req.setUri("https://oidc/logout");
req.setMethod(io.gravitee.common.http.HttpMethod.GET);
when(authProvider.signOutUrl(any())).thenReturn(Maybe.just(req));
when(identityProviderManager.get(any())).thenReturn(Maybe.just(authProvider));
router.route().order(-1).handler(routingContext -> {
User endUser = new User();
endUser.setClient("client-id");
final HashMap<String, Object> additionalInformation = new HashMap<>();
additionalInformation.put(ConstantKeys.OIDC_PROVIDER_ID_TOKEN_KEY, "opidtokenvalue");
endUser.setAdditionalInformation(additionalInformation);
routingContext.getDelegate().setUser(new io.gravitee.am.gateway.handler.common.vertx.web.auth.user.User(endUser));
routingContext.next();
});
testRequest(HttpMethod.GET, "/logout?target_url=https%3A%2F%2Ftest", null, resp -> {
String location = resp.headers().get("location");
assertNotNull(location);
assertTrue(location.endsWith("/error?client_id=client-id&error=invalid_request&error_description=The+post_logout_redirect_uri+MUST+match+the+registered+callback+URLs"));
}, HttpStatusCode.FOUND_302, "Found", null);
}
use of io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider in project gravitee-access-management by gravitee-io.
the class LoginController method login.
@RequestMapping(value = "/login")
public ModelAndView login(HttpServletRequest request, @RequestParam(value = ORGANIZATION_PARAMETER_NAME, defaultValue = "DEFAULT") String organizationId) {
Map<String, Object> params = new HashMap<>();
// fetch domain social identity providers
List<IdentityProvider> socialProviders = null;
try {
socialProviders = organizationService.findById(organizationId).map(org -> Optional.ofNullable(org.getIdentities()).orElse(emptyList())).blockingGet().stream().map(identity -> identityProviderManager.getIdentityProvider(identity)).filter(Objects::nonNull).filter(IdentityProvider::isExternal).collect(Collectors.toList());
} catch (Exception ex) {
LOGGER.error("An error has occurred while loading the organization social providers. It probably means that a social provider is not well started", ex);
}
// enhance social providers data
if (socialProviders != null && !socialProviders.isEmpty()) {
Set<IdentityProvider> enhancedSocialProviders = socialProviders.stream().map(identityProvider -> {
// get social identity provider type (currently use for display purpose (logo, description, ...)
identityProvider.setType(socialProviderTypes.getOrDefault(identityProvider.getType(), identityProvider.getType()));
return identityProvider;
}).collect(Collectors.toSet());
Map<String, String> authorizeUrls = new HashMap<>();
socialProviders.forEach(identity -> {
String identityId = identity.getId();
SocialAuthenticationProvider socialAuthenticationProvider = (SocialAuthenticationProvider) identityProviderManager.get(identityId);
if (socialAuthenticationProvider != null) {
final Maybe<Request> maybe = socialAuthenticationProvider.asyncSignInUrl(buildRedirectUri(request, identityId), RandomString.generate());
authorizeUrls.put(identityId, maybe.blockingGet().getUri());
}
});
params.put("oauth2Providers", enhancedSocialProviders);
params.put("socialProviders", enhancedSocialProviders);
params.put("authorizeUrls", authorizeUrls);
}
params.put("reCaptchaEnabled", reCaptchaService.isEnabled());
params.put("reCaptchaSiteKey", reCaptchaService.getSiteKey());
params.put("org", organizationId);
return new ModelAndView(organizationId + "#" + LOGIN_VIEW, params);
}
use of io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider in project gravitee-access-management by gravitee-io.
the class LoginSocialAuthenticationHandler method getAuthorizeUrl.
private Maybe<String> getAuthorizeUrl(String identityProviderId, RoutingContext context) {
return identityProviderManager.get(identityProviderId).flatMap(authenticationProvider -> {
// Generate a state containing provider id and current query parameter string. This state will be sent back to AM after social authentication.
final JWT stateJwt = new JWT();
stateJwt.put("p", identityProviderId);
stateJwt.put("q", context.request().query());
return jwtService.encode(stateJwt, certificateManager.defaultCertificateProvider()).flatMapMaybe(state -> {
String redirectUri = UriBuilderRequest.resolveProxyRequest(context.request(), context.get(CONTEXT_PATH) + "/login/callback");
Maybe<Request> signInURL = ((SocialAuthenticationProvider) authenticationProvider).asyncSignInUrl(redirectUri, state);
return signInURL.map(request -> {
if (HttpMethod.GET.equals(request.getMethod())) {
return request.getUri();
} else {
// Extract body to convert it to query parameters and use POST form.
final Map<String, String> queryParams = getParams(request.getBody());
queryParams.put(ACTION_KEY, request.getUri());
return UriBuilderRequest.resolveProxyRequest(context.request(), context.get(CONTEXT_PATH) + "/login/SSO/POST", queryParams);
}
});
});
});
}
Aggregations