Search in sources :

Example 51 with AccessTokenResponse

use of org.keycloak.representations.AccessTokenResponse in project keycloak by keycloak.

the class DefaultTokenExchangeProvider method exchangeClientToOIDCClient.

protected Response exchangeClientToOIDCClient(UserModel targetUser, UserSessionModel targetUserSession, String requestedTokenType, ClientModel targetClient, String audience, String scope) {
    RootAuthenticationSessionModel rootAuthSession = new AuthenticationSessionManager(session).createAuthenticationSession(realm, false);
    AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(targetClient);
    authSession.setAuthenticatedUser(targetUser);
    authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
    authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName()));
    authSession.setClientNote(OIDCLoginProtocol.SCOPE_PARAM, scope);
    event.session(targetUserSession);
    AuthenticationManager.setClientScopesInSession(authSession);
    ClientSessionContext clientSessionCtx = TokenManager.attachAuthenticationSession(this.session, targetUserSession, authSession);
    updateUserSessionFromClientAuth(targetUserSession);
    TokenManager.AccessTokenResponseBuilder responseBuilder = tokenManager.responseBuilder(realm, targetClient, event, this.session, targetUserSession, clientSessionCtx).generateAccessToken();
    responseBuilder.getAccessToken().issuedFor(client.getClientId());
    if (audience != null) {
        responseBuilder.getAccessToken().addAudience(audience);
    }
    if (requestedTokenType.equals(OAuth2Constants.REFRESH_TOKEN_TYPE) && OIDCAdvancedConfigWrapper.fromClientModel(client).isUseRefreshToken()) {
        responseBuilder.generateRefreshToken();
        responseBuilder.getRefreshToken().issuedFor(client.getClientId());
    }
    String scopeParam = clientSessionCtx.getClientSession().getNote(OAuth2Constants.SCOPE);
    if (TokenUtil.isOIDCRequest(scopeParam)) {
        responseBuilder.generateIDToken().generateAccessTokenHash();
    }
    AccessTokenResponse res = responseBuilder.build();
    event.detail(Details.AUDIENCE, targetClient.getClientId());
    event.success();
    return cors.builder(Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).build();
}
Also used : AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) ClientSessionContext(org.keycloak.models.ClientSessionContext) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse)

Example 52 with AccessTokenResponse

use of org.keycloak.representations.AccessTokenResponse in project keycloak by keycloak.

the class OIDCLoginProtocol method authenticated.

@Override
public Response authenticated(AuthenticationSessionModel authSession, UserSessionModel userSession, ClientSessionContext clientSessionCtx) {
    AuthenticatedClientSessionModel clientSession = clientSessionCtx.getClientSession();
    if (isOAuth2DeviceVerificationFlow(authSession)) {
        return approveOAuth2DeviceAuthorization(authSession, clientSession, session);
    }
    String responseTypeParam = authSession.getClientNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM);
    String responseModeParam = authSession.getClientNote(OIDCLoginProtocol.RESPONSE_MODE_PARAM);
    setupResponseTypeAndMode(responseTypeParam, responseModeParam);
    String redirect = authSession.getRedirectUri();
    OIDCRedirectUriBuilder redirectUri = OIDCRedirectUriBuilder.fromUri(redirect, responseMode, session, clientSession);
    String state = authSession.getClientNote(OIDCLoginProtocol.STATE_PARAM);
    logger.debugv("redirectAccessCode: state: {0}", state);
    if (state != null)
        redirectUri.addParam(OAuth2Constants.STATE, state);
    OIDCAdvancedConfigWrapper clientConfig = OIDCAdvancedConfigWrapper.fromClientModel(clientSession.getClient());
    if (!clientConfig.isExcludeSessionStateFromAuthResponse()) {
        redirectUri.addParam(OAuth2Constants.SESSION_STATE, userSession.getId());
    }
    String nonce = authSession.getClientNote(OIDCLoginProtocol.NONCE_PARAM);
    clientSessionCtx.setAttribute(OIDCLoginProtocol.NONCE_PARAM, nonce);
    String kcActionStatus = authSession.getClientNote(Constants.KC_ACTION_STATUS);
    if (kcActionStatus != null) {
        redirectUri.addParam(Constants.KC_ACTION_STATUS, kcActionStatus);
    }
    // Standard or hybrid flow
    String code = null;
    if (responseType.hasResponseType(OIDCResponseType.CODE)) {
        OAuth2Code codeData = new OAuth2Code(UUID.randomUUID(), Time.currentTime() + userSession.getRealm().getAccessCodeLifespan(), nonce, authSession.getClientNote(OAuth2Constants.SCOPE), authSession.getClientNote(OIDCLoginProtocol.REDIRECT_URI_PARAM), authSession.getClientNote(OIDCLoginProtocol.CODE_CHALLENGE_PARAM), authSession.getClientNote(OIDCLoginProtocol.CODE_CHALLENGE_METHOD_PARAM));
        code = OAuth2CodeParser.persistCode(session, clientSession, codeData);
        redirectUri.addParam(OAuth2Constants.CODE, code);
    }
    // Implicit or hybrid flow
    if (responseType.isImplicitOrHybridFlow()) {
        org.keycloak.protocol.oidc.TokenManager tokenManager = new org.keycloak.protocol.oidc.TokenManager();
        org.keycloak.protocol.oidc.TokenManager.AccessTokenResponseBuilder responseBuilder = tokenManager.responseBuilder(realm, clientSession.getClient(), event, session, userSession, clientSessionCtx).generateAccessToken();
        if (responseType.hasResponseType(OIDCResponseType.ID_TOKEN)) {
            responseBuilder.generateIDToken(isIdTokenAsDetachedSignature(clientSession.getClient()));
            if (responseType.hasResponseType(OIDCResponseType.TOKEN)) {
                responseBuilder.generateAccessTokenHash();
            }
            if (responseType.hasResponseType(OIDCResponseType.CODE)) {
                responseBuilder.generateCodeHash(code);
            }
            // http://openid.net/specs/openid-financial-api-part-2.html#authorization-server
            if (state != null && !state.isEmpty())
                responseBuilder.generateStateHash(state);
        }
        AccessTokenResponse res = responseBuilder.build();
        if (responseType.hasResponseType(OIDCResponseType.ID_TOKEN)) {
            redirectUri.addParam(OAuth2Constants.ID_TOKEN, res.getIdToken());
        }
        if (responseType.hasResponseType(OIDCResponseType.TOKEN)) {
            redirectUri.addParam(OAuth2Constants.ACCESS_TOKEN, res.getToken());
            redirectUri.addParam(OAuth2Constants.TOKEN_TYPE, res.getTokenType());
            redirectUri.addParam(OAuth2Constants.EXPIRES_IN, String.valueOf(res.getExpiresIn()));
        }
    }
    return redirectUri.build();
}
Also used : AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) OIDCRedirectUriBuilder(org.keycloak.protocol.oidc.utils.OIDCRedirectUriBuilder) OAuth2Code(org.keycloak.protocol.oidc.utils.OAuth2Code) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse)

Example 53 with AccessTokenResponse

use of org.keycloak.representations.AccessTokenResponse in project keycloak by keycloak.

the class AuthUtil method ensureToken.

public static String ensureToken(ConfigData config) {
    checkAuthInfo(config);
    RealmConfigData realmConfig = config.sessionRealmConfigData();
    long now = currentTimeMillis();
    // if it's less than 5s to expiry, renew it
    if (realmConfig.getExpiresAt() - now < 5000) {
        // if it's less than 5s to expiry, fail with credentials expired
        if (realmConfig.getRefreshExpiresAt() != null && realmConfig.getRefreshExpiresAt() - now < 5000) {
            throw new RuntimeException("Session has expired. Login again with '" + OsUtil.CMD + " config credentials'");
        }
        if (realmConfig.getSigExpiresAt() != null && realmConfig.getSigExpiresAt() - now < 5000) {
            throw new RuntimeException("Session has expired. Login again with '" + OsUtil.CMD + " config credentials'");
        }
        try {
            String authorization = null;
            StringBuilder body = new StringBuilder();
            if (realmConfig.getRefreshToken() != null) {
                body.append("grant_type=refresh_token").append("&refresh_token=").append(realmConfig.getRefreshToken());
            } else {
                body.append("grant_type=").append(realmConfig.getGrantTypeForAuthentication());
            }
            body.append("&client_id=").append(urlencode(realmConfig.getClientId()));
            if (realmConfig.getSigningToken() != null) {
                body.append("&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer").append("&client_assertion=").append(realmConfig.getSigningToken());
            } else if (realmConfig.getSecret() != null) {
                authorization = BasicAuthHelper.createHeader(realmConfig.getClientId(), realmConfig.getSecret());
            }
            InputStream result = doPost(realmConfig.serverUrl() + "/realms/" + realmConfig.realm() + "/protocol/openid-connect/token", APPLICATION_FORM_URL_ENCODED, APPLICATION_JSON, body.toString(), authorization);
            AccessTokenResponse token = JsonSerialization.readValue(result, AccessTokenResponse.class);
            saveMergeConfig(cfg -> {
                RealmConfigData realmData = cfg.sessionRealmConfigData();
                realmData.setToken(token.getToken());
                realmData.setRefreshToken(token.getRefreshToken());
                realmData.setExpiresAt(currentTimeMillis() + token.getExpiresIn() * 1000);
                if (token.getRefreshToken() != null) {
                    realmData.setRefreshExpiresAt(currentTimeMillis() + token.getRefreshExpiresIn() * 1000);
                }
            });
            return token.getToken();
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Unexpected error", e);
        } catch (IOException e) {
            throw new RuntimeException("Failed to read Refresh Token response", e);
        }
    }
    return realmConfig.getToken();
}
Also used : RealmConfigData(org.keycloak.client.registration.cli.config.RealmConfigData) InputStream(java.io.InputStream) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse)

Example 54 with AccessTokenResponse

use of org.keycloak.representations.AccessTokenResponse in project keycloak by keycloak.

the class SocialLoginTest method testTokenExchange.

protected void testTokenExchange() {
    List<UserRepresentation> users = adminClient.realm(REALM).users().search(null, null, null);
    Assert.assertEquals(1, users.size());
    String username = users.get(0).getUsername();
    checkFeature(501, username);
    Response tokenResp = testingClient.testing().enableFeature(Profile.Feature.TOKEN_EXCHANGE.toString());
    assertEquals(200, tokenResp.getStatus());
    ProfileAssume.assumeFeatureEnabled(Profile.Feature.TOKEN_EXCHANGE);
    Client httpClient = AdminClientUtil.createResteasyClient();
    try {
        AccessTokenResponse tokenResponse = checkFeature(200, username);
        Assert.assertNotNull(tokenResponse);
        String socialToken = tokenResponse.getToken();
        Assert.assertNotNull(socialToken);
        // remove all users
        removeUser();
        users = adminClient.realm(REALM).users().search(null, null, null);
        Assert.assertEquals(0, users.size());
        // now try external exchange where we trust social provider and import the external token.
        Response response = getExchangeUrl(httpClient).request().header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(EXCHANGE_CLIENT, "secret")).post(Entity.form(new Form().param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE).param(OAuth2Constants.SUBJECT_TOKEN, socialToken).param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE).param(OAuth2Constants.SUBJECT_ISSUER, currentTestProvider.id())));
        Assert.assertEquals(200, response.getStatus());
        response.close();
        users = adminClient.realm(REALM).users().search(null, null, null);
        Assert.assertEquals(1, users.size());
        Assert.assertEquals(username, users.get(0).getUsername());
        // remove all users
        removeUser();
        users = adminClient.realm(REALM).users().search(null, null, null);
        Assert.assertEquals(0, users.size());
        // /// Test that we can update social token from session with stored tokens turned off.
        // turn off store token
        IdentityProviderRepresentation idp = adminClient.realm(REALM).identityProviders().get(currentTestProvider.id).toRepresentation();
        idp.setStoreToken(false);
        adminClient.realm(REALM).identityProviders().get(idp.getAlias()).update(idp);
        // first exchange social token to get a user session that should store the social token there
        response = getExchangeUrl(httpClient).request().header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(EXCHANGE_CLIENT, "secret")).post(Entity.form(new Form().param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE).param(OAuth2Constants.SUBJECT_TOKEN, socialToken).param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE).param(OAuth2Constants.SUBJECT_ISSUER, currentTestProvider.id())));
        Assert.assertEquals(200, response.getStatus());
        tokenResponse = response.readEntity(AccessTokenResponse.class);
        String keycloakToken = tokenResponse.getToken();
        response.close();
        // now take keycloak token and make sure it can get back the social token from the user session since stored tokens are off
        response = getExchangeUrl(httpClient).request().header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(EXCHANGE_CLIENT, "secret")).post(Entity.form(new Form().param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE).param(OAuth2Constants.SUBJECT_TOKEN, keycloakToken).param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE).param(OAuth2Constants.REQUESTED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE).param(OAuth2Constants.REQUESTED_ISSUER, currentTestProvider.id())));
        Assert.assertEquals(200, response.getStatus());
        tokenResponse = response.readEntity(AccessTokenResponse.class);
        response.close();
        Assert.assertEquals(socialToken, tokenResponse.getToken());
        // turn on store token
        idp = adminClient.realm(REALM).identityProviders().get(currentTestProvider.id).toRepresentation();
        idp.setStoreToken(true);
        adminClient.realm(REALM).identityProviders().get(idp.getAlias()).update(idp);
    } finally {
        httpClient.close();
        tokenResp = testingClient.testing().disableFeature(Profile.Feature.TOKEN_EXCHANGE.toString());
        assertEquals(200, tokenResp.getStatus());
        checkFeature(501, username);
    }
}
Also used : AccessTokenResponse(org.keycloak.representations.AccessTokenResponse) Response(javax.ws.rs.core.Response) Form(javax.ws.rs.core.Form) IdentityProviderRepresentation(org.keycloak.representations.idm.IdentityProviderRepresentation) OAuthClient(org.keycloak.testsuite.util.OAuthClient) Client(javax.ws.rs.client.Client) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse) UserRepresentation(org.keycloak.representations.idm.UserRepresentation)

Example 55 with AccessTokenResponse

use of org.keycloak.representations.AccessTokenResponse in project keycloak by keycloak.

the class SocialLoginTest method checkFeature.

private AccessTokenResponse checkFeature(int expectedStatusCode, String username) {
    Client httpClient = AdminClientUtil.createResteasyClient();
    Response response = null;
    try {
        testingClient.server().run(SocialLoginTest::setupClientExchangePermissions);
        WebTarget exchangeUrl = getExchangeUrl(httpClient);
        response = exchangeUrl.request().header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader(EXCHANGE_CLIENT, "secret")).post(Entity.form(new Form().param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE).param(OAuth2Constants.REQUESTED_SUBJECT, username).param(OAuth2Constants.REQUESTED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE).param(OAuth2Constants.REQUESTED_ISSUER, currentTestProvider.id())));
        Assert.assertEquals(expectedStatusCode, response.getStatus());
        if (expectedStatusCode == Response.Status.OK.getStatusCode())
            return response.readEntity(AccessTokenResponse.class);
        else
            return null;
    } finally {
        if (response != null)
            response.close();
        httpClient.close();
    }
}
Also used : AccessTokenResponse(org.keycloak.representations.AccessTokenResponse) Response(javax.ws.rs.core.Response) Form(javax.ws.rs.core.Form) WebTarget(javax.ws.rs.client.WebTarget) OAuthClient(org.keycloak.testsuite.util.OAuthClient) Client(javax.ws.rs.client.Client) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse)

Aggregations

AccessTokenResponse (org.keycloak.representations.AccessTokenResponse)73 Response (javax.ws.rs.core.Response)30 Test (org.junit.Test)29 OAuthClient (org.keycloak.testsuite.util.OAuthClient)25 Client (javax.ws.rs.client.Client)24 AbstractKeycloakTest (org.keycloak.testsuite.AbstractKeycloakTest)17 Form (javax.ws.rs.core.Form)15 WebTarget (javax.ws.rs.client.WebTarget)14 AccessToken (org.keycloak.representations.AccessToken)14 IOException (java.io.IOException)12 ClientResource (org.keycloak.admin.client.resource.ClientResource)7 AuthorizationResponse (org.keycloak.representations.idm.authorization.AuthorizationResponse)7 AuthzClient (org.keycloak.authorization.client.AuthzClient)5 PermissionRequest (org.keycloak.representations.idm.authorization.PermissionRequest)5 CorsErrorResponseException (org.keycloak.services.CorsErrorResponseException)5 UncaughtServerErrorExpected (org.keycloak.testsuite.arquillian.annotation.UncaughtServerErrorExpected)5 InputStream (java.io.InputStream)4 URI (java.net.URI)4 NameValuePair (org.apache.http.NameValuePair)4 UrlEncodedFormEntity (org.apache.http.client.entity.UrlEncodedFormEntity)4