Search in sources :

Example 11 with ErrorResponseException

use of org.keycloak.services.ErrorResponseException 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 12 with ErrorResponseException

use of org.keycloak.services.ErrorResponseException in project keycloak by keycloak.

the class OpenShiftTokenReviewEndpoint method authorizeClient.

private void authorizeClient() {
    try {
        ClientModel client = AuthorizeClientUtil.authorizeClient(session, event, null).getClient();
        event.client(client);
        if (client == null || client.isPublicClient()) {
            error(401, Errors.INVALID_CLIENT, "Public client is not permitted to invoke token review endpoint");
        }
    } catch (ErrorResponseException ere) {
        error(401, Errors.INVALID_CLIENT_CREDENTIALS, ere.getErrorDescription());
    } catch (Exception e) {
        error(401, Errors.INVALID_CLIENT_CREDENTIALS, null);
    }
}
Also used : ClientModel(org.keycloak.models.ClientModel) ErrorResponseException(org.keycloak.services.ErrorResponseException) ErrorResponseException(org.keycloak.services.ErrorResponseException) VerificationException(org.keycloak.common.VerificationException)

Example 13 with ErrorResponseException

use of org.keycloak.services.ErrorResponseException in project keycloak by keycloak.

the class TestingOIDCEndpointsApplicationResource method cibaClientNotificationEndpoint.

@POST
@Path("/push-ciba-client-notification")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public Response cibaClientNotificationEndpoint(@Context HttpHeaders headers, ClientNotificationEndpointRequest request) {
    String clientNotificationToken = AppAuthManager.extractAuthorizationHeaderToken(headers);
    ClientNotificationEndpointRequest existing = cibaClientNotifications.putIfAbsent(clientNotificationToken, request);
    if (existing != null) {
        throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "There is already entry for clientNotification " + clientNotificationToken + ". Make sure to cleanup after previous tests.", Response.Status.BAD_REQUEST);
    }
    return Response.noContent().build();
}
Also used : ClientNotificationEndpointRequest(org.keycloak.protocol.oidc.grants.ciba.endpoints.ClientNotificationEndpointRequest) ErrorResponseException(org.keycloak.services.ErrorResponseException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) NoCache(org.jboss.resteasy.annotations.cache.NoCache)

Example 14 with ErrorResponseException

use of org.keycloak.services.ErrorResponseException in project keycloak by keycloak.

the class LogoutEndpoint method backchannelLogout.

/**
 * Backchannel logout endpoint implementation for Keycloak, which tries to logout the user from all sessions via
 * POST with a valid LogoutToken.
 *
 * Logout a session via a non-browser invocation. Will be implemented as a backchannel logout based on the
 * specification
 * https://openid.net/specs/openid-connect-backchannel-1_0.html
 *
 * @return
 */
@Path("/backchannel-logout")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response backchannelLogout() {
    MultivaluedMap<String, String> form = request.getDecodedFormParameters();
    event.event(EventType.LOGOUT);
    String encodedLogoutToken = form.getFirst(OAuth2Constants.LOGOUT_TOKEN);
    if (encodedLogoutToken == null) {
        event.error(Errors.INVALID_TOKEN);
        throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "No logout token", Response.Status.BAD_REQUEST);
    }
    LogoutTokenValidationCode validationCode = tokenManager.verifyLogoutToken(session, realm, encodedLogoutToken);
    if (!validationCode.equals(LogoutTokenValidationCode.VALIDATION_SUCCESS)) {
        event.error(Errors.INVALID_TOKEN);
        throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, validationCode.getErrorMessage(), Response.Status.BAD_REQUEST);
    }
    LogoutToken logoutToken = tokenManager.toLogoutToken(encodedLogoutToken).get();
    Stream<String> identityProviderAliases = tokenManager.getValidOIDCIdentityProvidersForBackchannelLogout(realm, session, encodedLogoutToken, logoutToken).map(idp -> idp.getConfig().getAlias());
    boolean logoutOfflineSessions = Boolean.parseBoolean(logoutToken.getEvents().getOrDefault(TokenUtil.TOKEN_BACKCHANNEL_LOGOUT_EVENT_REVOKE_OFFLINE_TOKENS, false).toString());
    BackchannelLogoutResponse backchannelLogoutResponse;
    if (logoutToken.getSid() != null) {
        backchannelLogoutResponse = backchannelLogoutWithSessionId(logoutToken.getSid(), identityProviderAliases, logoutOfflineSessions, logoutToken.getSubject());
    } else {
        backchannelLogoutResponse = backchannelLogoutFederatedUserId(logoutToken.getSubject(), identityProviderAliases, logoutOfflineSessions);
    }
    if (!backchannelLogoutResponse.getLocalLogoutSucceeded()) {
        event.error(Errors.LOGOUT_FAILED);
        throw new ErrorResponseException(OAuthErrorException.SERVER_ERROR, "There was an error in the local logout", Response.Status.NOT_IMPLEMENTED);
    }
    session.getProvider(SecurityHeadersProvider.class).options().allowEmptyContentType();
    if (oneOrMoreDownstreamLogoutsFailed(backchannelLogoutResponse)) {
        return Cors.add(request).auth().builder(Response.status(Response.Status.GATEWAY_TIMEOUT).type(MediaType.APPLICATION_JSON_TYPE)).build();
    }
    return Cors.add(request).auth().builder(Response.ok().type(MediaType.APPLICATION_JSON_TYPE)).build();
}
Also used : LogoutTokenValidationCode(org.keycloak.protocol.oidc.LogoutTokenValidationCode) LogoutToken(org.keycloak.representations.LogoutToken) ErrorResponseException(org.keycloak.services.ErrorResponseException) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) BackchannelLogoutResponse(org.keycloak.protocol.oidc.BackchannelLogoutResponse) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes)

Example 15 with ErrorResponseException

use of org.keycloak.services.ErrorResponseException in project keycloak by keycloak.

the class DockerAuthV2Protocol method authenticated.

@Override
public Response authenticated(final AuthenticationSessionModel authSession, final UserSessionModel userSession, final ClientSessionContext clientSessionCtx) {
    // First, create a base response token with realm + user values populated
    final AuthenticatedClientSessionModel clientSession = clientSessionCtx.getClientSession();
    final ClientModel client = clientSession.getClient();
    DockerResponseToken responseToken = new DockerResponseToken().id(KeycloakModelUtils.generateId()).type(TokenUtil.TOKEN_TYPE_BEARER).issuer(authSession.getClientNote(DockerAuthV2Protocol.ISSUER)).subject(userSession.getUser().getUsername()).issuedNow().audience(client.getClientId()).issuedFor(client.getClientId());
    // since realm access token is given in seconds
    final int accessTokenLifespan = realm.getAccessTokenLifespan();
    responseToken.notBefore(responseToken.getIssuedAt()).expiration(responseToken.getIssuedAt() + accessTokenLifespan);
    // Next, allow mappers to decorate the token to add/remove scopes as appropriate
    AtomicReference<DockerResponseToken> finalResponseToken = new AtomicReference<>(responseToken);
    ProtocolMapperUtils.getSortedProtocolMappers(session, clientSessionCtx).filter(mapper -> mapper.getValue() instanceof DockerAuthV2AttributeMapper).filter(mapper -> ((DockerAuthV2AttributeMapper) mapper.getValue()).appliesTo(finalResponseToken.get())).forEach(mapper -> finalResponseToken.set(((DockerAuthV2AttributeMapper) mapper.getValue()).transformDockerResponseToken(finalResponseToken.get(), mapper.getKey(), session, userSession, clientSession)));
    responseToken = finalResponseToken.get();
    try {
        // Finally, construct the response to the docker client with the token + metadata
        if (event.getEvent() != null && EventType.LOGIN.equals(event.getEvent().getType())) {
            final KeyManager.ActiveRsaKey activeKey = session.keys().getActiveRsaKey(realm);
            final String encodedToken = new JWSBuilder().kid(new DockerKeyIdentifier(activeKey.getPublicKey()).toString()).type("JWT").jsonContent(responseToken).rsa256(activeKey.getPrivateKey());
            final String expiresInIso8601String = new SimpleDateFormat(ISO_8601_DATE_FORMAT).format(new Date(responseToken.getIssuedAt() * 1000L));
            final DockerResponse responseEntity = new DockerResponse().setToken(encodedToken).setExpires_in(accessTokenLifespan).setIssued_at(expiresInIso8601String);
            return new ResponseBuilderImpl().status(Response.Status.OK).header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON).entity(responseEntity).build();
        } else {
            logger.errorv("Unable to handle request for event type {0}.  Currently only LOGIN event types are supported by docker protocol.", event.getEvent() == null ? "null" : event.getEvent().getType());
            throw new ErrorResponseException("invalid_request", "Event type not supported", Response.Status.BAD_REQUEST);
        }
    } catch (final InstantiationException e) {
        logger.errorv("Error attempting to create Key ID for Docker JOSE header: ", e.getMessage());
        throw new ErrorResponseException("token_error", "Unable to construct JOSE header for JWT", Response.Status.INTERNAL_SERVER_ERROR);
    }
}
Also used : DockerAuthV2AttributeMapper(org.keycloak.protocol.docker.mapper.DockerAuthV2AttributeMapper) ClientModel(org.keycloak.models.ClientModel) KeycloakModelUtils(org.keycloak.models.utils.KeycloakModelUtils) Date(java.util.Date) Logger(org.jboss.logging.Logger) SimpleDateFormat(java.text.SimpleDateFormat) ResponseBuilderImpl(org.jboss.resteasy.specimpl.ResponseBuilderImpl) AtomicReference(java.util.concurrent.atomic.AtomicReference) KeyManager(org.keycloak.models.KeyManager) TokenUtil(org.keycloak.util.TokenUtil) MediaType(javax.ws.rs.core.MediaType) ClientSessionContext(org.keycloak.models.ClientSessionContext) JWSBuilder(org.keycloak.jose.jws.JWSBuilder) EventBuilder(org.keycloak.events.EventBuilder) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) ErrorResponseException(org.keycloak.services.ErrorResponseException) DockerResponseToken(org.keycloak.representations.docker.DockerResponseToken) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RealmModel(org.keycloak.models.RealmModel) KeycloakSession(org.keycloak.models.KeycloakSession) EventType(org.keycloak.events.EventType) UserSessionModel(org.keycloak.models.UserSessionModel) DockerResponse(org.keycloak.representations.docker.DockerResponse) HttpHeaders(javax.ws.rs.core.HttpHeaders) Response(javax.ws.rs.core.Response) ProtocolMapperUtils(org.keycloak.protocol.ProtocolMapperUtils) UriInfo(javax.ws.rs.core.UriInfo) DockerAuthV2AttributeMapper(org.keycloak.protocol.docker.mapper.DockerAuthV2AttributeMapper) LoginProtocol(org.keycloak.protocol.LoginProtocol) DockerResponse(org.keycloak.representations.docker.DockerResponse) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) AtomicReference(java.util.concurrent.atomic.AtomicReference) DockerResponseToken(org.keycloak.representations.docker.DockerResponseToken) Date(java.util.Date) JWSBuilder(org.keycloak.jose.jws.JWSBuilder) ClientModel(org.keycloak.models.ClientModel) ResponseBuilderImpl(org.jboss.resteasy.specimpl.ResponseBuilderImpl) ErrorResponseException(org.keycloak.services.ErrorResponseException) KeyManager(org.keycloak.models.KeyManager) SimpleDateFormat(java.text.SimpleDateFormat)

Aggregations

ErrorResponseException (org.keycloak.services.ErrorResponseException)60 Consumes (javax.ws.rs.Consumes)25 Path (javax.ws.rs.Path)20 POST (javax.ws.rs.POST)19 ClientModel (org.keycloak.models.ClientModel)19 Produces (javax.ws.rs.Produces)17 NoCache (org.jboss.resteasy.annotations.cache.NoCache)14 ClientPolicyException (org.keycloak.services.clientpolicy.ClientPolicyException)11 NotFoundException (javax.ws.rs.NotFoundException)9 IOException (java.io.IOException)8 Response (javax.ws.rs.core.Response)8 DELETE (javax.ws.rs.DELETE)7 PUT (javax.ws.rs.PUT)7 OAuthErrorException (org.keycloak.OAuthErrorException)7 RealmModel (org.keycloak.models.RealmModel)7 ModelException (org.keycloak.models.ModelException)6 RoleModel (org.keycloak.models.RoleModel)6 List (java.util.List)5 GET (javax.ws.rs.GET)5 Resource (org.keycloak.authorization.model.Resource)5