Search in sources :

Example 1 with SocialAuthenticationProvider

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()));
}
Also used : Client(io.gravitee.am.model.oidc.Client) Authentication(io.gravitee.am.identityprovider.api.Authentication) Maybe(io.reactivex.Maybe) LoggerFactory(org.slf4j.LoggerFactory) IdentityProviderManager(io.gravitee.am.gateway.handler.common.auth.idp.IdentityProviderManager) UserService(io.gravitee.am.gateway.handler.root.service.user.UserService) ConstantKeys(io.gravitee.am.common.utils.ConstantKeys) JWTService(io.gravitee.am.gateway.handler.common.jwt.JWTService) ClientSyncService(io.gravitee.am.gateway.handler.common.client.ClientSyncService) AsyncResult(io.vertx.core.AsyncResult) User(io.gravitee.am.model.User) SimpleAuthenticationContext(io.gravitee.am.identityprovider.api.SimpleAuthenticationContext) SocialAuthenticationProvider(io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider) UriBuilder(io.gravitee.am.common.web.UriBuilder) AuthenticationFlowContextService(io.gravitee.am.service.AuthenticationFlowContextService) RequestUtils(io.gravitee.am.gateway.handler.common.vertx.utils.RequestUtils) Logger(org.slf4j.Logger) HttpServerRequest(io.vertx.reactivex.core.http.HttpServerRequest) JWT(io.gravitee.am.common.jwt.JWT) CertificateManager(io.gravitee.am.gateway.handler.common.certificate.CertificateManager) Request(io.gravitee.am.identityprovider.api.common.Request) Domain(io.gravitee.am.model.Domain) VertxHttpServerRequest(io.gravitee.am.gateway.handler.common.vertx.core.http.VertxHttpServerRequest) Future(io.vertx.core.Future) RoutingContext(io.vertx.reactivex.ext.web.RoutingContext) WebClient(io.vertx.reactivex.ext.web.client.WebClient) UserNotFoundException(io.gravitee.am.service.exception.UserNotFoundException) UriBuilderRequest(io.gravitee.am.gateway.handler.common.vertx.utils.UriBuilderRequest) MultiMap(io.vertx.reactivex.core.MultiMap) UserToken(io.gravitee.am.gateway.handler.root.service.user.model.UserToken) Parameters(io.gravitee.am.common.oidc.Parameters) EndUserAuthentication(io.gravitee.am.gateway.handler.common.auth.user.EndUserAuthentication) CONTEXT_PATH(io.gravitee.am.gateway.handler.common.vertx.utils.UriBuilderRequest.CONTEXT_PATH) Handler(io.vertx.core.Handler) StringUtils(org.springframework.util.StringUtils) User(io.gravitee.am.model.User) SimpleAuthenticationContext(io.gravitee.am.identityprovider.api.SimpleAuthenticationContext) VertxHttpServerRequest(io.gravitee.am.gateway.handler.common.vertx.core.http.VertxHttpServerRequest) Authentication(io.gravitee.am.identityprovider.api.Authentication) EndUserAuthentication(io.gravitee.am.gateway.handler.common.auth.user.EndUserAuthentication) Client(io.gravitee.am.model.oidc.Client) WebClient(io.vertx.reactivex.ext.web.client.WebClient) SocialAuthenticationProvider(io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider) EndUserAuthentication(io.gravitee.am.gateway.handler.common.auth.user.EndUserAuthentication)

Example 2 with SocialAuthenticationProvider

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);
}
Also used : User(io.gravitee.am.model.User) HashMap(java.util.HashMap) JWT(io.gravitee.am.common.jwt.JWT) Request(io.gravitee.am.identityprovider.api.common.Request) UriBuilderRequest(io.gravitee.am.gateway.handler.common.vertx.utils.UriBuilderRequest) CertificateProvider(io.gravitee.am.gateway.certificate.CertificateProvider) Client(io.gravitee.am.model.oidc.Client) WebClient(io.vertx.reactivex.ext.web.client.WebClient) SocialAuthenticationProvider(io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider) Test(org.junit.Test)

Example 3 with SocialAuthenticationProvider

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);
}
Also used : User(io.gravitee.am.model.User) HashMap(java.util.HashMap) JWT(io.gravitee.am.common.jwt.JWT) Request(io.gravitee.am.identityprovider.api.common.Request) UriBuilderRequest(io.gravitee.am.gateway.handler.common.vertx.utils.UriBuilderRequest) CertificateProvider(io.gravitee.am.gateway.certificate.CertificateProvider) Client(io.gravitee.am.model.oidc.Client) WebClient(io.vertx.reactivex.ext.web.client.WebClient) SocialAuthenticationProvider(io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider) Test(org.junit.Test)

Example 4 with SocialAuthenticationProvider

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);
}
Also used : IdentityProviderManager(io.gravitee.am.management.handlers.management.api.authentication.manager.idp.IdentityProviderManager) UriComponentsBuilder(org.springframework.web.util.UriComponentsBuilder) RequestParam(org.springframework.web.bind.annotation.RequestParam) java.util(java.util) HttpHeaders(io.gravitee.common.http.HttpHeaders) Logger(org.slf4j.Logger) Collections.emptyList(java.util.Collections.emptyList) Maybe(io.reactivex.Maybe) LoggerFactory(org.slf4j.LoggerFactory) HttpServletResponse(javax.servlet.http.HttpServletResponse) Autowired(org.springframework.beans.factory.annotation.Autowired) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) Request(io.gravitee.am.identityprovider.api.common.Request) IOException(java.io.IOException) IdentityProvider(io.gravitee.am.model.IdentityProvider) Controller(org.springframework.stereotype.Controller) Collectors(java.util.stream.Collectors) RandomString(io.gravitee.am.common.utils.RandomString) ModelAndView(org.springframework.web.servlet.ModelAndView) HttpServletRequest(javax.servlet.http.HttpServletRequest) OrganizationService(io.gravitee.am.service.OrganizationService) DEFAULT_REDIRECT_COOKIE_NAME(io.gravitee.am.management.handlers.management.api.authentication.provider.generator.RedirectCookieGenerator.DEFAULT_REDIRECT_COOKIE_NAME) ReCaptchaService(io.gravitee.am.service.ReCaptchaService) SocialAuthenticationProvider(io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider) Request(io.gravitee.am.identityprovider.api.common.Request) HttpServletRequest(javax.servlet.http.HttpServletRequest) ModelAndView(org.springframework.web.servlet.ModelAndView) IdentityProvider(io.gravitee.am.model.IdentityProvider) RandomString(io.gravitee.am.common.utils.RandomString) IOException(java.io.IOException) SocialAuthenticationProvider(io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 5 with SocialAuthenticationProvider

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);
                }
            });
        });
    });
}
Also used : JWT(io.gravitee.am.common.jwt.JWT) Request(io.gravitee.am.identityprovider.api.common.Request) UriBuilderRequest(io.gravitee.am.gateway.handler.common.vertx.utils.UriBuilderRequest) SocialAuthenticationProvider(io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider)

Aggregations

Request (io.gravitee.am.identityprovider.api.common.Request)5 SocialAuthenticationProvider (io.gravitee.am.identityprovider.api.social.SocialAuthenticationProvider)5 JWT (io.gravitee.am.common.jwt.JWT)4 UriBuilderRequest (io.gravitee.am.gateway.handler.common.vertx.utils.UriBuilderRequest)4 User (io.gravitee.am.model.User)3 Client (io.gravitee.am.model.oidc.Client)3 WebClient (io.vertx.reactivex.ext.web.client.WebClient)3 CertificateProvider (io.gravitee.am.gateway.certificate.CertificateProvider)2 Maybe (io.reactivex.Maybe)2 HashMap (java.util.HashMap)2 Test (org.junit.Test)2 Logger (org.slf4j.Logger)2 LoggerFactory (org.slf4j.LoggerFactory)2 Parameters (io.gravitee.am.common.oidc.Parameters)1 ConstantKeys (io.gravitee.am.common.utils.ConstantKeys)1 RandomString (io.gravitee.am.common.utils.RandomString)1 UriBuilder (io.gravitee.am.common.web.UriBuilder)1 IdentityProviderManager (io.gravitee.am.gateway.handler.common.auth.idp.IdentityProviderManager)1 EndUserAuthentication (io.gravitee.am.gateway.handler.common.auth.user.EndUserAuthentication)1 CertificateManager (io.gravitee.am.gateway.handler.common.certificate.CertificateManager)1