mirror of
https://github.com/keycloak/keycloak.git
synced 2026-02-11 17:59:09 -06:00
i18n for error message in login
This commit is contained in:
@@ -117,8 +117,46 @@ emailInstruction=Enter your username or email address and we will send you instr
|
||||
accountUpdated=Your account has been updated
|
||||
accountPasswordUpdated=Your password has been updated
|
||||
|
||||
identityProviderUnexpectedError=Unexpected error when authenticating with identity provider
|
||||
identityProviderNotFound="Could not find an identity provider with the identifier [{0}]."
|
||||
identityProviderNoToken=Could not obtain token from identity provider [{0}].
|
||||
realmSupportsNoCredentials=Realm [{0}] does not support any credential type.
|
||||
identityProviderNotUnique = Realm [{0}] supports multiple identity providers. Could not determine which identity provider should be used to authenticate with.
|
||||
identityProviderNotUnique=Realm [{0}] supports multiple identity providers. Could not determine which identity provider should be used to authenticate with.
|
||||
|
||||
noAccess=No access
|
||||
noAccess=No access
|
||||
|
||||
invalidPasswordMinLength=Invalid password: minimum length {0}
|
||||
invalidPasswordMinDigits=Invalid password: must contain at least {0} numerical digits
|
||||
invalidPasswordMinLowerCaseChars=Invalid password: must contain at least {0} lower case characters
|
||||
invalidPasswordMinUpperCaseChars=Invalid password: must contain at least {0} upper case characters
|
||||
invalidPasswordMinSpecialChars=Invalid password: must contain at least {0} special characters
|
||||
|
||||
failedToProcessResponse=Failed to process response
|
||||
httpsRequired=HTTPS required
|
||||
realmNotEnabled=Realm not enabled
|
||||
invalidRequest=Invalid Request
|
||||
unknownLoginRequester=Unknown login requester
|
||||
loginRequesterNotEnabled=Login requester not enabled
|
||||
bearerOnly=Bearer-only applications are not allowed to initiate browser login
|
||||
directGrantsOnly=Direct-grants-only clients are not allowed to initiate browser login
|
||||
invalidRedirectUri=Invalid redirect uri
|
||||
unsupportedNameIdFormat=Unsupported NameIDFormat
|
||||
invlidRequester=Invalid requester
|
||||
registrationNotAllowed=Registration not allowed
|
||||
|
||||
permissionNotApproved=Permission not approved.
|
||||
noRelayStateInResponse=No relay state in response from identity provider [{0}].
|
||||
identityProviderAlreadyLinked=The identity returned by the identity provider [{0}] is already linked to another user.
|
||||
userDisabled="User is disabled."
|
||||
insufficientPermission=Insufficient permissions to link identities.
|
||||
couldNotProceedWithAuthenticationRequest=Could not proceed with authentication request to identity provider.
|
||||
couldNotObtainToken=Could not obtain token from identity provider [{0}].
|
||||
unexpectedErrorRetrievingToken=Unexpected error when retrieving token from identity provider [{0}].
|
||||
unexpectedErrorHandlingResponse=Unexpected error when handling response from identity provider [{0}].
|
||||
identityProviderAuthenticationFailed=Authentication failed. Could not authenticate with identity provider [{0}].
|
||||
couldNotSendAuthenticationRequest=Could not send authentication request to identity provider [{0}].
|
||||
unexpectedErrorHandlingRequest=Unexpected error when handling authentication request to identity provider [{0}].
|
||||
invalidAccessCode=Invalid access code.
|
||||
sessionNotActive=Session not active.
|
||||
unknownCode=Unknown code, please login again through your application.
|
||||
invalidCode=Invalid code, please login again through your application.
|
||||
@@ -119,7 +119,7 @@ import java.util.concurrent.TimeUnit;
|
||||
session.getProvider(EmailProvider.class).setRealm(realm).setUser(user).sendVerifyEmail(link, expiration);
|
||||
} catch (EmailException e) {
|
||||
logger.error("Failed to send verification email", e);
|
||||
return setError("emailSendError").createErrorPage();
|
||||
return setError(Messages.EMAIL_SENT_ERROR).createErrorPage();
|
||||
}
|
||||
|
||||
actionMessage = Messages.ACTION_WARN_EMAIL;
|
||||
|
||||
@@ -5,6 +5,8 @@ package org.keycloak.models;
|
||||
*/
|
||||
public class ModelException extends RuntimeException {
|
||||
|
||||
private Object[] parameters;
|
||||
|
||||
public ModelException() {
|
||||
}
|
||||
|
||||
@@ -12,6 +14,11 @@ public class ModelException extends RuntimeException {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ModelException(String message, Object ... parameters) {
|
||||
super(message);
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public ModelException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
@@ -20,4 +27,11 @@ public class ModelException extends RuntimeException {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public Object[] getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameters(Object[] parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.keycloak.models;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -74,9 +75,9 @@ public class PasswordPolicy {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String validate(String password) {
|
||||
public Error validate(String password) {
|
||||
for (Policy p : policies) {
|
||||
String error = p.validate(password);
|
||||
Error error = p.validate(password);
|
||||
if (error != null) {
|
||||
return error;
|
||||
}
|
||||
@@ -85,7 +86,25 @@ public class PasswordPolicy {
|
||||
}
|
||||
|
||||
private static interface Policy {
|
||||
public String validate(String password);
|
||||
public Error validate(String password);
|
||||
}
|
||||
|
||||
public static class Error{
|
||||
private String message;
|
||||
private Object[] parameters;
|
||||
|
||||
private Error(String message, Object ... parameters){
|
||||
this.message = message;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Object[] getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
||||
private static class HashIterations implements Policy {
|
||||
@@ -97,7 +116,7 @@ public class PasswordPolicy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validate(String password) {
|
||||
public Error validate(String password) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -111,8 +130,8 @@ public class PasswordPolicy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validate(String password) {
|
||||
return password.length() < min ? "Invalid password: minimum length " + min : null;
|
||||
public Error validate(String password) {
|
||||
return password.length() < min ? new Error("invalidPasswordMinLength", min) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,14 +144,14 @@ public class PasswordPolicy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validate(String password) {
|
||||
public Error validate(String password) {
|
||||
int count = 0;
|
||||
for (char c : password.toCharArray()) {
|
||||
if (Character.isDigit(c)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count < min ? "Invalid password: must contain at least " + min + " numerical digits" : null;
|
||||
return count < min ? new Error("invalidPasswordMinDigits", min) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,14 +164,14 @@ public class PasswordPolicy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validate(String password) {
|
||||
public Error validate(String password) {
|
||||
int count = 0;
|
||||
for (char c : password.toCharArray()) {
|
||||
if (Character.isLowerCase(c)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count < min ? "Invalid password: must contain at least " + min + " lower case characters": null;
|
||||
return count < min ? new Error("invalidPasswordMinLowerCaseChars", min): null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,14 +184,14 @@ public class PasswordPolicy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validate(String password) {
|
||||
public Error validate(String password) {
|
||||
int count = 0;
|
||||
for (char c : password.toCharArray()) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count < min ? "Invalid password: must contain at least " + min + " upper case characters" : null;
|
||||
return count < min ? new Error("invalidPasswordMinUpperCaseChars", min) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,14 +204,14 @@ public class PasswordPolicy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String validate(String password) {
|
||||
public Error validate(String password) {
|
||||
int count = 0;
|
||||
for (char c : password.toCharArray()) {
|
||||
if (!Character.isLetterOrDigit(c)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count < min ? "Invalid password: must contain at least " + min + " special characters" : null;
|
||||
return count < min ? new Error("invalidPasswordMinSpecialChars", min) : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -322,8 +322,8 @@ public class UserFederationManager implements UserProvider {
|
||||
public void updateCredential(RealmModel realm, UserModel user, UserCredentialModel credential) {
|
||||
if (credential.getType().equals(UserCredentialModel.PASSWORD)) {
|
||||
if (realm.getPasswordPolicy() != null) {
|
||||
String error = realm.getPasswordPolicy().validate(credential.getValue());
|
||||
if (error != null) throw new ModelException(error);
|
||||
PasswordPolicy.Error error = realm.getPasswordPolicy().validate(credential.getValue());
|
||||
if (error != null) throw new ModelException(error.getMessage(), error.getParameters());
|
||||
}
|
||||
}
|
||||
user.updateCredential(credential);
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.keycloak.protocol.ProtocolMapper;
|
||||
import org.keycloak.protocol.saml.mappers.SAMLLoginResponseMapper;
|
||||
import org.keycloak.services.managers.ClientSessionCode;
|
||||
import org.keycloak.services.managers.ResourceAdminManager;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.services.resources.admin.ClientAttributeCertificateResource;
|
||||
import org.keycloak.services.resources.flows.Flows;
|
||||
@@ -143,7 +144,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||
return builder.redirectBinding().response();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Failed to process response", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.FAILED_TO_PROCESS_RESPONSE );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,7 +285,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||
samlDocument = builder.buildDocument(samlModel);
|
||||
} catch (Exception e) {
|
||||
logger.error("failed", e);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Failed to process response");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.FAILED_TO_PROCESS_RESPONSE);
|
||||
}
|
||||
|
||||
SAML2BindingBuilder2 bindingBuilder = new SAML2BindingBuilder2();
|
||||
@@ -306,7 +307,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||
publicKey = SamlProtocolUtils.getEncryptionValidationKey(client);
|
||||
} catch (Exception e) {
|
||||
logger.error("failed", e);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Failed to process response", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.FAILED_TO_PROCESS_RESPONSE);
|
||||
}
|
||||
bindingBuilder.encrypt(publicKey);
|
||||
}
|
||||
@@ -318,7 +319,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("failed", e);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Failed to process response", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.FAILED_TO_PROCESS_RESPONSE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.managers.ClientSessionCode;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.services.resources.flows.Flows;
|
||||
import org.keycloak.util.StreamUtil;
|
||||
@@ -101,18 +102,18 @@ public class SamlService {
|
||||
if (!checkSsl()) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED );
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
event.event(EventType.LOGIN_ERROR);
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
||||
}
|
||||
|
||||
if (samlRequest == null && samlResponse == null) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST );
|
||||
|
||||
}
|
||||
return null;
|
||||
@@ -124,7 +125,7 @@ public class SamlService {
|
||||
logger.warn("Unknown saml response.");
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
||||
}
|
||||
// assume this is a logout response
|
||||
UserSessionModel userSession = authResult.getSession();
|
||||
@@ -133,7 +134,7 @@ public class SamlService {
|
||||
logger.warn("UserSession is not tagged as logging out.");
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
||||
}
|
||||
logger.debug("logout response");
|
||||
return authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||
@@ -144,7 +145,7 @@ public class SamlService {
|
||||
if (documentHolder == null) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
||||
}
|
||||
|
||||
SAML2Object samlObject = documentHolder.getSamlObject();
|
||||
@@ -156,23 +157,23 @@ public class SamlService {
|
||||
if (client == null) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.CLIENT_NOT_FOUND);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_LOGIN_REQUESTER);
|
||||
}
|
||||
|
||||
if (!client.isEnabled()) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.CLIENT_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.LOGIN_REQUESTER_NOT_ENABLED);
|
||||
}
|
||||
if ((client instanceof ApplicationModel) && ((ApplicationModel)client).isBearerOnly()) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.NOT_ALLOWED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Bearer-only applications are not allowed to initiate browser login", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.BEARER_ONLY);
|
||||
}
|
||||
if (client.isDirectGrantsOnly()) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.NOT_ALLOWED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "direct-grants-only clients are not allowed to initiate browser login", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.DIRECT_GRANTS_ONLY );
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -181,7 +182,7 @@ public class SamlService {
|
||||
SamlService.logger.error("request validation failed", e);
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_SIGNATURE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid requester.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUESTER);
|
||||
}
|
||||
logger.debug("verified request");
|
||||
if (samlObject instanceof AuthnRequestType) {
|
||||
@@ -199,7 +200,7 @@ public class SamlService {
|
||||
} else {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +230,7 @@ public class SamlService {
|
||||
|
||||
if (redirect == null) {
|
||||
event.error(Errors.INVALID_REDIRECT_URI);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect_uri.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REDIRECT_URI );
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +252,7 @@ public class SamlService {
|
||||
clientSession.setNote(GeneralConstants.NAMEID_FORMAT, nameIdFormat);
|
||||
} else {
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unsupported NameIDFormat.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNSUPPORTED_NAME_ID_FORMAT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,7 +341,7 @@ public class SamlService {
|
||||
if (redirectUri != null) {
|
||||
redirectUri = OIDCLoginProtocolService.verifyRedirectUri(uriInfo, redirectUri, realm, client);
|
||||
if (redirectUri == null) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect uri.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REDIRECT_URI );
|
||||
}
|
||||
}
|
||||
if (redirectUri != null) {
|
||||
|
||||
@@ -72,7 +72,6 @@ import javax.ws.rs.ext.Providers;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -787,37 +786,37 @@ public class OIDCLoginProtocolService {
|
||||
event.client(clientId).detail(Details.REDIRECT_URI, redirect).detail(Details.RESPONSE_TYPE, "code");
|
||||
if (!checkSsl()) {
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
||||
}
|
||||
|
||||
clientSession = null;
|
||||
ClientModel client = realm.findClient(clientId);
|
||||
if (client == null) {
|
||||
event.error(Errors.CLIENT_NOT_FOUND);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_LOGIN_REQUESTER);
|
||||
}
|
||||
|
||||
if (!client.isEnabled()) {
|
||||
event.error(Errors.CLIENT_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.LOGIN_REQUESTER_NOT_ENABLED);
|
||||
}
|
||||
if ((client instanceof ApplicationModel) && ((ApplicationModel)client).isBearerOnly()) {
|
||||
event.error(Errors.NOT_ALLOWED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Bearer-only applications are not allowed to initiate browser login", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.BEARER_ONLY);
|
||||
}
|
||||
if (client.isDirectGrantsOnly()) {
|
||||
event.error(Errors.NOT_ALLOWED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "direct-grants-only clients are not allowed to initiate browser login", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.DIRECT_GRANTS_ONLY);
|
||||
}
|
||||
String redirectUriParam = redirect;
|
||||
redirect = verifyRedirectUri(uriInfo, redirect, realm, client);
|
||||
if (redirect == null) {
|
||||
event.error(Errors.INVALID_REDIRECT_URI);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect_uri.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REDIRECT_URI);
|
||||
}
|
||||
clientSession = session.sessions().createClientSession(realm, client);
|
||||
clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
@@ -962,7 +961,7 @@ public class OIDCLoginProtocolService {
|
||||
event.event(EventType.REGISTER);
|
||||
if (!realm.isRegistrationAllowed()) {
|
||||
event.error(Errors.REGISTRATION_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REGISTRATION_NOT_ALLOWED );
|
||||
}
|
||||
|
||||
FrontPageInitializer pageInitializer = new FrontPageInitializer();
|
||||
@@ -1006,7 +1005,7 @@ public class OIDCLoginProtocolService {
|
||||
if (redirectUri != null) {
|
||||
String validatedRedirect = verifyRealmRedirectUri(uriInfo, redirectUri, realm);
|
||||
if (validatedRedirect == null) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect uri.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REDIRECT_URI);
|
||||
}
|
||||
return Response.status(302).location(UriBuilder.fromUri(validatedRedirect).build()).build();
|
||||
} else {
|
||||
|
||||
@@ -112,7 +112,7 @@ public class HttpAuthenticationManager {
|
||||
Response response;
|
||||
if (!user.isEnabled()) {
|
||||
event.error(Errors.USER_DISABLED);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, Messages.ACCOUNT_DISABLED, headers);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.ACCOUNT_DISABLED);
|
||||
} else {
|
||||
UserSessionModel userSession = session.sessions().createUserSession(realm, user, user.getUsername(), clientConnection.getRemoteAddr(), authMethod, false);
|
||||
TokenManager.attachClientSession(userSession, clientSession);
|
||||
|
||||
@@ -27,6 +27,7 @@ package org.keycloak.services.messages;
|
||||
public class Messages {
|
||||
|
||||
public static final String ACCOUNT_DISABLED = "accountDisabled";
|
||||
|
||||
public static final String ACCOUNT_TEMPORARILY_DISABLED = "accountTemporarilyDisabled";
|
||||
|
||||
public static final String INVALID_PASSWORD = "invalidPassword";
|
||||
@@ -87,6 +88,10 @@ public class Messages {
|
||||
|
||||
public static final String IDENTITY_PROVIDER_REMOVED = "identityProviderRemoved";
|
||||
|
||||
public static final String IDENTITY_PROVIDER_UNEXPECTED_ERROR = "identityProviderUnexpectedError";
|
||||
|
||||
public static final String IDENTITY_PROVIDER_NO_TOKEN = "identityProviderNoToken";
|
||||
|
||||
public static final String ERROR = "error";
|
||||
|
||||
public static final String REALM_SUPPORTS_NO_CREDENTIALS = "realmSupportsNoCredentials";
|
||||
@@ -94,4 +99,65 @@ public class Messages {
|
||||
public static final String IDENTITY_PROVIDER_NOT_UNIQUE = "identityProviderNotUnique";
|
||||
|
||||
public static final String NO_ACCESS = "noAccess";
|
||||
|
||||
public static final String EMAIL_SENT = "emailSent";
|
||||
|
||||
public static final String EMAIL_SENT_ERROR = "emailSendError";
|
||||
|
||||
public static final String FAILED_TO_PROCESS_RESPONSE = "failedToProcessResponse";
|
||||
|
||||
public static final String HTTPS_REQUIRED = "httpsRequired";
|
||||
|
||||
public static final String REALM_NOT_ENABLED = "realmNotEnabled";
|
||||
|
||||
public static final String INVALID_REQUEST = "invalidRequest";
|
||||
|
||||
public static final String INVALID_REQUESTER = "invalidRequester";
|
||||
|
||||
public static final String UNKNOWN_LOGIN_REQUESTER = "unknownLoginRequester";
|
||||
|
||||
public static final String LOGIN_REQUESTER_NOT_ENABLED = "loginRequesterNotEnabled";
|
||||
|
||||
public static final String BEARER_ONLY = "bearerOnly";
|
||||
|
||||
public static final String DIRECT_GRANTS_ONLY = "directGrantsOnly";
|
||||
|
||||
public static final String INVALID_REDIRECT_URI = "invalidRedirectUri";
|
||||
|
||||
public static final String UNSUPPORTED_NAME_ID_FORMAT = "unsupportedNameIdFormat";
|
||||
|
||||
public static final String REGISTRATION_NOT_ALLOWED = "registrationNotAllowed";
|
||||
|
||||
public static final String PERMISSION_NOT_APPROVED = "permissionNotApproved";
|
||||
|
||||
public static final String NO_RELAY_STATE_IN_RESPONSE = "noRelayStateInResponse";
|
||||
|
||||
public static final String IDENTITY_PROVIDER_ALREADY_LINKED = "identityProviderAlreadyLinked";
|
||||
|
||||
public static final String USER_DISABLED = "userDisabled";
|
||||
|
||||
public static final String INSUFFICIENT_PERMISSION = "insufficientPermission";
|
||||
|
||||
|
||||
public static final String COULD_NOT_PROCEED_WITH_AUTHENTICATION_REQUEST = "couldNotProceedWithAuthenticationRequest";
|
||||
|
||||
public static final String COULD_NOT_OBTAIN_TOKEN = "couldNotObtainToken";
|
||||
|
||||
public static final String UNEXPECTED_ERROR_RETRIEVING_TOKEN = "unexpectedErrorRetrievingToken";
|
||||
|
||||
public static final String IDENTITY_PROVIDER_AUTHENTICATION_FAILED = "identityProviderAuthenticationFailed";
|
||||
|
||||
public static final String UNEXPECTED_ERROR_HANDLING_RESPONSE = "unexpectedErrorHandlingResponse";
|
||||
|
||||
public static final String COULD_NOT_SEND_AUTHENTICATION_REQUEST = "couldNotSendAuthenticationRequest";
|
||||
|
||||
public static final String UNEXPECTED_ERROR_HANDLING_REQUEST = "unexpectedErrorHandlingRequest";
|
||||
|
||||
public static final String INVALID_ACCESS_CODE = "invalidAccessCode";
|
||||
|
||||
public static final String SESSION_NOT_ACTIVE = "sessionNotActive";
|
||||
|
||||
public static final String UNKNOWN_CODE = "unknownCode";
|
||||
|
||||
public static final String INVALID_CODE = "invalidCode";
|
||||
}
|
||||
|
||||
@@ -611,7 +611,7 @@ public class AccountService {
|
||||
} catch (ModelReadOnlyException mre) {
|
||||
setReferrerOnPage();
|
||||
return account.setError(Messages.READ_ONLY_PASSWORD).createResponse(AccountPages.PASSWORD);
|
||||
} catch (Exception ape) {
|
||||
}catch (Exception ape) {
|
||||
logger.error("Failed to update password", ape);
|
||||
setReferrerOnPage();
|
||||
return account.setError(ape.getMessage()).createResponse(AccountPages.PASSWORD);
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.managers.AuthenticationManager.AuthResult;
|
||||
import org.keycloak.services.managers.ClientSessionCode;
|
||||
import org.keycloak.services.managers.EventsManager;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.services.resources.flows.Flows;
|
||||
import org.keycloak.services.resources.flows.Urls;
|
||||
import org.keycloak.social.SocialIdentityProvider;
|
||||
@@ -134,12 +135,12 @@ public class IdentityBrokerService {
|
||||
return response;
|
||||
}
|
||||
} catch (IdentityBrokerException e) {
|
||||
return redirectToErrorPage("Could not send authentication request to identity provider [" + providerId + "].", e);
|
||||
return redirectToErrorPage(Messages.COULD_NOT_SEND_AUTHENTICATION_REQUEST, e, providerId);
|
||||
} catch (Exception e) {
|
||||
return redirectToErrorPage("Unexpected error when handling authentication request to identity provider [" + providerId + "].", e);
|
||||
return redirectToErrorPage(Messages.UNEXPECTED_ERROR_HANDLING_REQUEST, e, providerId);
|
||||
}
|
||||
|
||||
return redirectToErrorPage("Could not proceed with authentication request to identity provider.");
|
||||
return redirectToErrorPage(Messages.COULD_NOT_PROCEED_WITH_AUTHENTICATION_REQUEST);
|
||||
}
|
||||
|
||||
@GET
|
||||
@@ -218,9 +219,9 @@ public class IdentityBrokerService {
|
||||
|
||||
return badRequest("Invalid token.");
|
||||
} catch (IdentityBrokerException e) {
|
||||
return redirectToErrorPage("Could not obtain token fron identity provider [" + providerId + "].", e);
|
||||
return redirectToErrorPage(Messages.COULD_NOT_OBTAIN_TOKEN, e, providerId);
|
||||
} catch (Exception e) {
|
||||
return redirectToErrorPage("Unexpected error when retrieving token from identity provider [" + providerId + "].", e);
|
||||
return redirectToErrorPage(Messages.UNEXPECTED_ERROR_RETRIEVING_TOKEN, e, providerId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +231,7 @@ public class IdentityBrokerService {
|
||||
public Response consentTokenRetrieval(@PathParam("provider_id") String providerId,
|
||||
MultivaluedMap<String, String> formData) {
|
||||
if (formData.containsKey("cancel")) {
|
||||
return redirectToErrorPage("Permission not approved.");
|
||||
return redirectToErrorPage(Messages.PERMISSION_NOT_APPROVED);
|
||||
}
|
||||
|
||||
return getToken(providerId, true);
|
||||
@@ -249,7 +250,7 @@ public class IdentityBrokerService {
|
||||
String relayState = identityProvider.getRelayState(createAuthenticationRequest(providerId, null));
|
||||
|
||||
if (relayState == null) {
|
||||
return redirectToErrorPage("No relay state in response from identity identity [" + providerId + ".");
|
||||
return redirectToErrorPage(Messages.NO_RELAY_STATE_IN_RESPONSE, providerId);
|
||||
}
|
||||
|
||||
if (isDebugEnabled()) {
|
||||
@@ -285,10 +286,10 @@ public class IdentityBrokerService {
|
||||
return performLocalAuthentication(identity, clientSessionCode);
|
||||
} catch (IdentityBrokerException e) {
|
||||
rollback();
|
||||
return redirectToErrorPage("Authentication failed. Could not authenticate with identity provider [" + providerId + "].", e);
|
||||
return redirectToErrorPage(Messages.IDENTITY_PROVIDER_AUTHENTICATION_FAILED, e, providerId);
|
||||
} catch (Exception e) {
|
||||
rollback();
|
||||
return redirectToErrorPage("Unexpected error when handling response from identity provider [" + providerId + "].", e);
|
||||
return redirectToErrorPage(Messages.UNEXPECTED_ERROR_HANDLING_RESPONSE, e, providerId);
|
||||
} finally {
|
||||
if (this.session.getTransaction().isActive()) {
|
||||
this.session.getTransaction().commit();
|
||||
@@ -351,7 +352,7 @@ public class IdentityBrokerService {
|
||||
this.event.event(EventType.IDENTITY_PROVIDER_ACCCOUNT_LINKING);
|
||||
|
||||
if (federatedUser != null) {
|
||||
return redirectToErrorPage("The identity returned by the identity provider [" + providerId + "] is already linked to other user.");
|
||||
return redirectToErrorPage(Messages.IDENTITY_PROVIDER_ALREADY_LINKED, providerId);
|
||||
}
|
||||
|
||||
UserModel authenticatedUser = clientSession.getUserSession().getUser();
|
||||
@@ -362,12 +363,12 @@ public class IdentityBrokerService {
|
||||
|
||||
if (!authenticatedUser.isEnabled()) {
|
||||
fireErrorEvent(Errors.USER_DISABLED);
|
||||
return redirectToErrorPage("User is disabled.");
|
||||
return redirectToErrorPage(Messages.USER_DISABLED);
|
||||
}
|
||||
|
||||
if (!authenticatedUser.hasRole(this.realmModel.getApplicationByName(ACCOUNT_MANAGEMENT_APP).getRole(MANAGE_ACCOUNT))) {
|
||||
fireErrorEvent(Errors.NOT_ALLOWED);
|
||||
return redirectToErrorPage("Insufficient permissions to link identities.");
|
||||
return redirectToErrorPage(Messages.INSUFFICIENT_PERMISSION);
|
||||
}
|
||||
|
||||
this.session.users().addFederatedIdentity(this.realmModel, authenticatedUser, federatedIdentityModel);
|
||||
@@ -436,24 +437,24 @@ public class IdentityBrokerService {
|
||||
return Urls.identityProviderAuthnResponse(this.uriInfo.getBaseUri(), providerId, this.realmModel.getName()).toString();
|
||||
}
|
||||
|
||||
private Response redirectToErrorPage(String message) {
|
||||
return redirectToErrorPage(message, null);
|
||||
private Response redirectToErrorPage(String message, Object ... parameters) {
|
||||
return redirectToErrorPage(message, null, parameters);
|
||||
}
|
||||
|
||||
private Response redirectToErrorPage(String message, Throwable throwable) {
|
||||
private Response redirectToErrorPage(String message, Throwable throwable, Object ... parameters) {
|
||||
if (message == null) {
|
||||
message = "Unexpected error when authenticating with identity provider";
|
||||
message = Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR;
|
||||
}
|
||||
|
||||
fireErrorEvent(message, throwable);
|
||||
return Flows.forwardToSecurityFailurePage(this.session, this.realmModel, this.uriInfo, message, headers);
|
||||
return Flows.forwardToSecurityFailurePage(this.session, this.realmModel, this.uriInfo, headers, message, parameters);
|
||||
}
|
||||
|
||||
private Response redirectToLoginPage(Throwable t, ClientSessionCode clientCode) {
|
||||
String message = t.getMessage();
|
||||
|
||||
if (message == null) {
|
||||
message = "Unexpected error when authenticating with identity provider";
|
||||
message = Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR;
|
||||
}
|
||||
|
||||
fireErrorEvent(message);
|
||||
|
||||
@@ -32,15 +32,8 @@ import org.keycloak.events.EventBuilder;
|
||||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.jose.jws.JWSBuilder;
|
||||
import org.keycloak.login.LoginFormsProvider;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredCredentialModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.UserModel.RequiredAction;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.TimeBasedOTP;
|
||||
import org.keycloak.protocol.LoginProtocol;
|
||||
@@ -156,7 +149,7 @@ public class LoginActionsService {
|
||||
return false;
|
||||
} else if (!clientCode.isValid(requiredAction)) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.", headers);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_CODE);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -166,18 +159,18 @@ public class LoginActionsService {
|
||||
public boolean check(String code) {
|
||||
if (!checkSsl()) {
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED );
|
||||
return false;
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.", headers);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
||||
return false;
|
||||
}
|
||||
clientCode = ClientSessionCode.parse(code, session, realm);
|
||||
if (clientCode == null) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.", headers);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_CODE );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -226,7 +219,7 @@ public class LoginActionsService {
|
||||
event.event(EventType.REGISTER);
|
||||
if (!realm.isRegistrationAllowed()) {
|
||||
event.error(Errors.REGISTRATION_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REGISTRATION_NOT_ALLOWED );
|
||||
}
|
||||
|
||||
Checks checks = new Checks();
|
||||
@@ -260,17 +253,17 @@ public class LoginActionsService {
|
||||
event.event(EventType.LOGIN);
|
||||
if (!checkSsl()) {
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED );
|
||||
}
|
||||
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
||||
}
|
||||
ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
|
||||
if (clientCode == null) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_CODE );
|
||||
}
|
||||
ClientSessionModel clientSession = clientCode.getClientSession();
|
||||
if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE) || clientSession.getUserSession() != null) {
|
||||
@@ -300,11 +293,11 @@ public class LoginActionsService {
|
||||
ClientModel client = clientSession.getClient();
|
||||
if (client == null) {
|
||||
event.error(Errors.CLIENT_NOT_FOUND);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_LOGIN_REQUESTER );
|
||||
}
|
||||
if (!client.isEnabled()) {
|
||||
event.error(Errors.CLIENT_NOT_FOUND);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.LOGIN_REQUESTER_NOT_ENABLED );
|
||||
}
|
||||
|
||||
if (formData.containsKey("cancel")) {
|
||||
@@ -389,25 +382,25 @@ public class LoginActionsService {
|
||||
event.event(EventType.REGISTER);
|
||||
if (!checkSsl()) {
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
||||
}
|
||||
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
||||
}
|
||||
if (!realm.isRegistrationAllowed()) {
|
||||
event.error(Errors.REGISTRATION_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REGISTRATION_NOT_ALLOWED );
|
||||
}
|
||||
ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
|
||||
if (clientCode == null) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_CODE );
|
||||
}
|
||||
if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE)) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_CODE );
|
||||
}
|
||||
|
||||
String username = formData.getFirst("username");
|
||||
@@ -422,17 +415,17 @@ public class LoginActionsService {
|
||||
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
||||
}
|
||||
ClientModel client = clientSession.getClient();
|
||||
if (client == null) {
|
||||
event.error(Errors.CLIENT_NOT_FOUND);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_LOGIN_REQUESTER );
|
||||
}
|
||||
|
||||
if (!client.isEnabled()) {
|
||||
event.error(Errors.CLIENT_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.LOGIN_REQUESTER_NOT_ENABLED );
|
||||
}
|
||||
|
||||
|
||||
@@ -442,15 +435,18 @@ public class LoginActionsService {
|
||||
}
|
||||
|
||||
// Validate here, so user is not created if password doesn't validate to passwordPolicy of current realm
|
||||
String error = Validation.validateRegistrationForm(formData, requiredCredentialTypes);
|
||||
if (error == null) {
|
||||
error = Validation.validatePassword(formData, realm.getPasswordPolicy());
|
||||
String errorMessage = Validation.validateRegistrationForm(formData, requiredCredentialTypes);
|
||||
Object[] parameters = new Object[0];
|
||||
if (errorMessage == null) {
|
||||
PasswordPolicy.Error error = Validation.validatePassword(formData, realm.getPasswordPolicy());
|
||||
errorMessage = error.getMessage();
|
||||
parameters = error.getParameters();
|
||||
}
|
||||
|
||||
if (error != null) {
|
||||
if (errorMessage != null) {
|
||||
event.error(Errors.INVALID_REGISTRATION);
|
||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
||||
.setError(error)
|
||||
.setError(errorMessage, parameters)
|
||||
.setFormData(formData)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
.createRegistration();
|
||||
@@ -490,9 +486,14 @@ public class LoginActionsService {
|
||||
|
||||
boolean passwordUpdateSuccessful;
|
||||
String passwordUpdateError = null;
|
||||
Object[] passwordUpdateErrorParameters = null;
|
||||
try {
|
||||
session.users().updateCredential(realm, user, UserCredentialModel.password(formData.getFirst("password")));
|
||||
passwordUpdateSuccessful = true;
|
||||
} catch (ModelException me) {
|
||||
passwordUpdateSuccessful = false;
|
||||
passwordUpdateError = me.getMessage();
|
||||
passwordUpdateErrorParameters = me.getParameters();
|
||||
} catch (Exception ape) {
|
||||
passwordUpdateSuccessful = false;
|
||||
passwordUpdateError = ape.getMessage();
|
||||
@@ -502,7 +503,7 @@ public class LoginActionsService {
|
||||
if (!passwordUpdateSuccessful) {
|
||||
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
|
||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
||||
.setError(passwordUpdateError)
|
||||
.setError(passwordUpdateError, passwordUpdateErrorParameters)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
.createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
|
||||
}
|
||||
@@ -528,7 +529,7 @@ public class LoginActionsService {
|
||||
|
||||
|
||||
if (!checkSsl()) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
||||
}
|
||||
|
||||
String code = formData.getFirst("code");
|
||||
@@ -536,7 +537,7 @@ public class LoginActionsService {
|
||||
ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
|
||||
if (accessCode == null || !accessCode.isValid(ClientSessionModel.Action.OAUTH_GRANT)) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid access code.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_ACCESS_CODE );
|
||||
}
|
||||
ClientSessionModel clientSession = accessCode.getClientSession();
|
||||
event.detail(Details.CODE_ID, clientSession.getId());
|
||||
@@ -560,7 +561,7 @@ public class LoginActionsService {
|
||||
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
|
||||
AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Session not active", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.SESSION_NOT_ACTIVE );
|
||||
}
|
||||
event.session(userSession);
|
||||
|
||||
@@ -715,6 +716,10 @@ public class LoginActionsService {
|
||||
|
||||
try {
|
||||
session.users().updateCredential(realm, user, UserCredentialModel.password(passwordNew));
|
||||
} catch (ModelException me) {
|
||||
return loginForms.setError(me.getMessage(), me.getParameters())
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
.createResponse(RequiredAction.UPDATE_PASSWORD);
|
||||
} catch (Exception ape) {
|
||||
return loginForms.setError(ape.getMessage())
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
@@ -794,16 +799,16 @@ public class LoginActionsService {
|
||||
final MultivaluedMap<String, String> formData) {
|
||||
event.event(EventType.SEND_RESET_PASSWORD);
|
||||
if (!checkSsl()) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
||||
}
|
||||
ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
|
||||
if (accessCode == null) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_CODE );
|
||||
}
|
||||
ClientSessionModel clientSession = accessCode.getClientSession();
|
||||
|
||||
@@ -811,12 +816,10 @@ public class LoginActionsService {
|
||||
|
||||
ClientModel client = clientSession.getClient();
|
||||
if (client == null) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
|
||||
"Unknown login requester.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_LOGIN_REQUESTER );
|
||||
}
|
||||
if (!client.isEnabled()) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
|
||||
"Login requester not enabled.", headers);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.LOGIN_REQUESTER_NOT_ENABLED );
|
||||
}
|
||||
|
||||
event.client(client.getClientId())
|
||||
@@ -859,13 +862,13 @@ public class LoginActionsService {
|
||||
} catch (EmailException e) {
|
||||
event.error(Errors.EMAIL_SEND_FAILED);
|
||||
logger.error("Failed to send password reset email", e);
|
||||
return Flows.forms(this.session, realm, client, uriInfo, headers).setError("emailSendError")
|
||||
return Flows.forms(this.session, realm, client, uriInfo, headers).setError(Messages.EMAIL_SENT_ERROR)
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
.createErrorPage();
|
||||
}
|
||||
}
|
||||
|
||||
return Flows.forms(session, realm, client, uriInfo, headers).setSuccess("emailSent").setClientSessionCode(accessCode.getCode()).createPasswordReset();
|
||||
return Flows.forms(session, realm, client, uriInfo, headers).setSuccess(Messages.EMAIL_SENT).setClientSessionCode(accessCode.getCode()).createPasswordReset();
|
||||
}
|
||||
|
||||
private Response redirectOauth(UserModel user, ClientSessionCode accessCode, ClientSessionModel clientSession, UserSessionModel userSession) {
|
||||
|
||||
@@ -46,8 +46,8 @@ public class Flows {
|
||||
return new ErrorFlows();
|
||||
}
|
||||
|
||||
public static Response forwardToSecurityFailurePage(KeycloakSession session, RealmModel realm, UriInfo uriInfo, String message, HttpHeaders headers) {
|
||||
return Flows.forms(session, realm, null, uriInfo, headers).setError(message).createErrorPage();
|
||||
public static Response forwardToSecurityFailurePage(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers, String message, Object ... parameters) {
|
||||
return Flows.forms(session, realm, null, uriInfo, headers).setError(message,parameters).createErrorPage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public class Validation {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String validatePassword(MultivaluedMap<String, String> formData, PasswordPolicy policy) {
|
||||
public static PasswordPolicy.Error validatePassword(MultivaluedMap<String, String> formData, PasswordPolicy policy) {
|
||||
return policy.validate(formData.getFirst("password"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user