Search in sources :

Example 16 with ClientPolicyException

use of org.keycloak.services.clientpolicy.ClientPolicyException in project keycloak by keycloak.

the class HolderOfKeyEnforcerExecutor method checkUserInfo.

private void checkUserInfo(UserInfoRequestContext context, HttpRequest request) throws ClientPolicyException {
    String encodedAccessToken = context.getTokenString();
    AccessToken accessToken = session.tokens().decode(encodedAccessToken, AccessToken.class);
    if (accessToken == null) {
        // this executor does not treat this error case.
        return;
    }
    if (!MtlsHoKTokenUtil.verifyTokenBindingWithClientCertificate(accessToken, request, session)) {
        throw new ClientPolicyException(Errors.NOT_ALLOWED, MtlsHoKTokenUtil.CERT_VERIFY_ERROR_DESC, Response.Status.UNAUTHORIZED);
    }
}
Also used : AccessToken(org.keycloak.representations.AccessToken) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException)

Example 17 with ClientPolicyException

use of org.keycloak.services.clientpolicy.ClientPolicyException in project keycloak by keycloak.

the class ClientRegistrationAuth method requireUpdate.

public RegistrationAuth requireUpdate(ClientRegistrationContext context, ClientModel client) {
    RegistrationAuth regAuth = requireUpdateAuth(client);
    try {
        session.clientPolicy().triggerOnEvent(new DynamicClientUpdateContext(context, client, jwt, realm));
        ClientRegistrationPolicyManager.triggerBeforeUpdate(context, regAuth, client);
    } catch (ClientRegistrationPolicyException | ClientPolicyException crpe) {
        throw forbidden(crpe.getMessage());
    }
    return regAuth;
}
Also used : RegistrationAuth(org.keycloak.services.clientregistration.policy.RegistrationAuth) DynamicClientUpdateContext(org.keycloak.services.clientpolicy.context.DynamicClientUpdateContext) ClientRegistrationPolicyException(org.keycloak.services.clientregistration.policy.ClientRegistrationPolicyException) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException)

Example 18 with ClientPolicyException

use of org.keycloak.services.clientpolicy.ClientPolicyException in project keycloak by keycloak.

the class AbstractClientRegistrationProvider method create.

public ClientRepresentation create(ClientRegistrationContext context) {
    ClientRepresentation client = context.getClient();
    event.event(EventType.CLIENT_REGISTER);
    RegistrationAuth registrationAuth = auth.requireCreate(context);
    try {
        RealmModel realm = session.getContext().getRealm();
        ClientModel clientModel = ClientManager.createClient(session, realm, client);
        if (client.getDefaultRoles() != null) {
            for (String name : client.getDefaultRoles()) {
                clientModel.addDefaultRole(name);
            }
        }
        if (clientModel.isServiceAccountsEnabled()) {
            new ClientManager(new RealmManager(session)).enableServiceAccount(clientModel);
        }
        if (Boolean.TRUE.equals(client.getAuthorizationServicesEnabled())) {
            RepresentationToModel.createResourceServer(clientModel, session, true);
        }
        session.clientPolicy().triggerOnEvent(new DynamicClientRegisteredContext(context, clientModel, auth.getJwt(), realm));
        ClientRegistrationPolicyManager.triggerAfterRegister(context, registrationAuth, clientModel);
        client = ModelToRepresentation.toRepresentation(clientModel, session);
        client.setSecret(clientModel.getSecret());
        String registrationAccessToken = ClientRegistrationTokenUtils.updateRegistrationAccessToken(session, clientModel, registrationAuth);
        client.setRegistrationAccessToken(registrationAccessToken);
        if (auth.isInitialAccessToken()) {
            ClientInitialAccessModel initialAccessModel = auth.getInitialAccessModel();
            session.realms().decreaseRemainingCount(realm, initialAccessModel);
        }
        client.setDirectAccessGrantsEnabled(false);
        Stream<String> defaultRolesNames = clientModel.getDefaultRolesStream();
        if (defaultRolesNames != null) {
            client.setDefaultRoles(defaultRolesNames.toArray(String[]::new));
        }
        event.client(client.getClientId()).success();
        return client;
    } catch (ModelDuplicateException e) {
        throw new ErrorResponseException(ErrorCodes.INVALID_CLIENT_METADATA, "Client Identifier in use", Response.Status.BAD_REQUEST);
    } catch (ClientPolicyException cpe) {
        throw new ErrorResponseException(cpe.getError(), cpe.getErrorDetail(), Response.Status.BAD_REQUEST);
    }
}
Also used : ClientInitialAccessModel(org.keycloak.models.ClientInitialAccessModel) RegistrationAuth(org.keycloak.services.clientregistration.policy.RegistrationAuth) DynamicClientRegisteredContext(org.keycloak.services.clientpolicy.context.DynamicClientRegisteredContext) RealmManager(org.keycloak.services.managers.RealmManager) ClientRepresentation(org.keycloak.representations.idm.ClientRepresentation) OIDCClientRepresentation(org.keycloak.representations.oidc.OIDCClientRepresentation) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException) RealmModel(org.keycloak.models.RealmModel) ClientModel(org.keycloak.models.ClientModel) ClientManager(org.keycloak.services.managers.ClientManager) ModelDuplicateException(org.keycloak.models.ModelDuplicateException) ErrorResponseException(org.keycloak.services.ErrorResponseException)

Example 19 with ClientPolicyException

use of org.keycloak.services.clientpolicy.ClientPolicyException in project keycloak by keycloak.

the class ParEndpoint method request.

@Path("/")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON)
public Response request() {
    ProfileHelper.requireFeature(Profile.Feature.PAR);
    cors = Cors.add(httpRequest).auth().allowedMethods("POST").auth().exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS);
    event.event(EventType.PUSHED_AUTHORIZATION_REQUEST);
    checkSsl();
    checkRealm();
    authorizeClient();
    if (httpRequest.getDecodedFormParameters().containsKey(REQUEST_URI_PARAM)) {
        throw throwErrorResponseException(OAuthErrorException.INVALID_REQUEST, "It is not allowed to include request_uri to PAR.", Response.Status.BAD_REQUEST);
    }
    try {
        authorizationRequest = AuthorizationEndpointRequestParserProcessor.parseRequest(event, session, client, httpRequest.getDecodedFormParameters());
    } catch (Exception e) {
        throw throwErrorResponseException(OAuthErrorException.INVALID_REQUEST_OBJECT, e.getMessage(), Response.Status.BAD_REQUEST);
    }
    AuthorizationEndpointChecker checker = new AuthorizationEndpointChecker().event(event).client(client).realm(realm).request(authorizationRequest).session(session);
    try {
        checker.checkRedirectUri();
    } catch (AuthorizationEndpointChecker.AuthorizationCheckException ex) {
        throw throwErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Invalid parameter: redirect_uri", Response.Status.BAD_REQUEST);
    }
    try {
        checker.checkResponseType();
    } catch (AuthorizationEndpointChecker.AuthorizationCheckException ex) {
        if (ex.getError().equals(OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE)) {
            throw throwErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Unsupported response type", Response.Status.BAD_REQUEST);
        } else {
            ex.throwAsCorsErrorResponseException(cors);
        }
    }
    try {
        checker.checkValidScope();
    } catch (AuthorizationEndpointChecker.AuthorizationCheckException ex) {
        // PAR throws this as "invalid_request" error
        throw throwErrorResponseException(OAuthErrorException.INVALID_REQUEST, ex.getErrorDescription(), Response.Status.BAD_REQUEST);
    }
    try {
        checker.checkInvalidRequestMessage();
        checker.checkOIDCRequest();
        checker.checkOIDCParams();
        checker.checkPKCEParams();
    } catch (AuthorizationEndpointChecker.AuthorizationCheckException ex) {
        ex.throwAsCorsErrorResponseException(cors);
    }
    try {
        session.clientPolicy().triggerOnEvent(new PushedAuthorizationRequestContext(authorizationRequest, httpRequest.getDecodedFormParameters()));
    } catch (ClientPolicyException cpe) {
        throw throwErrorResponseException(cpe.getError(), cpe.getErrorDetail(), Response.Status.BAD_REQUEST);
    }
    Map<String, String> params = new HashMap<>();
    UUID key = UUID.randomUUID();
    String requestUri = REQUEST_URI_PREFIX + key.toString();
    int expiresIn = realm.getParPolicy().getRequestUriLifespan();
    httpRequest.getDecodedFormParameters().forEach((k, v) -> {
        // PAR store only accepts Map so that MultivaluedMap needs to be converted to Map.
        String singleValue = String.valueOf(v).replace("[", "").replace("]", "");
        params.put(k, singleValue);
    });
    params.put(PAR_CREATED_TIME, String.valueOf(System.currentTimeMillis()));
    PushedAuthzRequestStoreProvider parStore = session.getProvider(PushedAuthzRequestStoreProvider.class);
    parStore.put(key, expiresIn, params);
    ParResponse parResponse = new ParResponse(requestUri, expiresIn);
    session.getProvider(SecurityHeadersProvider.class).options().allowEmptyContentType();
    return cors.builder(Response.status(Response.Status.CREATED).entity(parResponse).type(MediaType.APPLICATION_JSON_TYPE)).build();
}
Also used : PushedAuthzRequestStoreProvider(org.keycloak.models.PushedAuthzRequestStoreProvider) ParResponse(org.keycloak.protocol.oidc.par.ParResponse) AuthorizationEndpointChecker(org.keycloak.protocol.oidc.endpoints.AuthorizationEndpointChecker) HashMap(java.util.HashMap) PushedAuthorizationRequestContext(org.keycloak.protocol.oidc.par.clientpolicy.context.PushedAuthorizationRequestContext) UUID(java.util.UUID) OAuthErrorException(org.keycloak.OAuthErrorException) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Example 20 with ClientPolicyException

use of org.keycloak.services.clientpolicy.ClientPolicyException in project keycloak by keycloak.

the class TokenEndpoint method clientCredentialsGrant.

public Response clientCredentialsGrant() {
    if (client.isBearerOnly()) {
        event.error(Errors.INVALID_CLIENT);
        throw new CorsErrorResponseException(cors, OAuthErrorException.UNAUTHORIZED_CLIENT, "Bearer-only client not allowed to retrieve service account", Response.Status.UNAUTHORIZED);
    }
    if (client.isPublicClient()) {
        event.error(Errors.INVALID_CLIENT);
        throw new CorsErrorResponseException(cors, OAuthErrorException.UNAUTHORIZED_CLIENT, "Public client not allowed to retrieve service account", Response.Status.UNAUTHORIZED);
    }
    if (!client.isServiceAccountsEnabled()) {
        event.error(Errors.INVALID_CLIENT);
        throw new CorsErrorResponseException(cors, OAuthErrorException.UNAUTHORIZED_CLIENT, "Client not enabled to retrieve service account", Response.Status.UNAUTHORIZED);
    }
    UserModel clientUser = session.users().getServiceAccount(client);
    if (clientUser == null || client.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, ServiceAccountConstants.CLIENT_ID_PROTOCOL_MAPPER) == null) {
        // May need to handle bootstrap here as well
        logger.debugf("Service account user for client '%s' not found or default protocol mapper for service account not found. Creating now", client.getClientId());
        new ClientManager(new RealmManager(session)).enableServiceAccount(client);
        clientUser = session.users().getServiceAccount(client);
    }
    String clientUsername = clientUser.getUsername();
    event.detail(Details.USERNAME, clientUsername);
    event.user(clientUser);
    if (!clientUser.isEnabled()) {
        event.error(Errors.USER_DISABLED);
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "User '" + clientUsername + "' disabled", Response.Status.UNAUTHORIZED);
    }
    String scope = getRequestedScopes();
    RootAuthenticationSessionModel rootAuthSession = new AuthenticationSessionManager(session).createAuthenticationSession(realm, false);
    AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(client);
    authSession.setAuthenticatedUser(clientUser);
    authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
    authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName()));
    authSession.setClientNote(OIDCLoginProtocol.SCOPE_PARAM, scope);
    // persisting of userSession by default
    UserSessionModel.SessionPersistenceState sessionPersistenceState = UserSessionModel.SessionPersistenceState.PERSISTENT;
    boolean useRefreshToken = OIDCAdvancedConfigWrapper.fromClientModel(client).isUseRefreshTokenForClientCredentialsGrant();
    if (!useRefreshToken) {
        // we don't want to store a session hence we mark it as transient, see KEYCLOAK-9551
        sessionPersistenceState = UserSessionModel.SessionPersistenceState.TRANSIENT;
    }
    UserSessionModel userSession = session.sessions().createUserSession(authSession.getParentSession().getId(), realm, clientUser, clientUsername, clientConnection.getRemoteAddr(), ServiceAccountConstants.CLIENT_AUTH, false, null, null, sessionPersistenceState);
    event.session(userSession);
    AuthenticationManager.setClientScopesInSession(authSession);
    ClientSessionContext clientSessionCtx = TokenManager.attachAuthenticationSession(session, userSession, authSession);
    // Notes about client details
    userSession.setNote(ServiceAccountConstants.CLIENT_ID, client.getClientId());
    userSession.setNote(ServiceAccountConstants.CLIENT_HOST, clientConnection.getRemoteHost());
    userSession.setNote(ServiceAccountConstants.CLIENT_ADDRESS, clientConnection.getRemoteAddr());
    try {
        session.clientPolicy().triggerOnEvent(new ServiceAccountTokenRequestContext(formParams, clientSessionCtx.getClientSession()));
    } catch (ClientPolicyException cpe) {
        event.error(cpe.getError());
        throw new CorsErrorResponseException(cors, cpe.getError(), cpe.getErrorDetail(), Response.Status.BAD_REQUEST);
    }
    updateUserSessionFromClientAuth(userSession);
    TokenManager.AccessTokenResponseBuilder responseBuilder = tokenManager.responseBuilder(realm, client, event, session, userSession, clientSessionCtx).generateAccessToken();
    // Make refresh token generation optional, see KEYCLOAK-9551
    if (useRefreshToken) {
        responseBuilder = responseBuilder.generateRefreshToken();
    } else {
        responseBuilder.getAccessToken().setSessionState(null);
    }
    checkMtlsHoKToken(responseBuilder, useRefreshToken);
    String scopeParam = clientSessionCtx.getClientSession().getNote(OAuth2Constants.SCOPE);
    if (TokenUtil.isOIDCRequest(scopeParam)) {
        responseBuilder.generateIDToken().generateAccessTokenHash();
    }
    // TODO : do the same as codeToToken()
    AccessTokenResponse res = responseBuilder.build();
    event.success();
    return cors.builder(Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).build();
}
Also used : AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) UserSessionModel(org.keycloak.models.UserSessionModel) RealmManager(org.keycloak.services.managers.RealmManager) ServiceAccountTokenRequestContext(org.keycloak.services.clientpolicy.context.ServiceAccountTokenRequestContext) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException) UserModel(org.keycloak.models.UserModel) AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) DefaultClientSessionContext(org.keycloak.services.util.DefaultClientSessionContext) ClientSessionContext(org.keycloak.models.ClientSessionContext) ClientManager(org.keycloak.services.managers.ClientManager) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) TokenManager(org.keycloak.protocol.oidc.TokenManager) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse)

Aggregations

ClientPolicyException (org.keycloak.services.clientpolicy.ClientPolicyException)62 ClientRepresentation (org.keycloak.representations.idm.ClientRepresentation)23 Test (org.junit.Test)22 OIDCClientRepresentation (org.keycloak.representations.oidc.OIDCClientRepresentation)19 ClientPoliciesBuilder (org.keycloak.testsuite.util.ClientPoliciesUtil.ClientPoliciesBuilder)14 ClientPolicyBuilder (org.keycloak.testsuite.util.ClientPoliciesUtil.ClientPolicyBuilder)14 ClientProfileBuilder (org.keycloak.testsuite.util.ClientPoliciesUtil.ClientProfileBuilder)13 ClientProfilesBuilder (org.keycloak.testsuite.util.ClientPoliciesUtil.ClientProfilesBuilder)13 ClientModel (org.keycloak.models.ClientModel)11 ErrorResponseException (org.keycloak.services.ErrorResponseException)10 OAuthErrorException (org.keycloak.OAuthErrorException)9 UserSessionModel (org.keycloak.models.UserSessionModel)9 CorsErrorResponseException (org.keycloak.services.CorsErrorResponseException)9 UserModel (org.keycloak.models.UserModel)8 IOException (java.io.IOException)6 Consumes (javax.ws.rs.Consumes)6 POST (javax.ws.rs.POST)6 Response (javax.ws.rs.core.Response)6 ClientSessionContext (org.keycloak.models.ClientSessionContext)6 RegistrationAuth (org.keycloak.services.clientregistration.policy.RegistrationAuth)6