Search in sources :

Example 1 with Request

use of io.gravitee.am.identityprovider.api.common.Request 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 Request

use of io.gravitee.am.identityprovider.api.common.Request 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 Request

use of io.gravitee.am.identityprovider.api.common.Request 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 Request

use of io.gravitee.am.identityprovider.api.common.Request in project gravitee-access-management by gravitee-io.

the class AzureADAuthenticationProviderTest method shouldGenerateSignInUrl_withScope.

@Test
public void shouldGenerateSignInUrl_withScope() throws Exception {
    when(configuration.getClientId()).thenReturn("testClientId");
    when(configuration.getTenantId()).thenReturn(TEST_TENANT_ID);
    // LinkedHashSet to preserve order of scopes into the URI
    LinkedHashSet<String> scopes = new LinkedHashSet<>();
    scopes.add("other_scope");
    scopes.add("other_scope2");
    // openid scope will be added by default
    when(configuration.getScopes()).thenReturn(scopes);
    forceProviderInfoForTest();
    final String state = RandomString.generate();
    Request request = provider.signInUrl("https://gravitee.io", state);
    Assert.assertNotNull(request);
    assertEquals(HttpMethod.GET, request.getMethod());
    assertEquals("https://login.microsoftonline.com/" + TEST_TENANT_ID + "/oauth2/v2.0/authorize?client_id=testClientId&response_type=code&scope=other_scope other_scope2 openid profile email&state=" + state + "&redirect_uri=https://gravitee.io", request.getUri());
    assertNull(request.getHeaders());
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Request(io.gravitee.am.identityprovider.api.common.Request) RandomString(io.gravitee.am.common.utils.RandomString) Test(org.junit.Test)

Example 5 with Request

use of io.gravitee.am.identityprovider.api.common.Request in project gravitee-access-management by gravitee-io.

the class AbstractOpenIDConnectAuthenticationProvider method signInUrl.

@Override
public Request signInUrl(String redirectUri, String state) {
    try {
        if (getConfiguration().getUserAuthorizationUri() == null) {
            LOGGER.warn("Social Provider {} can't provide signInUrl, userAuthorizationUri is null", this.getClass().getSimpleName());
            return null;
        }
        UriBuilder builder = UriBuilder.fromHttpUrl(getConfiguration().getUserAuthorizationUri());
        builder.addParameter(Parameters.CLIENT_ID, getConfiguration().getClientId());
        builder.addParameter(Parameters.RESPONSE_TYPE, getConfiguration().getResponseType());
        // append scopes
        if (getConfiguration().getScopes() != null && !getConfiguration().getScopes().isEmpty()) {
            builder.addParameter(Parameters.SCOPE, String.join(SCOPE_DELIMITER, getConfiguration().getScopes()));
        }
        // nonce parameter is required for implicit/hybrid flow
        if (!io.gravitee.am.common.oauth2.ResponseType.CODE.equals(getConfiguration().getResponseType())) {
            builder.addParameter(io.gravitee.am.common.oidc.Parameters.NONCE, SecureRandomString.generate());
        }
        // add state if provided.
        if (!StringUtils.isEmpty(state)) {
            builder.addParameter(Parameters.STATE, state);
        }
        // append redirect_uri
        builder.addParameter(Parameters.REDIRECT_URI, getConfiguration().isEncodeRedirectUri() ? encodeURIComponent(redirectUri) : redirectUri);
        Request request = new Request();
        request.setMethod(HttpMethod.GET);
        request.setUri(builder.buildString());
        return request;
    } catch (Exception e) {
        LOGGER.error("An error has occurred while building OpenID Connect Sign In URL", e);
        return null;
    }
}
Also used : HttpRequest(io.vertx.reactivex.ext.web.client.HttpRequest) Request(io.gravitee.am.identityprovider.api.common.Request) UriBuilder(io.gravitee.am.common.web.UriBuilder) InternalAuthenticationServiceException(io.gravitee.am.common.exception.authentication.InternalAuthenticationServiceException) BadCredentialsException(io.gravitee.am.common.exception.authentication.BadCredentialsException)

Aggregations

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