Java Code Examples for org.keycloak.models.ClientModel#isConsentRequired()

The following examples show how to use org.keycloak.models.ClientModel#isConsentRequired() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MigrationUtils.java    From keycloak with Apache License 2.0 6 votes vote down vote up
public static void migrateOldOfflineToken(KeycloakSession session, RealmModel realm, ClientModel client, UserModel user) throws OAuthErrorException {
    ClientScopeModel offlineScope = KeycloakModelUtils.getClientScopeByName(realm, OAuth2Constants.OFFLINE_ACCESS);
    if (offlineScope == null) {
        throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Offline Access scope not found");
    }

    if (client.isConsentRequired()) {
        // Automatically add consents for client and for offline_access. We know that both were defacto approved by user already and offlineSession is still valid
        UserConsentModel consent = session.users().getConsentByClient(realm, user.getId(), client.getId());
        if (consent != null) {
            if (client.isDisplayOnConsentScreen()) {
                consent.addGrantedClientScope(client);
            }
            if (offlineScope.isDisplayOnConsentScreen()) {
                consent.addGrantedClientScope(offlineScope);
            }
            session.users().updateConsent(realm, user.getId(), consent);
        }
    }
}
 
Example 2
Source File: TokenManager.java    From keycloak with Apache License 2.0 6 votes vote down vote up
public static boolean verifyConsentStillAvailable(KeycloakSession session, UserModel user, ClientModel client, Set<ClientScopeModel> requestedClientScopes) {
    if (!client.isConsentRequired()) {
        return true;
    }

    UserConsentModel grantedConsent = session.users().getConsentByClient(client.getRealm(), user.getId(), client.getId());

    for (ClientScopeModel requestedScope : requestedClientScopes) {
        if (!requestedScope.isDisplayOnConsentScreen()) {
            continue;
        }

        if (grantedConsent == null || !grantedConsent.getGrantedClientScopes().contains(requestedScope)) {
            logger.debugf("Client '%s' no longer has requested consent from user '%s' for client scope '%s'",
                    client.getClientId(), user.getUsername(), requestedScope.getName());
            return false;
        }
    }

    return true;
}
 
Example 3
Source File: AccountRestService.java    From keycloak with Apache License 2.0 6 votes vote down vote up
/**
 * Create a new consent model object from the requested consent object
 * for the given client model.
 *
 * @param client    client to create a consent for
 * @param requested list of client scopes that the new consent should contain
 * @return newly created consent model
 * @throws IllegalArgumentException throws an exception if the scope id is not available
 */
private UserConsentModel createConsent(ClientModel client, ConsentRepresentation requested) throws IllegalArgumentException {
    UserConsentModel consent = new UserConsentModel(client);
    Map<String, ClientScopeModel> availableGrants = realm.getClientScopes().stream().collect(Collectors.toMap(ClientScopeModel::getId, s -> s));

    if (client.isConsentRequired()) {
        availableGrants.put(client.getId(), client);
    }

    for (ConsentScopeRepresentation scopeRepresentation : requested.getGrantedScopes()) {
        ClientScopeModel scopeModel = availableGrants.get(scopeRepresentation.getId());
        if (scopeModel == null) {
            String msg = String.format("Scope id %s does not exist for client %s.", scopeRepresentation, consent.getClient().getName());
            event.error(msg);
            throw new IllegalArgumentException(msg);
        } else {
            consent.addGrantedClientScope(scopeModel);
        }
    }
    return consent;
}
 
Example 4
Source File: ConsentRequiredClientRegistrationPolicy.java    From keycloak with Apache License 2.0 6 votes vote down vote up
@Override
public void beforeUpdate(ClientRegistrationContext context, ClientModel clientModel) throws ClientRegistrationPolicyException {
    if (context.getClient().isConsentRequired() == null) {
        return;
    }
    if (clientModel == null) {
        return;
    }

    boolean isEnabled = clientModel.isConsentRequired();
    boolean newEnabled = context.getClient().isConsentRequired();

    if (isEnabled && !newEnabled) {
        throw new ClientRegistrationPolicyException("Not permitted to update consentRequired to false");
    }
}
 
Example 5
Source File: AuthenticationManager.java    From keycloak with Apache License 2.0 5 votes vote down vote up
public static String nextRequiredAction(final KeycloakSession session, final AuthenticationSessionModel authSession,
                                        final ClientConnection clientConnection,
                                        final HttpRequest request, final UriInfo uriInfo, final EventBuilder event) {
    final RealmModel realm = authSession.getRealm();
    final UserModel user = authSession.getAuthenticatedUser();
    final ClientModel client = authSession.getClient();

    evaluateRequiredActionTriggers(session, authSession, clientConnection, request, uriInfo, event, realm, user);

    if (!user.getRequiredActions().isEmpty()) {
        return user.getRequiredActions().iterator().next();
    }
    if (!authSession.getRequiredActions().isEmpty()) {
        return authSession.getRequiredActions().iterator().next();
    }

    String kcAction = authSession.getClientNote(Constants.KC_ACTION);
    if (kcAction != null) {
        return kcAction;
    }

    if (client.isConsentRequired()) {

        UserConsentModel grantedConsent = getEffectiveGrantedConsent(session, authSession);

        // See if any clientScopes need to be approved on consent screen
        List<ClientScopeModel> clientScopesToApprove = getClientScopesToApproveOnConsentScreen(realm, grantedConsent, authSession);
        if (!clientScopesToApprove.isEmpty()) {
            return CommonClientSessionModel.Action.OAUTH_GRANT.name();
        }

        String consentDetail = (grantedConsent != null) ? Details.CONSENT_VALUE_PERSISTED_CONSENT : Details.CONSENT_VALUE_NO_CONSENT_REQUIRED;
        event.detail(Details.CONSENT, consentDetail);
    } else {
        event.detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED);
    }
    return null;

}
 
Example 6
Source File: TokenEndpoint.java    From keycloak with Apache License 2.0 4 votes vote down vote up
protected Response exchangeClientToClient(UserModel targetUser, UserSessionModel targetUserSession) {
    String requestedTokenType = formParams.getFirst(OAuth2Constants.REQUESTED_TOKEN_TYPE);
    if (requestedTokenType == null) {
        requestedTokenType = OAuth2Constants.REFRESH_TOKEN_TYPE;
    } else if (!requestedTokenType.equals(OAuth2Constants.ACCESS_TOKEN_TYPE) &&
            !requestedTokenType.equals(OAuth2Constants.REFRESH_TOKEN_TYPE) &&
            !requestedTokenType.equals(OAuth2Constants.SAML2_TOKEN_TYPE)) {
        event.detail(Details.REASON, "requested_token_type unsupported");
        event.error(Errors.INVALID_REQUEST);
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "requested_token_type unsupported", Response.Status.BAD_REQUEST);

    }
    ClientModel targetClient = client;
    String audience = formParams.getFirst(OAuth2Constants.AUDIENCE);
    if (audience != null) {
        targetClient = realm.getClientByClientId(audience);
        if (targetClient == null) {
            event.detail(Details.REASON, "audience not found");
            event.error(Errors.CLIENT_NOT_FOUND);
            throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_CLIENT, "Audience not found", Response.Status.BAD_REQUEST);

        }
    }

    if (targetClient.isConsentRequired()) {
        event.detail(Details.REASON, "audience requires consent");
        event.error(Errors.CONSENT_DENIED);
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_CLIENT, "Client requires user consent", Response.Status.BAD_REQUEST);
    }

    if (!targetClient.equals(client) && !AdminPermissions.management(session, realm).clients().canExchangeTo(client, targetClient)) {
        event.detail(Details.REASON, "client not allowed to exchange to audience");
        event.error(Errors.NOT_ALLOWED);
        throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "Client not allowed to exchange", Response.Status.FORBIDDEN);
    }

    String scope = formParams.getFirst(OAuth2Constants.SCOPE);

    switch (requestedTokenType) {
        case OAuth2Constants.ACCESS_TOKEN_TYPE:
        case OAuth2Constants.REFRESH_TOKEN_TYPE:
            return exchangeClientToOIDCClient(targetUser, targetUserSession, requestedTokenType, targetClient, audience, scope);
        case OAuth2Constants.SAML2_TOKEN_TYPE:
            return exchangeClientToSAML2Client(targetUser, targetUserSession, requestedTokenType, targetClient, audience, scope);
    }

    throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "requested_token_type unsupported", Response.Status.BAD_REQUEST);
}
 
Example 7
Source File: ApplicationsBean.java    From keycloak with Apache License 2.0 4 votes vote down vote up
public ApplicationsBean(KeycloakSession session, RealmModel realm, UserModel user) {
    Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user);

    for (ClientModel client : getApplications(session, realm, user)) {
        if (isAdminClient(client) && ! AdminPermissions.realms(session, realm, user).isAdmin()) {
            continue;
        }

        // Construct scope parameter with all optional scopes to see all potentially available roles
        Set<ClientScopeModel> allClientScopes = new HashSet<>(client.getClientScopes(true, true).values());
        allClientScopes.addAll(client.getClientScopes(false, true).values());
        allClientScopes.add(client);

        Set<RoleModel> availableRoles = TokenManager.getAccess(user, client, allClientScopes);

        // Don't show applications, which user doesn't have access into (any available roles)
        // unless this is can be changed by approving/revoking consent
        if (! isAdminClient(client) && availableRoles.isEmpty() && ! client.isConsentRequired()) {
            continue;
        }

        List<RoleModel> realmRolesAvailable = new LinkedList<>();
        MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable = new MultivaluedHashMap<>();
        processRoles(availableRoles, realmRolesAvailable, resourceRolesAvailable);

        List<ClientScopeModel> orderedScopes = new LinkedList<>();
        if (client.isConsentRequired()) {
            UserConsentModel consent = session.users().getConsentByClient(realm, user.getId(), client.getId());

            if (consent != null) {
                orderedScopes.addAll(consent.getGrantedClientScopes());
            }
        }
        List<String> clientScopesGranted = orderedScopes.stream()
                .sorted(OrderedModel.OrderedModelComparator.getInstance())
                .map(ClientScopeModel::getConsentScreenText)
                .collect(Collectors.toList());

        List<String> additionalGrants = new ArrayList<>();
        if (offlineClients.contains(client)) {
            additionalGrants.add("${offlineToken}");
        }

        applications.add(new ApplicationEntry(session, realmRolesAvailable, resourceRolesAvailable, client, clientScopesGranted, additionalGrants));
    }
}
 
Example 8
Source File: AuthenticationManager.java    From keycloak with Apache License 2.0 4 votes vote down vote up
public static Response actionRequired(final KeycloakSession session, final AuthenticationSessionModel authSession,
                                                     final ClientConnection clientConnection,
                                                     final HttpRequest request, final UriInfo uriInfo, final EventBuilder event) {
    final RealmModel realm = authSession.getRealm();
    final UserModel user = authSession.getAuthenticatedUser();
    final ClientModel client = authSession.getClient();

    evaluateRequiredActionTriggers(session, authSession, clientConnection, request, uriInfo, event, realm, user);


    logger.debugv("processAccessCode: go to oauth page?: {0}", client.isConsentRequired());

    event.detail(Details.CODE_ID, authSession.getParentSession().getId());

    Set<String> requiredActions = user.getRequiredActions();
    Response action = executionActions(session, authSession, request, event, realm, user, requiredActions);
    if (action != null) return action;

    // executionActions() method should remove any duplicate actions that might be in the clientSession
    requiredActions = authSession.getRequiredActions();
    action = executionActions(session, authSession, request, event, realm, user, requiredActions);
    if (action != null) return action;

    if (client.isConsentRequired()) {

        UserConsentModel grantedConsent = getEffectiveGrantedConsent(session, authSession);

        List<ClientScopeModel> clientScopesToApprove = getClientScopesToApproveOnConsentScreen(realm, grantedConsent, authSession);

        // Skip grant screen if everything was already approved by this user
        if (clientScopesToApprove.size() > 0) {
            String execution = AuthenticatedClientSessionModel.Action.OAUTH_GRANT.name();

            ClientSessionCode<AuthenticationSessionModel> accessCode = new ClientSessionCode<>(session, realm, authSession);
            accessCode.setAction(AuthenticatedClientSessionModel.Action.REQUIRED_ACTIONS.name());
            authSession.setAuthNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION, execution);

            return session.getProvider(LoginFormsProvider.class)
                    .setAuthenticationSession(authSession)
                    .setExecution(execution)
                    .setClientSessionCode(accessCode.getOrGenerateCode())
                    .setAccessRequest(clientScopesToApprove)
                    .createOAuthGrant();
        } else {
            String consentDetail = (grantedConsent != null) ? Details.CONSENT_VALUE_PERSISTED_CONSENT : Details.CONSENT_VALUE_NO_CONSENT_REQUIRED;
            event.detail(Details.CONSENT, consentDetail);
        }
    } else {
        event.detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED);
    }
    return null;

}