Search in sources :

Example 6 with LoginProtocol

use of org.keycloak.protocol.LoginProtocol in project keycloak by keycloak.

the class LoginActionsService method processConsent.

/**
 * OAuth grant page.  You should not invoked this directly!
 *
 * @return
 */
@Path("consent")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response processConsent() {
    MultivaluedMap<String, String> formData = request.getDecodedFormParameters();
    event.event(EventType.LOGIN);
    String code = formData.getFirst(SESSION_CODE);
    String clientId = session.getContext().getUri().getQueryParameters().getFirst(Constants.CLIENT_ID);
    String tabId = session.getContext().getUri().getQueryParameters().getFirst(Constants.TAB_ID);
    SessionCodeChecks checks = checksForCode(null, code, null, clientId, tabId, REQUIRED_ACTION);
    if (!checks.verifyRequiredAction(AuthenticationSessionModel.Action.OAUTH_GRANT.name())) {
        return checks.getResponse();
    }
    AuthenticationSessionModel authSession = checks.getAuthenticationSession();
    initLoginEvent(authSession);
    UserModel user = authSession.getAuthenticatedUser();
    ClientModel client = authSession.getClient();
    if (formData.containsKey("cancel")) {
        LoginProtocol protocol = session.getProvider(LoginProtocol.class, authSession.getProtocol());
        protocol.setRealm(realm).setHttpHeaders(headers).setUriInfo(session.getContext().getUri()).setEventBuilder(event);
        Response response = protocol.sendError(authSession, Error.CONSENT_DENIED);
        event.error(Errors.REJECTED_BY_USER);
        return response;
    }
    UserConsentModel grantedConsent = session.users().getConsentByClient(realm, user.getId(), client.getId());
    if (grantedConsent == null) {
        grantedConsent = new UserConsentModel(client);
        session.users().addConsent(realm, user.getId(), grantedConsent);
    }
    // Update may not be required if all clientScopes were already granted (May happen for example with prompt=consent)
    boolean updateConsentRequired = false;
    for (String clientScopeId : authSession.getClientScopes()) {
        ClientScopeModel clientScope = KeycloakModelUtils.findClientScopeById(realm, client, clientScopeId);
        if (clientScope != null) {
            if (!grantedConsent.isClientScopeGranted(clientScope) && clientScope.isDisplayOnConsentScreen()) {
                grantedConsent.addGrantedClientScope(clientScope);
                updateConsentRequired = true;
            }
        } else {
            logger.warnf("Client scope or client with ID '%s' not found", clientScopeId);
        }
    }
    if (updateConsentRequired) {
        session.users().updateConsent(realm, user.getId(), grantedConsent);
    }
    event.detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED);
    event.success();
    ClientSessionContext clientSessionCtx = AuthenticationProcessor.attachSession(authSession, null, session, realm, clientConnection, event);
    return AuthenticationManager.redirectAfterSuccessfulFlow(session, realm, clientSessionCtx.getClientSession().getUserSession(), clientSessionCtx, request, session.getContext().getUri(), clientConnection, event, authSession);
}
Also used : UserModel(org.keycloak.models.UserModel) Response(javax.ws.rs.core.Response) ClientModel(org.keycloak.models.ClientModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) ClientSessionContext(org.keycloak.models.ClientSessionContext) ClientScopeModel(org.keycloak.models.ClientScopeModel) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) LoginProtocol(org.keycloak.protocol.LoginProtocol) UserConsentModel(org.keycloak.models.UserConsentModel) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes)

Example 7 with LoginProtocol

use of org.keycloak.protocol.LoginProtocol in project keycloak by keycloak.

the class IdentityBrokerService method checkPassiveLoginError.

/**
 * Checks if specified message matches one of the passive login error messages and if it does builds a response that
 * redirects the error back to the client.
 *
 * @param authSession the authentication session.
 * @param message the error message.
 * @return a {@code {@link Response}} that redirects the error message back to the client if the {@code message} is one
 * of the passive login error messages, or {@code null} if it is not.
 */
private Response checkPassiveLoginError(AuthenticationSessionModel authSession, String message) {
    LoginProtocol.Error error = OAuthErrorException.LOGIN_REQUIRED.equals(message) ? LoginProtocol.Error.PASSIVE_LOGIN_REQUIRED : (OAuthErrorException.INTERACTION_REQUIRED.equals(message) ? LoginProtocol.Error.PASSIVE_INTERACTION_REQUIRED : null);
    if (error != null) {
        LoginProtocol protocol = session.getProvider(LoginProtocol.class, authSession.getProtocol());
        protocol.setRealm(realmModel).setHttpHeaders(headers).setUriInfo(session.getContext().getUri()).setEventBuilder(event);
        return protocol.sendError(authSession, error);
    }
    return null;
}
Also used : LoginProtocol(org.keycloak.protocol.LoginProtocol) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol)

Example 8 with LoginProtocol

use of org.keycloak.protocol.LoginProtocol in project keycloak by keycloak.

the class AuthenticationManager method finishBrowserLogout.

public static Response finishBrowserLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
    final AuthenticationSessionManager asm = new AuthenticationSessionManager(session);
    AuthenticationSessionModel logoutAuthSession = createOrJoinLogoutSession(session, realm, asm, userSession, true);
    checkUserSessionOnlyHasLoggedOutClients(realm, userSession, logoutAuthSession);
    // For resolving artifact we don't need any cookie, all details are stored in session storage so we can remove
    expireIdentityCookie(realm, uriInfo, connection);
    expireRememberMeCookie(realm, uriInfo, connection);
    String method = userSession.getNote(KEYCLOAK_LOGOUT_PROTOCOL);
    EventBuilder event = new EventBuilder(realm, session, connection);
    LoginProtocol protocol = session.getProvider(LoginProtocol.class, method);
    protocol.setRealm(realm).setHttpHeaders(headers).setUriInfo(uriInfo).setEventBuilder(event);
    Response response = protocol.finishLogout(userSession);
    // It may be possible that there are some client sessions that are still in LOGGING_OUT state
    long numberOfUnconfirmedSessions = userSession.getAuthenticatedClientSessions().values().stream().filter(clientSessionModel -> CommonClientSessionModel.Action.LOGGING_OUT.name().equals(clientSessionModel.getAction())).count();
    // If logout flow end up correctly there should be at maximum 1 client session in LOGGING_OUT action, if there are more, something went wrong
    if (numberOfUnconfirmedSessions > 1) {
        logger.warnf("There are more than one clientSession in logging_out state. Perhaps some client did not finish logout flow correctly.");
    }
    // LOGGED_OUT action can remove UserSession
    if (numberOfUnconfirmedSessions >= 1) {
        userSession.setState(UserSessionModel.State.LOGGED_OUT_UNCONFIRMED);
    } else {
        userSession.setState(UserSessionModel.State.LOGGED_OUT);
    }
    // Do not remove user session, it will be removed when last clientSession will be logged out
    if (numberOfUnconfirmedSessions < 1) {
        session.sessions().removeUserSession(realm, userSession);
    }
    session.authenticationSessions().removeRootAuthenticationSession(realm, logoutAuthSession.getParentSession());
    return response;
}
Also used : BackchannelLogoutResponse(org.keycloak.protocol.oidc.BackchannelLogoutResponse) Response(javax.ws.rs.core.Response) DefaultClientSessionContext(org.keycloak.services.util.DefaultClientSessionContext) ActionTokenStoreProvider(org.keycloak.models.ActionTokenStoreProvider) Error(org.keycloak.protocol.LoginProtocol.Error) ErrorResponseException(org.keycloak.services.ErrorResponseException) Map(java.util.Map) ClientConnection(org.keycloak.common.ClientConnection) UriBuilder(javax.ws.rs.core.UriBuilder) Time(org.keycloak.common.util.Time) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) AuthenticationProcessor(org.keycloak.authentication.AuthenticationProcessor) Set(java.util.Set) AbstractUsernameFormAuthenticator(org.keycloak.authentication.authenticators.browser.AbstractUsernameFormAuthenticator) SecretGenerator(org.keycloak.common.util.SecretGenerator) Stream(java.util.stream.Stream) AuthenticationFlowException(org.keycloak.authentication.AuthenticationFlowException) SessionTimeoutHelper(org.keycloak.models.utils.SessionTimeoutHelper) LoginActionsService(org.keycloak.services.resources.LoginActionsService) UriInfo(javax.ws.rs.core.UriInfo) OAuth2Constants(org.keycloak.OAuth2Constants) LoginProtocol(org.keycloak.protocol.LoginProtocol) Constants(org.keycloak.models.Constants) TokenManager(org.keycloak.protocol.oidc.TokenManager) TokenUtil(org.keycloak.util.TokenUtil) UserModel(org.keycloak.models.UserModel) ClientSessionContext(org.keycloak.models.ClientSessionContext) Predicate(org.keycloak.TokenVerifier.Predicate) TokenVerifier(org.keycloak.TokenVerifier) CommonClientSessionModel(org.keycloak.sessions.CommonClientSessionModel) Base64Url(org.keycloak.common.util.Base64Url) BackchannelLogoutResponse(org.keycloak.protocol.oidc.BackchannelLogoutResponse) AuthenticationFlowError(org.keycloak.authentication.AuthenticationFlowError) ConsoleDisplayMode(org.keycloak.authentication.ConsoleDisplayMode) IdentityBrokerService(org.keycloak.services.resources.IdentityBrokerService) KeycloakSession(org.keycloak.models.KeycloakSession) AuthorizationDetails(org.keycloak.rar.AuthorizationDetails) HttpRequest(org.jboss.resteasy.spi.HttpRequest) EventType(org.keycloak.events.EventType) P3PHelper(org.keycloak.services.util.P3PHelper) RequiredActionProvider(org.keycloak.authentication.RequiredActionProvider) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException) LoginFormsProvider(org.keycloak.forms.login.LoginFormsProvider) URLDecoder(java.net.URLDecoder) ActionTokenKeyModel(org.keycloak.models.ActionTokenKeyModel) RequiredActionContextResult(org.keycloak.authentication.RequiredActionContextResult) RequiredActionFactory(org.keycloak.authentication.RequiredActionFactory) NewCookie(javax.ws.rs.core.NewCookie) Messages(org.keycloak.services.messages.Messages) DefaultActionTokenKey(org.keycloak.authentication.actiontoken.DefaultActionTokenKey) SignatureVerifierContext(org.keycloak.crypto.SignatureVerifierContext) AccessToken(org.keycloak.representations.AccessToken) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) URI(java.net.URI) SystemClientUtil(org.keycloak.models.utils.SystemClientUtil) VerificationException(org.keycloak.common.VerificationException) DeviceGrantType.isOAuth2DeviceVerificationFlow(org.keycloak.protocol.oidc.grants.device.DeviceGrantType.isOAuth2DeviceVerificationFlow) ClientScopeModel(org.keycloak.models.ClientScopeModel) RealmModel(org.keycloak.models.RealmModel) InitiatedActionSupport(org.keycloak.authentication.InitiatedActionSupport) AuthenticatorUtil(org.keycloak.authentication.AuthenticatorUtil) Collectors(java.util.stream.Collectors) Cookie(javax.ws.rs.core.Cookie) Objects(java.util.Objects) List(java.util.List) HttpHeaders(javax.ws.rs.core.HttpHeaders) Response(javax.ws.rs.core.Response) Details(org.keycloak.events.Details) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) Optional(java.util.Optional) UnsupportedEncodingException(java.io.UnsupportedEncodingException) RequiredActionProviderModel(org.keycloak.models.RequiredActionProviderModel) ClientModel(org.keycloak.models.ClientModel) RealmsResource(org.keycloak.services.resources.RealmsResource) Profile(org.keycloak.common.Profile) SameSiteAttributeValue(org.keycloak.common.util.ServerCookie.SameSiteAttributeValue) KeycloakModelUtils(org.keycloak.models.utils.KeycloakModelUtils) Logger(org.jboss.logging.Logger) ServicesLogger(org.keycloak.services.ServicesLogger) TokenTypeCheck(org.keycloak.TokenVerifier.TokenTypeCheck) RequiredActionContext(org.keycloak.authentication.RequiredActionContext) SignatureProvider(org.keycloak.crypto.SignatureProvider) EventBuilder(org.keycloak.events.EventBuilder) CookieHelper(org.keycloak.services.util.CookieHelper) UserConsentModel(org.keycloak.models.UserConsentModel) OIDCAdvancedConfigWrapper(org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper) LinkedList(java.util.LinkedList) DisplayTypeRequiredActionFactory(org.keycloak.authentication.DisplayTypeRequiredActionFactory) IdentityProvider(org.keycloak.broker.provider.IdentityProvider) Errors(org.keycloak.events.Errors) CORRESPONDING_SESSION_ID(org.keycloak.models.UserSessionModel.CORRESPONDING_SESSION_ID) UserSessionModel(org.keycloak.models.UserSessionModel) AuthorizationContextUtil(org.keycloak.services.util.AuthorizationContextUtil) URLEncoder(java.net.URLEncoder) LogoutRequestContext(org.keycloak.services.clientpolicy.context.LogoutRequestContext) CookieHelper.getCookie(org.keycloak.services.util.CookieHelper.getCookie) Urls(org.keycloak.services.Urls) Collections(java.util.Collections) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) EventBuilder(org.keycloak.events.EventBuilder) LoginProtocol(org.keycloak.protocol.LoginProtocol) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol)

Example 9 with LoginProtocol

use of org.keycloak.protocol.LoginProtocol in project keycloak by keycloak.

the class AuthenticationManager method redirectAfterSuccessfulFlow.

public static Response redirectAfterSuccessfulFlow(KeycloakSession session, RealmModel realm, UserSessionModel userSession, ClientSessionContext clientSessionCtx, HttpRequest request, UriInfo uriInfo, ClientConnection clientConnection, EventBuilder event, AuthenticationSessionModel authSession) {
    LoginProtocol protocolImpl = session.getProvider(LoginProtocol.class, authSession.getProtocol());
    protocolImpl.setRealm(realm).setHttpHeaders(request.getHttpHeaders()).setUriInfo(uriInfo).setEventBuilder(event);
    return redirectAfterSuccessfulFlow(session, realm, userSession, clientSessionCtx, request, uriInfo, clientConnection, event, authSession, protocolImpl);
}
Also used : LoginProtocol(org.keycloak.protocol.LoginProtocol) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol)

Example 10 with LoginProtocol

use of org.keycloak.protocol.LoginProtocol in project keycloak by keycloak.

the class AuthenticationManager method backchannelLogoutClientSession.

/**
 * Logs out the given client session and records the result into {@code logoutAuthSession} if set.
 *
 * @param session
 * @param realm
 * @param clientSession
 * @param logoutAuthSession auth session used for recording result of logout. May be {@code null}
 * @param uriInfo
 * @param headers
 * @return {@code http status OK} if the client was or is already being logged out, {@code null} if it is
 *         not known how to log it out and no request is made, otherwise the response of the logout request.
 */
private static Response backchannelLogoutClientSession(KeycloakSession session, RealmModel realm, AuthenticatedClientSessionModel clientSession, AuthenticationSessionModel logoutAuthSession, UriInfo uriInfo, HttpHeaders headers) {
    UserSessionModel userSession = clientSession.getUserSession();
    ClientModel client = clientSession.getClient();
    if (client.isFrontchannelLogout() || AuthenticationSessionModel.Action.LOGGED_OUT.name().equals(clientSession.getAction())) {
        return null;
    }
    final AuthenticationSessionModel.Action logoutState = getClientLogoutAction(logoutAuthSession, client.getId());
    if (logoutState == AuthenticationSessionModel.Action.LOGGED_OUT || logoutState == AuthenticationSessionModel.Action.LOGGING_OUT) {
        return Response.ok().build();
    }
    if (!client.isEnabled()) {
        return null;
    }
    try {
        setClientLogoutAction(logoutAuthSession, client.getId(), AuthenticationSessionModel.Action.LOGGING_OUT);
        String authMethod = clientSession.getProtocol();
        // must be a keycloak service like account
        if (authMethod == null)
            return Response.ok().build();
        logger.debugv("backchannel logout to: {0}", client.getClientId());
        LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
        protocol.setRealm(realm).setHttpHeaders(headers).setUriInfo(uriInfo);
        Response clientSessionLogout = protocol.backchannelLogout(userSession, clientSession);
        setClientLogoutAction(logoutAuthSession, client.getId(), AuthenticationSessionModel.Action.LOGGED_OUT);
        return clientSessionLogout;
    } catch (Exception ex) {
        ServicesLogger.LOGGER.failedToLogoutClient(ex);
        return Response.serverError().build();
    }
}
Also used : BackchannelLogoutResponse(org.keycloak.protocol.oidc.BackchannelLogoutResponse) Response(javax.ws.rs.core.Response) ClientModel(org.keycloak.models.ClientModel) UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) LoginProtocol(org.keycloak.protocol.LoginProtocol) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) ErrorResponseException(org.keycloak.services.ErrorResponseException) AuthenticationFlowException(org.keycloak.authentication.AuthenticationFlowException) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException) VerificationException(org.keycloak.common.VerificationException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Aggregations

LoginProtocol (org.keycloak.protocol.LoginProtocol)11 OIDCLoginProtocol (org.keycloak.protocol.oidc.OIDCLoginProtocol)10 Response (javax.ws.rs.core.Response)6 AuthenticationSessionModel (org.keycloak.sessions.AuthenticationSessionModel)6 RootAuthenticationSessionModel (org.keycloak.sessions.RootAuthenticationSessionModel)5 AuthenticationFlowException (org.keycloak.authentication.AuthenticationFlowException)4 ClientModel (org.keycloak.models.ClientModel)4 BackchannelLogoutResponse (org.keycloak.protocol.oidc.BackchannelLogoutResponse)4 UnsupportedEncodingException (java.io.UnsupportedEncodingException)3 VerificationException (org.keycloak.common.VerificationException)3 UserSessionModel (org.keycloak.models.UserSessionModel)3 ErrorResponseException (org.keycloak.services.ErrorResponseException)3 ClientPolicyException (org.keycloak.services.clientpolicy.ClientPolicyException)3 ClientScopeModel (org.keycloak.models.ClientScopeModel)2 ClientSessionContext (org.keycloak.models.ClientSessionContext)2 UserConsentModel (org.keycloak.models.UserConsentModel)2 UserModel (org.keycloak.models.UserModel)2 URI (java.net.URI)1 URLDecoder (java.net.URLDecoder)1 URLEncoder (java.net.URLEncoder)1