Search in sources :

Example 1 with AdminAuth

use of org.keycloak.services.resources.admin.AdminAuth in project keycloak by keycloak.

the class DefaultTokenExchangeProvider method tokenExchange.

protected Response tokenExchange() {
    UserModel tokenUser = null;
    UserSessionModel tokenSession = null;
    AccessToken token = null;
    String subjectToken = formParams.getFirst(OAuth2Constants.SUBJECT_TOKEN);
    if (subjectToken != null) {
        String subjectTokenType = formParams.getFirst(OAuth2Constants.SUBJECT_TOKEN_TYPE);
        String realmIssuerUrl = Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName());
        String subjectIssuer = formParams.getFirst(OAuth2Constants.SUBJECT_ISSUER);
        if (subjectIssuer == null && OAuth2Constants.JWT_TOKEN_TYPE.equals(subjectTokenType)) {
            try {
                JWSInput jws = new JWSInput(subjectToken);
                JsonWebToken jwt = jws.readJsonContent(JsonWebToken.class);
                subjectIssuer = jwt.getIssuer();
            } catch (JWSInputException e) {
                event.detail(Details.REASON, "unable to parse jwt subject_token");
                event.error(Errors.INVALID_TOKEN);
                throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_TOKEN, "Invalid token type, must be access token", Response.Status.BAD_REQUEST);
            }
        }
        if (subjectIssuer != null && !realmIssuerUrl.equals(subjectIssuer)) {
            event.detail(OAuth2Constants.SUBJECT_ISSUER, subjectIssuer);
            return exchangeExternalToken(subjectIssuer, subjectToken);
        }
        if (subjectTokenType != null && !subjectTokenType.equals(OAuth2Constants.ACCESS_TOKEN_TYPE)) {
            event.detail(Details.REASON, "subject_token supports access tokens only");
            event.error(Errors.INVALID_TOKEN);
            throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_TOKEN, "Invalid token type, must be access token", Response.Status.BAD_REQUEST);
        }
        AuthenticationManager.AuthResult authResult = AuthenticationManager.verifyIdentityToken(session, realm, session.getContext().getUri(), clientConnection, true, true, null, false, subjectToken, headers);
        if (authResult == null) {
            event.detail(Details.REASON, "subject_token validation failure");
            event.error(Errors.INVALID_TOKEN);
            throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_TOKEN, "Invalid token", Response.Status.BAD_REQUEST);
        }
        tokenUser = authResult.getUser();
        tokenSession = authResult.getSession();
        token = authResult.getToken();
    }
    String requestedSubject = formParams.getFirst(OAuth2Constants.REQUESTED_SUBJECT);
    if (requestedSubject != null) {
        event.detail(Details.REQUESTED_SUBJECT, requestedSubject);
        UserModel requestedUser = session.users().getUserByUsername(realm, requestedSubject);
        if (requestedUser == null) {
            requestedUser = session.users().getUserById(realm, requestedSubject);
        }
        if (requestedUser == null) {
            // We always returned access denied to avoid username fishing
            event.detail(Details.REASON, "requested_subject not found");
            event.error(Errors.NOT_ALLOWED);
            throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
        }
        if (token != null) {
            event.detail(Details.IMPERSONATOR, tokenUser.getUsername());
            // for this case, the user represented by the token, must have permission to impersonate.
            AdminAuth auth = new AdminAuth(realm, token, tokenUser, client);
            if (!AdminPermissions.evaluator(session, realm, auth).users().canImpersonate(requestedUser)) {
                event.detail(Details.REASON, "subject not allowed to impersonate");
                event.error(Errors.NOT_ALLOWED);
                throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
            }
        } else {
            // to impersonate
            if (client.isPublicClient()) {
                event.detail(Details.REASON, "public clients not allowed");
                event.error(Errors.NOT_ALLOWED);
                throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
            }
            if (!AdminPermissions.management(session, realm).users().canClientImpersonate(client, requestedUser)) {
                event.detail(Details.REASON, "client not allowed to impersonate");
                event.error(Errors.NOT_ALLOWED);
                throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
            }
        }
        tokenSession = session.sessions().createUserSession(realm, requestedUser, requestedUser.getUsername(), clientConnection.getRemoteAddr(), "impersonate", false, null, null);
        if (tokenUser != null) {
            tokenSession.setNote(IMPERSONATOR_ID.toString(), tokenUser.getId());
            tokenSession.setNote(IMPERSONATOR_USERNAME.toString(), tokenUser.getUsername());
        }
        tokenUser = requestedUser;
    }
    String requestedIssuer = formParams.getFirst(OAuth2Constants.REQUESTED_ISSUER);
    if (requestedIssuer == null) {
        return exchangeClientToClient(tokenUser, tokenSession);
    } else {
        try {
            return exchangeToIdentityProvider(tokenUser, tokenSession, requestedIssuer);
        } finally {
            if (subjectToken == null) {
                // we are naked! So need to clean up user session
                try {
                    session.sessions().removeUserSession(realm, tokenSession);
                } catch (Exception ignore) {
                }
            }
        }
    }
}
Also used : UserModel(org.keycloak.models.UserModel) AuthenticationManager(org.keycloak.services.managers.AuthenticationManager) AdminAuth(org.keycloak.services.resources.admin.AdminAuth) UserSessionModel(org.keycloak.models.UserSessionModel) AccessToken(org.keycloak.representations.AccessToken) JWSInputException(org.keycloak.jose.jws.JWSInputException) JWSInput(org.keycloak.jose.jws.JWSInput) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) JsonWebToken(org.keycloak.representations.JsonWebToken) OAuthErrorException(org.keycloak.OAuthErrorException) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) JWSInputException(org.keycloak.jose.jws.JWSInputException)

Example 2 with AdminAuth

use of org.keycloak.services.resources.admin.AdminAuth in project keycloak by keycloak.

the class ProtectionService method createAdminEventBuilder.

private AdminEventBuilder createAdminEventBuilder(KeycloakIdentity identity, ResourceServer resourceServer) {
    RealmModel realm = authorization.getRealm();
    ClientModel client = realm.getClientById(resourceServer.getId());
    KeycloakSession keycloakSession = authorization.getKeycloakSession();
    UserModel serviceAccount = keycloakSession.users().getServiceAccount(client);
    AdminEventBuilder adminEvent = new AdminEventBuilder(realm, new AdminAuth(realm, identity.getAccessToken(), serviceAccount, client), keycloakSession, clientConnection);
    return adminEvent.realm(realm).authClient(client).authUser(serviceAccount);
}
Also used : RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) AdminAuth(org.keycloak.services.resources.admin.AdminAuth) ClientModel(org.keycloak.models.ClientModel) KeycloakSession(org.keycloak.models.KeycloakSession) AdminEventBuilder(org.keycloak.services.resources.admin.AdminEventBuilder)

Aggregations

UserModel (org.keycloak.models.UserModel)2 AdminAuth (org.keycloak.services.resources.admin.AdminAuth)2 OAuthErrorException (org.keycloak.OAuthErrorException)1 JWSInput (org.keycloak.jose.jws.JWSInput)1 JWSInputException (org.keycloak.jose.jws.JWSInputException)1 ClientModel (org.keycloak.models.ClientModel)1 KeycloakSession (org.keycloak.models.KeycloakSession)1 RealmModel (org.keycloak.models.RealmModel)1 UserSessionModel (org.keycloak.models.UserSessionModel)1 AccessToken (org.keycloak.representations.AccessToken)1 JsonWebToken (org.keycloak.representations.JsonWebToken)1 CorsErrorResponseException (org.keycloak.services.CorsErrorResponseException)1 AuthenticationManager (org.keycloak.services.managers.AuthenticationManager)1 AdminEventBuilder (org.keycloak.services.resources.admin.AdminEventBuilder)1