commit
5ef1ddb9f1
64 changed files with 479 additions and 434 deletions
|
@ -34,7 +34,7 @@ import org.keycloak.models.FederatedIdentityModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorPage;
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
|
@ -217,7 +217,7 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
|
||||||
//logger.error("Failed " + getConfig().getAlias() + " broker login: " + error);
|
//logger.error("Failed " + getConfig().getAlias() + " broker login: " + error);
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(error);
|
event.error(error);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
|
return ErrorPage.error(session, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -239,7 +239,7 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
|
||||||
}
|
}
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.IDENTITY_PROVIDER_LOGIN_FAILURE);
|
event.error(Errors.IDENTITY_PROVIDER_LOGIN_FAILURE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
|
return ErrorPage.error(session, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleHttp generateTokenRequest(String authorizationCode) {
|
public SimpleHttp generateTokenRequest(String authorizationCode) {
|
||||||
|
|
|
@ -19,7 +19,6 @@ package org.keycloak.broker.oidc;
|
||||||
|
|
||||||
import org.codehaus.jackson.JsonNode;
|
import org.codehaus.jackson.JsonNode;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.RSATokenVerifier;
|
|
||||||
import org.keycloak.broker.oidc.util.SimpleHttp;
|
import org.keycloak.broker.oidc.util.SimpleHttp;
|
||||||
import org.keycloak.broker.provider.AuthenticationRequest;
|
import org.keycloak.broker.provider.AuthenticationRequest;
|
||||||
import org.keycloak.broker.provider.FederatedIdentity;
|
import org.keycloak.broker.provider.FederatedIdentity;
|
||||||
|
@ -37,7 +36,7 @@ import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.IdentityBrokerService;
|
import org.keycloak.services.resources.IdentityBrokerService;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorPage;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
import org.keycloak.util.PemUtils;
|
import org.keycloak.util.PemUtils;
|
||||||
|
|
||||||
|
@ -116,14 +115,14 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
|
||||||
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
||||||
event.event(EventType.LOGOUT);
|
event.event(EventType.LOGOUT);
|
||||||
event.error(Errors.USER_SESSION_NOT_FOUND);
|
event.error(Errors.USER_SESSION_NOT_FOUND);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
|
return ErrorPage.error(session, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
|
||||||
}
|
}
|
||||||
if (userSession.getState() != UserSessionModel.State.LOGGING_OUT) {
|
if (userSession.getState() != UserSessionModel.State.LOGGING_OUT) {
|
||||||
logger.error("usersession in different state");
|
logger.error("usersession in different state");
|
||||||
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
||||||
event.event(EventType.LOGOUT);
|
event.event(EventType.LOGOUT);
|
||||||
event.error(Errors.USER_SESSION_NOT_FOUND);
|
event.error(Errors.USER_SESSION_NOT_FOUND);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.SESSION_NOT_ACTIVE);
|
return ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE);
|
||||||
}
|
}
|
||||||
return AuthenticationManager.finishBrowserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
return AuthenticationManager.finishBrowserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import org.keycloak.protocol.saml.SamlProtocol;
|
||||||
import org.keycloak.protocol.saml.SamlProtocolUtils;
|
import org.keycloak.protocol.saml.SamlProtocolUtils;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorPage;
|
||||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||||
import org.keycloak.saml.common.constants.JBossSAMLConstants;
|
import org.keycloak.saml.common.constants.JBossSAMLConstants;
|
||||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
|
@ -130,18 +130,18 @@ public class SAMLEndpoint {
|
||||||
if (!checkSsl()) {
|
if (!checkSsl()) {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.SSL_REQUIRED);
|
event.error(Errors.SSL_REQUIRED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
return ErrorPage.error(session, Messages.HTTPS_REQUIRED);
|
||||||
}
|
}
|
||||||
if (!realm.isEnabled()) {
|
if (!realm.isEnabled()) {
|
||||||
event.event(EventType.LOGIN_ERROR);
|
event.event(EventType.LOGIN_ERROR);
|
||||||
event.error(Errors.REALM_DISABLED);
|
event.error(Errors.REALM_DISABLED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
return ErrorPage.error(session, Messages.REALM_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (samlRequest == null && samlResponse == null) {
|
if (samlRequest == null && samlResponse == null) {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.INVALID_REQUEST);
|
event.error(Errors.INVALID_REQUEST);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST );
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -177,7 +177,7 @@ public class SAMLEndpoint {
|
||||||
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
|
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
|
||||||
event.error(Errors.INVALID_SAML_RESPONSE);
|
event.error(Errors.INVALID_SAML_RESPONSE);
|
||||||
event.detail(Details.REASON, "invalid_destination");
|
event.detail(Details.REASON, "invalid_destination");
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
}
|
}
|
||||||
if (config.isValidateSignature()) {
|
if (config.isValidateSignature()) {
|
||||||
try {
|
try {
|
||||||
|
@ -186,7 +186,7 @@ public class SAMLEndpoint {
|
||||||
logger.error("validation failed", e);
|
logger.error("validation failed", e);
|
||||||
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
|
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
|
||||||
event.error(Errors.INVALID_SIGNATURE);
|
event.error(Errors.INVALID_SIGNATURE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUESTER);
|
return ErrorPage.error(session, Messages.INVALID_REQUESTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ public class SAMLEndpoint {
|
||||||
} else {
|
} else {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.INVALID_TOKEN);
|
event.error(Errors.INVALID_TOKEN);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ public class SAMLEndpoint {
|
||||||
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
|
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
|
||||||
event.error(Errors.INVALID_SAML_RESPONSE);
|
event.error(Errors.INVALID_SAML_RESPONSE);
|
||||||
event.detail(Details.REASON, "invalid_destination");
|
event.detail(Details.REASON, "invalid_destination");
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
|
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
|
||||||
}
|
}
|
||||||
if (config.isValidateSignature()) {
|
if (config.isValidateSignature()) {
|
||||||
try {
|
try {
|
||||||
|
@ -336,7 +336,7 @@ public class SAMLEndpoint {
|
||||||
logger.error("validation failed", e);
|
logger.error("validation failed", e);
|
||||||
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
|
event.event(EventType.IDENTITY_PROVIDER_RESPONSE);
|
||||||
event.error(Errors.INVALID_SIGNATURE);
|
event.error(Errors.INVALID_SIGNATURE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
|
return ErrorPage.error(session, Messages.INVALID_FEDERATED_IDENTITY_ACTION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (statusResponse instanceof ResponseType) {
|
if (statusResponse instanceof ResponseType) {
|
||||||
|
@ -355,20 +355,20 @@ public class SAMLEndpoint {
|
||||||
logger.error("no valid user session");
|
logger.error("no valid user session");
|
||||||
event.event(EventType.LOGOUT);
|
event.event(EventType.LOGOUT);
|
||||||
event.error(Errors.USER_SESSION_NOT_FOUND);
|
event.error(Errors.USER_SESSION_NOT_FOUND);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
|
return ErrorPage.error(session, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
|
||||||
}
|
}
|
||||||
UserSessionModel userSession = session.sessions().getUserSession(realm, relayState);
|
UserSessionModel userSession = session.sessions().getUserSession(realm, relayState);
|
||||||
if (userSession == null) {
|
if (userSession == null) {
|
||||||
logger.error("no valid user session");
|
logger.error("no valid user session");
|
||||||
event.event(EventType.LOGOUT);
|
event.event(EventType.LOGOUT);
|
||||||
event.error(Errors.USER_SESSION_NOT_FOUND);
|
event.error(Errors.USER_SESSION_NOT_FOUND);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
|
return ErrorPage.error(session, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR);
|
||||||
}
|
}
|
||||||
if (userSession.getState() != UserSessionModel.State.LOGGING_OUT) {
|
if (userSession.getState() != UserSessionModel.State.LOGGING_OUT) {
|
||||||
logger.error("usersession in different state");
|
logger.error("usersession in different state");
|
||||||
event.event(EventType.LOGOUT);
|
event.event(EventType.LOGOUT);
|
||||||
event.error(Errors.USER_SESSION_NOT_FOUND);
|
event.error(Errors.USER_SESSION_NOT_FOUND);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.SESSION_NOT_ACTIVE);
|
return ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE);
|
||||||
}
|
}
|
||||||
return AuthenticationManager.finishBrowserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
return AuthenticationManager.finishBrowserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
<module name="org.keycloak.keycloak-events-api"/>
|
<module name="org.keycloak.keycloak-events-api"/>
|
||||||
<module name="org.jboss.logging"/>
|
<module name="org.jboss.logging"/>
|
||||||
<module name="javax.api"/>
|
<module name="javax.api"/>
|
||||||
|
<module name="javax.ws.rs.api"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</module>
|
</module>
|
||||||
|
|
|
@ -36,6 +36,11 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
<artifactId>resteasy-jaxrs</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|
|
@ -3,23 +3,35 @@ package org.keycloak.events.log;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.events.Event;
|
import org.keycloak.events.Event;
|
||||||
import org.keycloak.events.EventListenerProvider;
|
import org.keycloak.events.EventListenerProvider;
|
||||||
|
import org.keycloak.models.KeycloakContext;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.Cookie;
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public class JBossLoggingEventListenerProvider implements EventListenerProvider {
|
public class JBossLoggingEventListenerProvider implements EventListenerProvider {
|
||||||
|
|
||||||
|
private final KeycloakSession session;
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
|
private final Logger.Level successLevel;
|
||||||
|
private final Logger.Level errorLevel;
|
||||||
|
|
||||||
public JBossLoggingEventListenerProvider(Logger logger) {
|
public JBossLoggingEventListenerProvider(KeycloakSession session, Logger logger, Logger.Level successLevel, Logger.Level errorLevel) {
|
||||||
|
this.session = session;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
|
this.successLevel = successLevel;
|
||||||
|
this.errorLevel = errorLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(Event event) {
|
public void onEvent(Event event) {
|
||||||
Logger.Level level = event.getError() != null ? Logger.Level.WARN : Logger.Level.INFO;
|
Logger.Level level = event.getError() != null ? errorLevel : successLevel;
|
||||||
|
|
||||||
if (logger.isEnabled(level)) {
|
if (logger.isEnabled(level)) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
@ -55,7 +67,31 @@ public class JBossLoggingEventListenerProvider implements EventListenerProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log(level, sb.toString());
|
if (logger.isTraceEnabled()) {
|
||||||
|
KeycloakContext context = session.getContext();
|
||||||
|
UriInfo uriInfo = context.getUri();
|
||||||
|
HttpHeaders headers = context.getRequestHeaders();
|
||||||
|
if (uriInfo != null) {
|
||||||
|
sb.append(", requestUri=");
|
||||||
|
sb.append(uriInfo.getRequestUri().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headers != null) {
|
||||||
|
sb.append(", cookies=[");
|
||||||
|
boolean f = true;
|
||||||
|
for (Map.Entry<String, Cookie> e : headers.getCookies().entrySet()) {
|
||||||
|
if (f) {
|
||||||
|
f = false;
|
||||||
|
} else {
|
||||||
|
sb.append(", ");
|
||||||
|
}
|
||||||
|
sb.append(e.getValue().toString());
|
||||||
|
}
|
||||||
|
sb.append("]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.log(logger.isTraceEnabled() ? Logger.Level.TRACE : level, sb.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@ import org.keycloak.events.EventListenerProvider;
|
||||||
import org.keycloak.events.EventListenerProviderFactory;
|
import org.keycloak.events.EventListenerProviderFactory;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import sun.rmi.runtime.Log;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -16,13 +19,18 @@ public class JBossLoggingEventListenerProviderFactory implements EventListenerPr
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger("org.keycloak.events");
|
private static final Logger logger = Logger.getLogger("org.keycloak.events");
|
||||||
|
|
||||||
|
private Logger.Level successLevel;
|
||||||
|
private Logger.Level errorLevel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventListenerProvider create(KeycloakSession session) {
|
public EventListenerProvider create(KeycloakSession session) {
|
||||||
return new JBossLoggingEventListenerProvider(logger);
|
return new JBossLoggingEventListenerProvider(session, logger, successLevel, errorLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void init(Config.Scope config) {
|
||||||
|
successLevel = Logger.Level.valueOf(config.get("success-level", "debug").toUpperCase());
|
||||||
|
errorLevel = Logger.Level.valueOf(config.get("error-level", "warn").toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -47,7 +47,7 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
import org.keycloak.models.utils.FormMessage;
|
import org.keycloak.models.utils.FormMessage;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
|
|
@ -6,7 +6,7 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.services.resources.AccountService;
|
import org.keycloak.services.resources.AccountService;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.keycloak.account.freemarker.model;
|
||||||
|
|
||||||
import org.keycloak.freemarker.Theme;
|
import org.keycloak.freemarker.Theme;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,6 @@ import org.keycloak.provider.Provider;
|
||||||
*/
|
*/
|
||||||
public interface LoginFormsProvider extends Provider {
|
public interface LoginFormsProvider extends Provider {
|
||||||
|
|
||||||
public LoginFormsProvider setRealm(RealmModel realm);
|
|
||||||
|
|
||||||
public LoginFormsProvider setUriInfo(UriInfo uriInfo);
|
|
||||||
|
|
||||||
public LoginFormsProvider setHttpHeaders(HttpHeaders httpHeaders);
|
|
||||||
|
|
||||||
public Response createResponse(UserModel.RequiredAction action);
|
public Response createResponse(UserModel.RequiredAction action);
|
||||||
|
|
||||||
public Response createLogin();
|
public Response createLogin();
|
||||||
|
@ -67,14 +61,8 @@ public interface LoginFormsProvider extends Provider {
|
||||||
|
|
||||||
public LoginFormsProvider setSuccess(String message, Object ... parameters);
|
public LoginFormsProvider setSuccess(String message, Object ... parameters);
|
||||||
|
|
||||||
public LoginFormsProvider setWarning(String message, Object ... parameters);
|
|
||||||
|
|
||||||
public LoginFormsProvider setUser(UserModel user);
|
public LoginFormsProvider setUser(UserModel user);
|
||||||
|
|
||||||
public LoginFormsProvider setClient(ClientModel client);
|
|
||||||
|
|
||||||
public LoginFormsProvider setQueryParams(MultivaluedMap<String, String> queryParams);
|
|
||||||
|
|
||||||
public LoginFormsProvider setResponseHeader(String headerName, String headerValue);
|
public LoginFormsProvider setResponseHeader(String headerName, String headerValue);
|
||||||
|
|
||||||
public LoginFormsProvider setFormData(MultivaluedMap<String, String> formData);
|
public LoginFormsProvider setFormData(MultivaluedMap<String, String> formData);
|
||||||
|
|
|
@ -37,9 +37,8 @@ import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.FormMessage;
|
import org.keycloak.models.utils.FormMessage;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
@ -79,39 +78,20 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
private KeycloakSession session;
|
private KeycloakSession session;
|
||||||
private FreeMarkerUtil freeMarker;
|
private FreeMarkerUtil freeMarker;
|
||||||
private RealmModel realm;
|
|
||||||
|
|
||||||
private UserModel user;
|
private UserModel user;
|
||||||
|
|
||||||
private ClientModel client;
|
|
||||||
private ClientSessionModel clientSession;
|
private ClientSessionModel clientSession;
|
||||||
|
|
||||||
private UriInfo uriInfo;
|
|
||||||
|
|
||||||
private HttpHeaders httpHeaders;
|
|
||||||
|
|
||||||
public FreeMarkerLoginFormsProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
|
public FreeMarkerLoginFormsProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.freeMarker = freeMarker;
|
this.freeMarker = freeMarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoginFormsProvider setRealm(RealmModel realm) {
|
|
||||||
this.realm = realm;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoginFormsProvider setUriInfo(UriInfo uriInfo) {
|
|
||||||
this.uriInfo = uriInfo;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoginFormsProvider setHttpHeaders(HttpHeaders httpHeaders) {
|
|
||||||
this.httpHeaders = httpHeaders;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Response createResponse(UserModel.RequiredAction action) {
|
public Response createResponse(UserModel.RequiredAction action) {
|
||||||
|
RealmModel realm = session.getContext().getRealm();
|
||||||
|
UriInfo uriInfo = session.getContext().getUri();
|
||||||
|
|
||||||
String actionMessage;
|
String actionMessage;
|
||||||
LoginFormsPages page;
|
LoginFormsPages page;
|
||||||
|
|
||||||
|
@ -150,13 +130,17 @@ import java.util.concurrent.TimeUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messages == null) {
|
if (messages == null) {
|
||||||
setWarning(actionMessage);
|
setMessage(MessageType.WARNING, actionMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return createResponse(page);
|
return createResponse(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response createResponse(LoginFormsPages page) {
|
private Response createResponse(LoginFormsPages page) {
|
||||||
|
RealmModel realm = session.getContext().getRealm();
|
||||||
|
ClientModel client = session.getContext().getClient();
|
||||||
|
UriInfo uriInfo = session.getContext().getUri();
|
||||||
|
|
||||||
MultivaluedMap<String, String> queryParameterMap = queryParams != null ? queryParams : new MultivaluedMapImpl<String, String>();
|
MultivaluedMap<String, String> queryParameterMap = queryParams != null ? queryParams : new MultivaluedMapImpl<String, String>();
|
||||||
|
|
||||||
String requestURI = uriInfo.getBaseUri().getPath();
|
String requestURI = uriInfo.getBaseUri().getPath();
|
||||||
|
@ -191,7 +175,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Properties messagesBundle;
|
Properties messagesBundle;
|
||||||
Locale locale = LocaleHelper.getLocale(realm, user, uriInfo, httpHeaders);
|
Locale locale = LocaleHelper.getLocale(realm, user, uriInfo, session.getContext().getRequestHeaders());
|
||||||
try {
|
try {
|
||||||
messagesBundle = theme.getMessages(locale);
|
messagesBundle = theme.getMessages(locale);
|
||||||
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
|
||||||
|
@ -222,7 +206,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
if (realm != null) {
|
if (realm != null) {
|
||||||
attributes.put("realm", new RealmBean(realm));
|
attributes.put("realm", new RealmBean(realm));
|
||||||
attributes.put("social", new IdentityProviderBean(realm, baseUri, this.uriInfo));
|
attributes.put("social", new IdentityProviderBean(realm, baseUri, uriInfo));
|
||||||
attributes.put("url", new UrlBean(realm, theme, baseUri, this.actionUri));
|
attributes.put("url", new UrlBean(realm, theme, baseUri, this.actionUri));
|
||||||
|
|
||||||
if (realm.isInternationalizationEnabled()) {
|
if (realm.isInternationalizationEnabled()) {
|
||||||
|
@ -365,22 +349,11 @@ import java.util.concurrent.TimeUnit;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FreeMarkerLoginFormsProvider setWarning(String message, Object ... parameters) {
|
|
||||||
setMessage(MessageType.WARNING, message, parameters);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FreeMarkerLoginFormsProvider setUser(UserModel user) {
|
public FreeMarkerLoginFormsProvider setUser(UserModel user) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FreeMarkerLoginFormsProvider setClient(ClientModel client) {
|
|
||||||
this.client = client;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FreeMarkerLoginFormsProvider setFormData(MultivaluedMap<String, String> formData) {
|
public FreeMarkerLoginFormsProvider setFormData(MultivaluedMap<String, String> formData) {
|
||||||
this.formData = formData;
|
this.formData = formData;
|
||||||
return this;
|
return this;
|
||||||
|
@ -411,12 +384,6 @@ import java.util.concurrent.TimeUnit;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public LoginFormsProvider setQueryParams(MultivaluedMap<String, String> queryParams) {
|
|
||||||
this.queryParams = queryParams;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoginFormsProvider setActionUri(URI actionUri) {
|
public LoginFormsProvider setActionUri(URI actionUri) {
|
||||||
this.actionUri = actionUri;
|
this.actionUri = actionUri;
|
||||||
|
|
|
@ -23,7 +23,7 @@ package org.keycloak.login.freemarker.model;
|
||||||
|
|
||||||
import org.keycloak.models.IdentityProviderModel;
|
import org.keycloak.models.IdentityProviderModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
|
@ -23,7 +23,7 @@ package org.keycloak.login.freemarker.model;
|
||||||
|
|
||||||
import org.keycloak.freemarker.Theme;
|
import org.keycloak.freemarker.Theme;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@
|
||||||
<description/>
|
<description/>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
<artifactId>resteasy-jaxrs</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.iharder</groupId>
|
<groupId>net.iharder</groupId>
|
||||||
<artifactId>base64</artifactId>
|
<artifactId>base64</artifactId>
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
public interface KeycloakContext {
|
||||||
|
|
||||||
|
UriInfo getUri();
|
||||||
|
|
||||||
|
HttpHeaders getRequestHeaders();
|
||||||
|
|
||||||
|
RealmModel getRealm();
|
||||||
|
|
||||||
|
void setRealm(RealmModel realm);
|
||||||
|
|
||||||
|
ClientModel getClient();
|
||||||
|
|
||||||
|
void setClient(ClientModel client);
|
||||||
|
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ import java.util.Set;
|
||||||
*/
|
*/
|
||||||
public interface KeycloakSession {
|
public interface KeycloakSession {
|
||||||
|
|
||||||
|
KeycloakContext getContext();
|
||||||
|
|
||||||
KeycloakTransactionManager getTransaction();
|
KeycloakTransactionManager getTransaction();
|
||||||
|
|
||||||
<T extends Provider> T getProvider(Class<T> clazz);
|
<T extends Provider> T getProvider(Class<T> clazz);
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class RepresentationToModel {
|
||||||
if (rep.getFailureFactor() != null) newRealm.setFailureFactor(rep.getFailureFactor());
|
if (rep.getFailureFactor() != null) newRealm.setFailureFactor(rep.getFailureFactor());
|
||||||
if (rep.isEventsEnabled() != null) newRealm.setEventsEnabled(rep.isEventsEnabled());
|
if (rep.isEventsEnabled() != null) newRealm.setEventsEnabled(rep.isEventsEnabled());
|
||||||
if (rep.getEventsExpiration() != null) newRealm.setEventsExpiration(rep.getEventsExpiration());
|
if (rep.getEventsExpiration() != null) newRealm.setEventsExpiration(rep.getEventsExpiration());
|
||||||
if (rep.getEventsListeners() != null) newRealm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
|
if (rep.getEventsListeners() != null) newRealm.setEventsListeners(new HashSet<>(rep.getEventsListeners()));
|
||||||
|
|
||||||
if (rep.getNotBefore() != null) newRealm.setNotBefore(rep.getNotBefore());
|
if (rep.getNotBefore() != null) newRealm.setNotBefore(rep.getNotBefore());
|
||||||
|
|
||||||
|
@ -409,8 +409,8 @@ public class RepresentationToModel {
|
||||||
if (rep.getEmailTheme() != null) realm.setEmailTheme(rep.getEmailTheme());
|
if (rep.getEmailTheme() != null) realm.setEmailTheme(rep.getEmailTheme());
|
||||||
if (rep.isEventsEnabled() != null) realm.setEventsEnabled(rep.isEventsEnabled());
|
if (rep.isEventsEnabled() != null) realm.setEventsEnabled(rep.isEventsEnabled());
|
||||||
if (rep.getEventsExpiration() != null) realm.setEventsExpiration(rep.getEventsExpiration());
|
if (rep.getEventsExpiration() != null) realm.setEventsExpiration(rep.getEventsExpiration());
|
||||||
if (rep.getEventsListeners() != null) realm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
|
if (rep.getEventsListeners() != null) realm.setEventsListeners(new HashSet<>(rep.getEventsListeners()));
|
||||||
if (rep.getEnabledEventTypes() != null) realm.setEnabledEventTypes(new HashSet<String>(rep.getEnabledEventTypes()));
|
if (rep.getEnabledEventTypes() != null) realm.setEnabledEventTypes(new HashSet<>(rep.getEnabledEventTypes()));
|
||||||
|
|
||||||
if (rep.getPasswordPolicy() != null) realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
|
if (rep.getPasswordPolicy() != null) realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ import org.keycloak.services.managers.ResourceAdminManager;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.services.resources.admin.ClientAttributeCertificateResource;
|
import org.keycloak.services.resources.admin.ClientAttributeCertificateResource;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorPage;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
@ -152,7 +152,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
return builder.redirectBinding().response();
|
return builder.redirectBinding().response();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.FAILED_TO_PROCESS_RESPONSE );
|
return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
samlDocument = builder.buildDocument(samlModel);
|
samlDocument = builder.buildDocument(samlModel);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("failed", e);
|
logger.error("failed", e);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,headers, Messages.FAILED_TO_PROCESS_RESPONSE);
|
return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAML2BindingBuilder2 bindingBuilder = new SAML2BindingBuilder2();
|
SAML2BindingBuilder2 bindingBuilder = new SAML2BindingBuilder2();
|
||||||
|
@ -331,7 +331,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
publicKey = SamlProtocolUtils.getEncryptionValidationKey(client);
|
publicKey = SamlProtocolUtils.getEncryptionValidationKey(client);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("failed", e);
|
logger.error("failed", e);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.FAILED_TO_PROCESS_RESPONSE);
|
return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE);
|
||||||
}
|
}
|
||||||
bindingBuilder.encrypt(publicKey);
|
bindingBuilder.encrypt(publicKey);
|
||||||
}
|
}
|
||||||
|
@ -343,7 +343,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("failed", e);
|
logger.error("failed", e);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.FAILED_TO_PROCESS_RESPONSE );
|
return ErrorPage.error(session, Messages.FAILED_TO_PROCESS_RESPONSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import org.keycloak.services.managers.ClientSessionCode;
|
||||||
import org.keycloak.services.managers.HttpAuthenticationManager;
|
import org.keycloak.services.managers.HttpAuthenticationManager;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorPage;
|
||||||
import org.keycloak.util.StreamUtil;
|
import org.keycloak.util.StreamUtil;
|
||||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
|
@ -102,18 +102,18 @@ public class SamlService {
|
||||||
if (!checkSsl()) {
|
if (!checkSsl()) {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.SSL_REQUIRED);
|
event.error(Errors.SSL_REQUIRED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED );
|
return ErrorPage.error(session, Messages.HTTPS_REQUIRED);
|
||||||
}
|
}
|
||||||
if (!realm.isEnabled()) {
|
if (!realm.isEnabled()) {
|
||||||
event.event(EventType.LOGIN_ERROR);
|
event.event(EventType.LOGIN_ERROR);
|
||||||
event.error(Errors.REALM_DISABLED);
|
event.error(Errors.REALM_DISABLED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
return ErrorPage.error(session, Messages.REALM_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (samlRequest == null && samlResponse == null) {
|
if (samlRequest == null && samlResponse == null) {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.INVALID_TOKEN);
|
event.error(Errors.INVALID_TOKEN);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST );
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -127,7 +127,7 @@ public class SamlService {
|
||||||
if (!uriInfo.getAbsolutePath().toString().equals(statusResponse.getDestination())) {
|
if (!uriInfo.getAbsolutePath().toString().equals(statusResponse.getDestination())) {
|
||||||
event.error(Errors.INVALID_SAML_LOGOUT_RESPONSE);
|
event.error(Errors.INVALID_SAML_LOGOUT_RESPONSE);
|
||||||
event.detail(Details.REASON, "invalid_destination");
|
event.detail(Details.REASON, "invalid_destination");
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, clientConnection, headers, false);
|
AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, clientConnection, headers, false);
|
||||||
|
@ -135,7 +135,7 @@ public class SamlService {
|
||||||
logger.warn("Unknown saml response.");
|
logger.warn("Unknown saml response.");
|
||||||
event.event(EventType.LOGOUT);
|
event.event(EventType.LOGOUT);
|
||||||
event.error(Errors.INVALID_TOKEN);
|
event.error(Errors.INVALID_TOKEN);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
}
|
}
|
||||||
// assume this is a logout response
|
// assume this is a logout response
|
||||||
UserSessionModel userSession = authResult.getSession();
|
UserSessionModel userSession = authResult.getSession();
|
||||||
|
@ -144,7 +144,7 @@ public class SamlService {
|
||||||
logger.warn("UserSession is not tagged as logging out.");
|
logger.warn("UserSession is not tagged as logging out.");
|
||||||
event.event(EventType.LOGOUT);
|
event.event(EventType.LOGOUT);
|
||||||
event.error(Errors.INVALID_SAML_LOGOUT_RESPONSE);
|
event.error(Errors.INVALID_SAML_LOGOUT_RESPONSE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
}
|
}
|
||||||
logger.debug("logout response");
|
logger.debug("logout response");
|
||||||
Response response = authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
Response response = authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||||
|
@ -157,7 +157,7 @@ public class SamlService {
|
||||||
if (documentHolder == null) {
|
if (documentHolder == null) {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.INVALID_TOKEN);
|
event.error(Errors.INVALID_TOKEN);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAML2Object samlObject = documentHolder.getSamlObject();
|
SAML2Object samlObject = documentHolder.getSamlObject();
|
||||||
|
@ -169,32 +169,34 @@ public class SamlService {
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.CLIENT_NOT_FOUND);
|
event.error(Errors.CLIENT_NOT_FOUND);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_LOGIN_REQUESTER);
|
return ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!client.isEnabled()) {
|
if (!client.isEnabled()) {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.CLIENT_DISABLED);
|
event.error(Errors.CLIENT_DISABLED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.LOGIN_REQUESTER_NOT_ENABLED);
|
return ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
if ((client instanceof ClientModel) && ((ClientModel)client).isBearerOnly()) {
|
if ((client instanceof ClientModel) && ((ClientModel)client).isBearerOnly()) {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.NOT_ALLOWED);
|
event.error(Errors.NOT_ALLOWED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.BEARER_ONLY);
|
return ErrorPage.error(session, Messages.BEARER_ONLY);
|
||||||
}
|
}
|
||||||
if (client.isDirectGrantsOnly()) {
|
if (client.isDirectGrantsOnly()) {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.NOT_ALLOWED);
|
event.error(Errors.NOT_ALLOWED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.DIRECT_GRANTS_ONLY );
|
return ErrorPage.error(session, Messages.DIRECT_GRANTS_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.getContext().setClient(client);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
verifySignature(documentHolder, client);
|
verifySignature(documentHolder, client);
|
||||||
} catch (VerificationException e) {
|
} catch (VerificationException e) {
|
||||||
SamlService.logger.error("request validation failed", e);
|
SamlService.logger.error("request validation failed", e);
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.INVALID_SIGNATURE);
|
event.error(Errors.INVALID_SIGNATURE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUESTER);
|
return ErrorPage.error(session, Messages.INVALID_REQUESTER);
|
||||||
}
|
}
|
||||||
logger.debug("verified request");
|
logger.debug("verified request");
|
||||||
if (samlObject instanceof AuthnRequestType) {
|
if (samlObject instanceof AuthnRequestType) {
|
||||||
|
@ -212,7 +214,7 @@ public class SamlService {
|
||||||
} else {
|
} else {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error(Errors.INVALID_TOKEN);
|
event.error(Errors.INVALID_TOKEN);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,7 +228,7 @@ public class SamlService {
|
||||||
if (!uriInfo.getAbsolutePath().equals(requestAbstractType.getDestination())) {
|
if (!uriInfo.getAbsolutePath().equals(requestAbstractType.getDestination())) {
|
||||||
event.error(Errors.INVALID_SAML_AUTHN_REQUEST);
|
event.error(Errors.INVALID_SAML_AUTHN_REQUEST);
|
||||||
event.detail(Details.REASON, "invalid_destination");
|
event.detail(Details.REASON, "invalid_destination");
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
}
|
}
|
||||||
String bindingType = getBindingType(requestAbstractType);
|
String bindingType = getBindingType(requestAbstractType);
|
||||||
if ("true".equals(client.getAttribute(SamlProtocol.SAML_FORCE_POST_BINDING))) bindingType = SamlProtocol.SAML_POST_BINDING;
|
if ("true".equals(client.getAttribute(SamlProtocol.SAML_FORCE_POST_BINDING))) bindingType = SamlProtocol.SAML_POST_BINDING;
|
||||||
|
@ -248,7 +250,7 @@ public class SamlService {
|
||||||
|
|
||||||
if (redirect == null) {
|
if (redirect == null) {
|
||||||
event.error(Errors.INVALID_REDIRECT_URI);
|
event.error(Errors.INVALID_REDIRECT_URI);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REDIRECT_URI );
|
return ErrorPage.error(session, Messages.INVALID_REDIRECT_URI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -271,7 +273,7 @@ public class SamlService {
|
||||||
} else {
|
} else {
|
||||||
event.error(Errors.INVALID_SAML_AUTHN_REQUEST);
|
event.error(Errors.INVALID_SAML_AUTHN_REQUEST);
|
||||||
event.detail(Details.REASON, "unsupported_nameid_format");
|
event.detail(Details.REASON, "unsupported_nameid_format");
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNSUPPORTED_NAME_ID_FORMAT);
|
return ErrorPage.error(session, Messages.UNSUPPORTED_NAME_ID_FORMAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +285,7 @@ public class SamlService {
|
||||||
HttpAuthenticationManager.HttpAuthOutput httpAuthOutput = httpAuthManager.spnegoAuthenticate(headers);
|
HttpAuthenticationManager.HttpAuthOutput httpAuthOutput = httpAuthManager.spnegoAuthenticate(headers);
|
||||||
if (httpAuthOutput.getResponse() != null) return httpAuthOutput.getResponse();
|
if (httpAuthOutput.getResponse() != null) return httpAuthOutput.getResponse();
|
||||||
|
|
||||||
LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers)
|
LoginFormsProvider forms = session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(new ClientSessionCode(realm, clientSession).getCode());
|
.setClientSessionCode(new ClientSessionCode(realm, clientSession).getCode());
|
||||||
|
|
||||||
// Attach state from SPNEGO authentication
|
// Attach state from SPNEGO authentication
|
||||||
|
@ -335,7 +337,7 @@ public class SamlService {
|
||||||
if (!uriInfo.getAbsolutePath().equals(logoutRequest.getDestination())) {
|
if (!uriInfo.getAbsolutePath().equals(logoutRequest.getDestination())) {
|
||||||
event.error(Errors.INVALID_SAML_LOGOUT_REQUEST);
|
event.error(Errors.INVALID_SAML_LOGOUT_REQUEST);
|
||||||
event.detail(Details.REASON, "invalid_destination");
|
event.detail(Details.REASON, "invalid_destination");
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REQUEST);
|
return ErrorPage.error(session, Messages.INVALID_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
// authenticate identity cookie, but ignore an access token timeout as we're logging out anyways.
|
// authenticate identity cookie, but ignore an access token timeout as we're logging out anyways.
|
||||||
|
@ -374,7 +376,7 @@ public class SamlService {
|
||||||
if (redirectUri != null) {
|
if (redirectUri != null) {
|
||||||
redirectUri = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri, realm, client);
|
redirectUri = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri, realm, client);
|
||||||
if (redirectUri == null) {
|
if (redirectUri == null) {
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REDIRECT_URI );
|
return ErrorPage.error(session, Messages.INVALID_REDIRECT_URI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (redirectUri != null) {
|
if (redirectUri != null) {
|
||||||
|
|
|
@ -14,6 +14,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"eventsListener": {
|
||||||
|
"jboss-logging" : {
|
||||||
|
"success-level": "debug",
|
||||||
|
"error-level": "warn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"realm": {
|
"realm": {
|
||||||
"provider": "jpa"
|
"provider": "jpa"
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,7 +18,6 @@ import org.keycloak.protocol.oidc.endpoints.ValidateTokenEndpoint;
|
||||||
import org.keycloak.protocol.oidc.representations.JSONWebKeySet;
|
import org.keycloak.protocol.oidc.representations.JSONWebKeySet;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
@ -204,7 +203,7 @@ public class OIDCLoginProtocolService {
|
||||||
@Path("oauth/oob")
|
@Path("oauth/oob")
|
||||||
@GET
|
@GET
|
||||||
public Response installedAppUrnCallback(final @QueryParam("code") String code, final @QueryParam("error") String error, final @QueryParam("error_description") String errorDescription) {
|
public Response installedAppUrnCallback(final @QueryParam("code") String code, final @QueryParam("error") String error, final @QueryParam("error_description") String errorDescription) {
|
||||||
LoginFormsProvider forms = Flows.forms(session, realm, null, uriInfo, headers);
|
LoginFormsProvider forms = session.getProvider(LoginFormsProvider.class);
|
||||||
if (code != null) {
|
if (code != null) {
|
||||||
return forms.setClientSessionCode(code).createCode();
|
return forms.setClientSessionCode(code).createCode();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
package org.keycloak.protocol.oidc;
|
package org.keycloak.protocol.oidc;
|
||||||
|
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
|
import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.wellknown.WellKnownProvider;
|
import org.keycloak.wellknown.WellKnownProvider;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -29,8 +28,17 @@ public class OIDCWellKnownProvider implements WellKnownProvider {
|
||||||
|
|
||||||
public static final List<String> DEFAULT_RESPONSE_MODES_SUPPORTED = list("query");
|
public static final List<String> DEFAULT_RESPONSE_MODES_SUPPORTED = list("query");
|
||||||
|
|
||||||
|
private KeycloakSession session;
|
||||||
|
|
||||||
|
public OIDCWellKnownProvider(KeycloakSession session) {
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getConfig(RealmModel realm, UriInfo uriInfo) {
|
public Object getConfig() {
|
||||||
|
UriInfo uriInfo = session.getContext().getUri();
|
||||||
|
RealmModel realm = session.getContext().getRealm();
|
||||||
|
|
||||||
UriBuilder uriBuilder = RealmsResource.protocolUrl(uriInfo);
|
UriBuilder uriBuilder = RealmsResource.protocolUrl(uriInfo);
|
||||||
|
|
||||||
OIDCConfigurationRepresentation config = new OIDCConfigurationRepresentation();
|
OIDCConfigurationRepresentation config = new OIDCConfigurationRepresentation();
|
||||||
|
|
|
@ -11,16 +11,13 @@ import org.keycloak.wellknown.WellKnownProviderFactory;
|
||||||
*/
|
*/
|
||||||
public class OIDCWellKnownProviderFactory implements WellKnownProviderFactory {
|
public class OIDCWellKnownProviderFactory implements WellKnownProviderFactory {
|
||||||
|
|
||||||
private WellKnownProvider provider;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WellKnownProvider create(KeycloakSession session) {
|
public WellKnownProvider create(KeycloakSession session) {
|
||||||
return provider;
|
return new OIDCWellKnownProvider(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void init(Config.Scope config) {
|
||||||
provider = new OIDCWellKnownProvider();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,7 +26,6 @@ public class OIDCWellKnownProviderFactory implements WellKnownProviderFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
provider = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,8 +25,7 @@ import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.ClientSessionCode;
|
import org.keycloak.services.managers.ClientSessionCode;
|
||||||
import org.keycloak.services.managers.HttpAuthenticationManager;
|
import org.keycloak.services.managers.HttpAuthenticationManager;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
|
@ -116,7 +115,7 @@ public class AuthorizationEndpoint {
|
||||||
action = Action.REGISTER;
|
action = Action.REGISTER;
|
||||||
|
|
||||||
if (!realm.isRegistrationAllowed()) {
|
if (!realm.isRegistrationAllowed()) {
|
||||||
throw new ErrorPageException(session, realm, uriInfo, headers, Messages.REGISTRATION_NOT_ALLOWED);
|
throw new ErrorPageException(session, Messages.REGISTRATION_NOT_ALLOWED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -148,21 +147,21 @@ public class AuthorizationEndpoint {
|
||||||
private void checkSsl() {
|
private void checkSsl() {
|
||||||
if (!uriInfo.getBaseUri().getScheme().equals("https") && realm.getSslRequired().isRequired(clientConnection)) {
|
if (!uriInfo.getBaseUri().getScheme().equals("https") && realm.getSslRequired().isRequired(clientConnection)) {
|
||||||
event.error(Errors.SSL_REQUIRED);
|
event.error(Errors.SSL_REQUIRED);
|
||||||
throw new ErrorPageException(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
throw new ErrorPageException(session, Messages.HTTPS_REQUIRED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRealm() {
|
private void checkRealm() {
|
||||||
if (!realm.isEnabled()) {
|
if (!realm.isEnabled()) {
|
||||||
event.error(Errors.REALM_DISABLED);
|
event.error(Errors.REALM_DISABLED);
|
||||||
throw new ErrorPageException(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
throw new ErrorPageException(session, Messages.REALM_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkClient() {
|
private void checkClient() {
|
||||||
if (clientId == null) {
|
if (clientId == null) {
|
||||||
event.error(Errors.INVALID_REQUEST);
|
event.error(Errors.INVALID_REQUEST);
|
||||||
throw new ErrorPageException(session, realm, uriInfo, headers, Messages.MISSING_PARAMETER, OIDCLoginProtocol.CLIENT_ID_PARAM );
|
throw new ErrorPageException(session, Messages.MISSING_PARAMETER, OIDCLoginProtocol.CLIENT_ID_PARAM );
|
||||||
}
|
}
|
||||||
|
|
||||||
event.client(clientId);
|
event.client(clientId);
|
||||||
|
@ -170,18 +169,20 @@ public class AuthorizationEndpoint {
|
||||||
client = realm.getClientByClientId(clientId);
|
client = realm.getClientByClientId(clientId);
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
event.error(Errors.CLIENT_NOT_FOUND);
|
event.error(Errors.CLIENT_NOT_FOUND);
|
||||||
throw new ErrorPageException(session, realm, uriInfo, headers, Messages.CLIENT_NOT_FOUND );
|
throw new ErrorPageException(session, Messages.CLIENT_NOT_FOUND );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((client instanceof ClientModel) && ((ClientModel) client).isBearerOnly()) {
|
if ((client instanceof ClientModel) && ((ClientModel) client).isBearerOnly()) {
|
||||||
event.error(Errors.NOT_ALLOWED);
|
event.error(Errors.NOT_ALLOWED);
|
||||||
throw new ErrorPageException(session, realm, uriInfo, headers, Messages.BEARER_ONLY );
|
throw new ErrorPageException(session, Messages.BEARER_ONLY );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client.isDirectGrantsOnly()) {
|
if (client.isDirectGrantsOnly()) {
|
||||||
event.error(Errors.NOT_ALLOWED);
|
event.error(Errors.NOT_ALLOWED);
|
||||||
throw new ErrorPageException(session, realm, uriInfo, headers, Messages.DIRECT_GRANTS_ONLY);
|
throw new ErrorPageException(session, Messages.DIRECT_GRANTS_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.getContext().setClient(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkResponseType() {
|
private void checkResponseType() {
|
||||||
|
@ -190,7 +191,7 @@ public class AuthorizationEndpoint {
|
||||||
responseType = legacyResponseType;
|
responseType = legacyResponseType;
|
||||||
} else {
|
} else {
|
||||||
event.error(Errors.INVALID_REQUEST);
|
event.error(Errors.INVALID_REQUEST);
|
||||||
throw new ErrorPageException(session, realm, uriInfo, headers, Messages.MISSING_PARAMETER, OIDCLoginProtocol.RESPONSE_TYPE_PARAM );
|
throw new ErrorPageException(session, Messages.MISSING_PARAMETER, OIDCLoginProtocol.RESPONSE_TYPE_PARAM );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +201,7 @@ public class AuthorizationEndpoint {
|
||||||
action = Action.CODE;
|
action = Action.CODE;
|
||||||
} else {
|
} else {
|
||||||
event.error(Errors.INVALID_REQUEST);
|
event.error(Errors.INVALID_REQUEST);
|
||||||
throw new ErrorPageException(session, realm, uriInfo, headers, Messages.INVALID_PARAMETER, OIDCLoginProtocol.RESPONSE_TYPE_PARAM );
|
throw new ErrorPageException(session, Messages.INVALID_PARAMETER, OIDCLoginProtocol.RESPONSE_TYPE_PARAM );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +211,7 @@ public class AuthorizationEndpoint {
|
||||||
redirectUri = RedirectUtils.verifyRedirectUri(uriInfo, redirectUriParam, realm, client);
|
redirectUri = RedirectUtils.verifyRedirectUri(uriInfo, redirectUriParam, realm, client);
|
||||||
if (redirectUri == null) {
|
if (redirectUri == null) {
|
||||||
event.error(Errors.INVALID_REDIRECT_URI);
|
event.error(Errors.INVALID_REDIRECT_URI);
|
||||||
throw new ErrorPageException(session, realm, uriInfo, headers, Messages.INVALID_PARAMETER, OIDCLoginProtocol.REDIRECT_URI_PARAM);
|
throw new ErrorPageException(session, Messages.INVALID_PARAMETER, OIDCLoginProtocol.REDIRECT_URI_PARAM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +239,7 @@ public class AuthorizationEndpoint {
|
||||||
IdentityProviderModel identityProviderModel = realm.getIdentityProviderByAlias(idpHint);
|
IdentityProviderModel identityProviderModel = realm.getIdentityProviderByAlias(idpHint);
|
||||||
|
|
||||||
if (identityProviderModel == null) {
|
if (identityProviderModel == null) {
|
||||||
return Flows.forms(session, realm, null, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setError(Messages.IDENTITY_PROVIDER_NOT_FOUND, idpHint)
|
.setError(Messages.IDENTITY_PROVIDER_NOT_FOUND, idpHint)
|
||||||
.createErrorPage();
|
.createErrorPage();
|
||||||
}
|
}
|
||||||
|
@ -272,14 +273,13 @@ public class AuthorizationEndpoint {
|
||||||
return buildRedirectToIdentityProvider(identityProviders.get(0).getAlias(), accessCode);
|
return buildRedirectToIdentityProvider(identityProviders.get(0).getAlias(), accessCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Flows.forms(session, realm, null, uriInfo, headers).setError(Messages.IDENTITY_PROVIDER_NOT_UNIQUE, realm.getName()).createErrorPage();
|
return session.getProvider(LoginFormsProvider.class).setError(Messages.IDENTITY_PROVIDER_NOT_UNIQUE, realm.getName()).createErrorPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Flows.forms(session, realm, null, uriInfo, headers).setError(Messages.REALM_SUPPORTS_NO_CREDENTIALS, realm.getName()).createErrorPage();
|
return session.getProvider(LoginFormsProvider.class).setError(Messages.REALM_SUPPORTS_NO_CREDENTIALS, realm.getName()).createErrorPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers)
|
LoginFormsProvider forms = session.getProvider(LoginFormsProvider.class).setClientSessionCode(accessCode);
|
||||||
.setClientSessionCode(accessCode);
|
|
||||||
|
|
||||||
// Attach state from SPNEGO authentication
|
// Attach state from SPNEGO authentication
|
||||||
if (httpAuthOutput.getChallenge() != null) {
|
if (httpAuthOutput.getChallenge() != null) {
|
||||||
|
@ -307,7 +307,7 @@ public class AuthorizationEndpoint {
|
||||||
private Response buildRegister() {
|
private Response buildRegister() {
|
||||||
authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
|
authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
|
||||||
|
|
||||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(new ClientSessionCode(realm, clientSession).getCode())
|
.setClientSessionCode(new ClientSessionCode(realm, clientSession).getCode())
|
||||||
.createRegistration();
|
.createRegistration();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import org.keycloak.services.ErrorResponseException;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.Cors;
|
import org.keycloak.services.resources.Cors;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorPage;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
@ -92,7 +92,7 @@ public class LogoutEndpoint {
|
||||||
event.event(EventType.LOGOUT);
|
event.event(EventType.LOGOUT);
|
||||||
event.detail(Details.REDIRECT_URI, redirect);
|
event.detail(Details.REDIRECT_URI, redirect);
|
||||||
event.error(Errors.INVALID_REDIRECT_URI);
|
event.error(Errors.INVALID_REDIRECT_URI);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_REDIRECT_URI);
|
return ErrorPage.error(session, Messages.INVALID_REDIRECT_URI);
|
||||||
}
|
}
|
||||||
redirect = validatedUri;
|
redirect = validatedUri;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ public class LogoutEndpoint {
|
||||||
if (error) {
|
if (error) {
|
||||||
event.event(EventType.LOGOUT);
|
event.event(EventType.LOGOUT);
|
||||||
event.error(Errors.INVALID_TOKEN);
|
event.error(Errors.INVALID_TOKEN);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.SESSION_NOT_ACTIVE);
|
return ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.keycloak.services.ErrorResponseException;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.ClientSessionCode;
|
import org.keycloak.services.managers.ClientSessionCode;
|
||||||
import org.keycloak.services.resources.Cors;
|
import org.keycloak.services.resources.Cors;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.OPTIONS;
|
import javax.ws.rs.OPTIONS;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
|
|
|
@ -36,7 +36,7 @@ import org.keycloak.representations.AccessToken;
|
||||||
import org.keycloak.services.ErrorResponseException;
|
import org.keycloak.services.ErrorResponseException;
|
||||||
import org.keycloak.services.managers.AppAuthManager;
|
import org.keycloak.services.managers.AppAuthManager;
|
||||||
import org.keycloak.services.resources.Cors;
|
import org.keycloak.services.resources.Cors;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
|
|
|
@ -15,10 +15,9 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.protocol.oidc.TokenManager;
|
import org.keycloak.protocol.oidc.TokenManager;
|
||||||
import org.keycloak.representations.AccessToken;
|
import org.keycloak.representations.AccessToken;
|
||||||
import org.keycloak.services.ErrorResponseException;
|
import org.keycloak.services.ErrorResponseException;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.*;
|
import javax.ws.rs.core.*;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import org.jboss.logging.Logger;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package org.keycloak.services;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.KeycloakContext;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
public class DefaultKeycloakContext implements KeycloakContext {
|
||||||
|
|
||||||
|
private RealmModel realm;
|
||||||
|
|
||||||
|
private ClientModel client;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UriInfo getUri() {
|
||||||
|
return ResteasyProviderFactory.getContextData(UriInfo.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpHeaders getRequestHeaders() {
|
||||||
|
return ResteasyProviderFactory.getContextData(HttpHeaders.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel getRealm() {
|
||||||
|
return realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRealm(RealmModel realm) {
|
||||||
|
this.realm = realm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientModel getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClient(ClientModel client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
package org.keycloak.services;
|
package org.keycloak.services;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.spi.HttpRequest;
|
||||||
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
|
import org.keycloak.models.KeycloakContext;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.models.KeycloakTransactionManager;
|
import org.keycloak.models.KeycloakTransactionManager;
|
||||||
|
@ -12,6 +15,7 @@ import org.keycloak.models.cache.CacheUserProvider;
|
||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -32,11 +36,18 @@ public class DefaultKeycloakSession implements KeycloakSession {
|
||||||
private UserProvider userModel;
|
private UserProvider userModel;
|
||||||
private UserSessionProvider sessionProvider;
|
private UserSessionProvider sessionProvider;
|
||||||
private UserFederationManager federationManager;
|
private UserFederationManager federationManager;
|
||||||
|
private KeycloakContext context;
|
||||||
|
|
||||||
public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) {
|
public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) {
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
this.transactionManager = new DefaultKeycloakTransactionManager();
|
this.transactionManager = new DefaultKeycloakTransactionManager();
|
||||||
federationManager = new UserFederationManager(this);
|
federationManager = new UserFederationManager(this);
|
||||||
|
context = new DefaultKeycloakContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeycloakContext getContext() {
|
||||||
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RealmProvider getRealmProvider() {
|
private RealmProvider getRealmProvider() {
|
||||||
|
|
|
@ -19,35 +19,20 @@
|
||||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
*/
|
*/
|
||||||
package org.keycloak.services.resources.flows;
|
package org.keycloak.services;
|
||||||
|
|
||||||
import org.keycloak.login.LoginFormsProvider;
|
import org.keycloak.login.LoginFormsProvider;
|
||||||
import org.keycloak.models.ClientModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public class Flows {
|
public class ErrorPage {
|
||||||
|
|
||||||
private Flows() {
|
public static Response error(KeycloakSession session, String message, Object... parameters) {
|
||||||
}
|
return session.getProvider(LoginFormsProvider.class).setError(message, parameters).createErrorPage();
|
||||||
|
|
||||||
public static LoginFormsProvider forms(KeycloakSession session, RealmModel realm, ClientModel client, UriInfo uriInfo, HttpHeaders headers) {
|
|
||||||
return session.getProvider(LoginFormsProvider.class).setRealm(realm).setUriInfo(uriInfo).setClient(client).setHttpHeaders(headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ErrorFlows errors() {
|
|
||||||
return new ErrorFlows();
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
package org.keycloak.services;
|
package org.keycloak.services;
|
||||||
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
|
||||||
|
|
||||||
import javax.ws.rs.WebApplicationException;
|
import javax.ws.rs.WebApplicationException;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -15,24 +11,18 @@ import javax.ws.rs.core.UriInfo;
|
||||||
public class ErrorPageException extends WebApplicationException {
|
public class ErrorPageException extends WebApplicationException {
|
||||||
|
|
||||||
private final KeycloakSession session;
|
private final KeycloakSession session;
|
||||||
private final RealmModel realm;
|
|
||||||
private final UriInfo uriInfo;
|
|
||||||
private final HttpHeaders httpHeaders;
|
|
||||||
private final String errorMessage;
|
private final String errorMessage;
|
||||||
private final Object[] parameters;
|
private final Object[] parameters;
|
||||||
|
|
||||||
public ErrorPageException(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers, String errorMessage, Object ... parameters) {
|
public ErrorPageException(KeycloakSession session, String errorMessage, Object... parameters) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.realm = realm;
|
|
||||||
this.uriInfo = uriInfo;
|
|
||||||
this.httpHeaders = headers;
|
|
||||||
this.errorMessage = errorMessage;
|
this.errorMessage = errorMessage;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response getResponse() {
|
public Response getResponse() {
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, httpHeaders, errorMessage, parameters);
|
return ErrorPage.error(session, errorMessage, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.keycloak.services.resources.flows;
|
package org.keycloak.services;
|
||||||
|
|
||||||
import org.keycloak.representations.idm.ErrorRepresentation;
|
import org.keycloak.representations.idm.ErrorRepresentation;
|
||||||
|
|
||||||
|
@ -8,20 +8,18 @@ import javax.ws.rs.core.Response;
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public class ErrorFlows {
|
public class ErrorResponse {
|
||||||
|
|
||||||
public Response exists(String message) {
|
public static Response exists(String message) {
|
||||||
ErrorRepresentation error = new ErrorRepresentation();
|
ErrorRepresentation error = new ErrorRepresentation();
|
||||||
error.setErrorMessage(message);
|
error.setErrorMessage(message);
|
||||||
return Response.status(Response.Status.CONFLICT).entity(error).type(MediaType.APPLICATION_JSON).build();
|
return Response.status(Response.Status.CONFLICT).entity(error).type(MediaType.APPLICATION_JSON).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response error(String message, Response.Status status) {
|
public static Response error(String message, Response.Status status) {
|
||||||
ErrorRepresentation error = new ErrorRepresentation();
|
ErrorRepresentation error = new ErrorRepresentation();
|
||||||
error.setErrorMessage(message);
|
error.setErrorMessage(message);
|
||||||
return Response.status(status).entity(error).type(MediaType.APPLICATION_JSON).build();
|
return Response.status(status).entity(error).type(MediaType.APPLICATION_JSON).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,14 +1,10 @@
|
||||||
package org.keycloak.services;
|
package org.keycloak.services;
|
||||||
|
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
|
||||||
|
|
||||||
import javax.ws.rs.WebApplicationException;
|
import javax.ws.rs.WebApplicationException;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||||
*/
|
*/
|
||||||
package org.keycloak.services.resources.flows;
|
package org.keycloak.services;
|
||||||
|
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.Version;
|
import org.keycloak.Version;
|
|
@ -30,8 +30,7 @@ import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.services.resources.IdentityBrokerService;
|
import org.keycloak.services.resources.IdentityBrokerService;
|
||||||
import org.keycloak.services.resources.LoginActionsService;
|
import org.keycloak.services.resources.LoginActionsService;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
|
||||||
import org.keycloak.services.util.CookieHelper;
|
import org.keycloak.services.util.CookieHelper;
|
||||||
import org.keycloak.services.validation.Validation;
|
import org.keycloak.services.validation.Validation;
|
||||||
import org.keycloak.util.Time;
|
import org.keycloak.util.Time;
|
||||||
|
@ -401,7 +400,7 @@ public class AuthenticationManager {
|
||||||
if (action != null) {
|
if (action != null) {
|
||||||
accessCode.setRequiredAction(action);
|
accessCode.setRequiredAction(action);
|
||||||
|
|
||||||
LoginFormsProvider loginFormsProvider = Flows.forms(session, realm, client, uriInfo, request.getHttpHeaders()).setClientSessionCode(accessCode.getCode())
|
LoginFormsProvider loginFormsProvider = session.getProvider(LoginFormsProvider.class).setClientSessionCode(accessCode.getCode())
|
||||||
.setUser(user);
|
.setUser(user);
|
||||||
if (action.equals(UserModel.RequiredAction.VERIFY_EMAIL)) {
|
if (action.equals(UserModel.RequiredAction.VERIFY_EMAIL)) {
|
||||||
event.clone().event(EventType.SEND_VERIFY_EMAIL).detail(Details.EMAIL, user.getEmail()).success();
|
event.clone().event(EventType.SEND_VERIFY_EMAIL).detail(Details.EMAIL, user.getEmail()).success();
|
||||||
|
@ -425,10 +424,9 @@ public class AuthenticationManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Flows.forms(session, realm, client, uriInfo, request.getHttpHeaders())
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(accessCode.getCode())
|
.setClientSessionCode(accessCode.getCode())
|
||||||
.setAccessRequest(realmRoles, resourceRoles)
|
.setAccessRequest(realmRoles, resourceRoles)
|
||||||
.setClient(client)
|
|
||||||
.createOAuthGrant(clientSession);
|
.createOAuthGrant(clientSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.keycloak.constants.KerberosConstants;
|
||||||
import org.keycloak.protocol.oidc.TokenManager;
|
import org.keycloak.protocol.oidc.TokenManager;
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorPage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle HTTP authentication types requiring complex handshakes with multiple HTTP request/responses
|
* Handle HTTP authentication types requiring complex handshakes with multiple HTTP request/responses
|
||||||
|
@ -114,7 +114,7 @@ public class HttpAuthenticationManager {
|
||||||
Response response;
|
Response response;
|
||||||
if (!user.isEnabled()) {
|
if (!user.isEnabled()) {
|
||||||
event.error(Errors.USER_DISABLED);
|
event.error(Errors.USER_DISABLED);
|
||||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.ACCOUNT_DISABLED);
|
response = ErrorPage.error(session, Messages.ACCOUNT_DISABLED);
|
||||||
} else {
|
} else {
|
||||||
UserSessionModel userSession = session.sessions().createUserSession(realm, user, user.getUsername(), clientConnection.getRemoteAddr(), authMethod, false, null, null);
|
UserSessionModel userSession = session.sessions().createUserSession(realm, user, user.getUsername(), clientConnection.getRemoteAddr(), authMethod, false, null, null);
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,8 @@ public class RealmManager {
|
||||||
realm.setMaxDeltaTimeSeconds(60 * 60 * 12); // 12 hours
|
realm.setMaxDeltaTimeSeconds(60 * 60 * 12); // 12 hours
|
||||||
realm.setFailureFactor(30);
|
realm.setFailureFactor(30);
|
||||||
realm.setSslRequired(SslRequired.EXTERNAL);
|
realm.setSslRequired(SslRequired.EXTERNAL);
|
||||||
|
|
||||||
|
realm.setEventsListeners(Collections.singleton("jboss-logging"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeRealm(RealmModel realm) {
|
public boolean removeRealm(RealmModel realm) {
|
||||||
|
|
|
@ -24,7 +24,9 @@ package org.keycloak.services.resources;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.spi.BadRequestException;
|
import org.jboss.resteasy.spi.BadRequestException;
|
||||||
import org.jboss.resteasy.spi.HttpRequest;
|
import org.jboss.resteasy.spi.HttpRequest;
|
||||||
|
import org.keycloak.AbstractOAuthClient;
|
||||||
import org.keycloak.ClientConnection;
|
import org.keycloak.ClientConnection;
|
||||||
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.account.AccountPages;
|
import org.keycloak.account.AccountPages;
|
||||||
import org.keycloak.account.AccountProvider;
|
import org.keycloak.account.AccountProvider;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
|
@ -32,6 +34,7 @@ import org.keycloak.events.Event;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.events.EventStoreProvider;
|
import org.keycloak.events.EventStoreProvider;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
|
import org.keycloak.login.LoginFormsProvider;
|
||||||
import org.keycloak.models.*;
|
import org.keycloak.models.*;
|
||||||
import org.keycloak.models.utils.FormMessage;
|
import org.keycloak.models.utils.FormMessage;
|
||||||
import org.keycloak.models.utils.ModelToRepresentation;
|
import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
|
@ -47,9 +50,7 @@ import org.keycloak.services.managers.Auth;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.ClientSessionCode;
|
import org.keycloak.services.managers.ClientSessionCode;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.services.resources.flows.OAuthRedirect;
|
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
|
||||||
import org.keycloak.services.util.CookieHelper;
|
import org.keycloak.services.util.CookieHelper;
|
||||||
import org.keycloak.services.util.ResolveRelative;
|
import org.keycloak.services.util.ResolveRelative;
|
||||||
import org.keycloak.services.validation.Validation;
|
import org.keycloak.services.validation.Validation;
|
||||||
|
@ -66,6 +67,7 @@ import javax.ws.rs.core.Cookie;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
|
import javax.ws.rs.core.NewCookie;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
@ -230,7 +232,7 @@ public class AccountService {
|
||||||
try {
|
try {
|
||||||
require(AccountRoles.MANAGE_ACCOUNT);
|
require(AccountRoles.MANAGE_ACCOUNT);
|
||||||
} catch (ForbiddenException e) {
|
} catch (ForbiddenException e) {
|
||||||
return Flows.forms(session, realm, null, uriInfo, headers).setError(Messages.NO_ACCESS).createErrorPage();
|
return session.getProvider(LoginFormsProvider.class).setError(Messages.NO_ACCESS).createErrorPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
setReferrerOnPage();
|
setReferrerOnPage();
|
||||||
|
@ -873,4 +875,42 @@ public class AccountService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class OAuthRedirect extends AbstractOAuthClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* closes client
|
||||||
|
*/
|
||||||
|
public void stop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response redirect(UriInfo uriInfo, String redirectUri) {
|
||||||
|
String state = getStateCode();
|
||||||
|
|
||||||
|
UriBuilder uriBuilder = UriBuilder.fromUri(authUrl)
|
||||||
|
.queryParam(OAuth2Constants.CLIENT_ID, clientId)
|
||||||
|
.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri)
|
||||||
|
.queryParam(OAuth2Constants.STATE, state)
|
||||||
|
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE);
|
||||||
|
if (scope != null) {
|
||||||
|
uriBuilder.queryParam(OAuth2Constants.SCOPE, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
URI url = uriBuilder.build();
|
||||||
|
|
||||||
|
// todo httpOnly!
|
||||||
|
NewCookie cookie = new NewCookie(getStateCookieName(), state, getStateCookiePath(uriInfo), null, null, -1, isSecure);
|
||||||
|
logger.debug("NewCookie: " + cookie.toString());
|
||||||
|
logger.debug("Oauth Redirect to: " + url);
|
||||||
|
return Response.status(302)
|
||||||
|
.location(url)
|
||||||
|
.cookie(cookie).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStateCookiePath(UriInfo uriInfo) {
|
||||||
|
if (stateCookiePath != null) return stateCookiePath;
|
||||||
|
return uriInfo.getBaseUri().getRawPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Errors;
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
|
import org.keycloak.login.LoginFormsProvider;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.ClientSessionModel;
|
import org.keycloak.models.ClientSessionModel;
|
||||||
import org.keycloak.models.FederatedIdentityModel;
|
import org.keycloak.models.FederatedIdentityModel;
|
||||||
|
@ -45,8 +46,9 @@ import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.AuthenticationManager.AuthResult;
|
import org.keycloak.services.managers.AuthenticationManager.AuthResult;
|
||||||
import org.keycloak.services.managers.ClientSessionCode;
|
import org.keycloak.services.managers.ClientSessionCode;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorResponse;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.ErrorPage;
|
||||||
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.services.validation.Validation;
|
import org.keycloak.services.validation.Validation;
|
||||||
import org.keycloak.social.SocialIdentityProvider;
|
import org.keycloak.social.SocialIdentityProvider;
|
||||||
import org.keycloak.util.ObjectUtil;
|
import org.keycloak.util.ObjectUtil;
|
||||||
|
@ -185,15 +187,16 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
return badRequest("Invalid client.");
|
return badRequest("Invalid client.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.getContext().setClient(clientModel);
|
||||||
|
|
||||||
if (!clientModel.isAllowedRetrieveTokenFromIdentityProvider(providerId)) {
|
if (!clientModel.isAllowedRetrieveTokenFromIdentityProvider(providerId)) {
|
||||||
return corsResponse(badRequest("Client [" + audience + "] not authorized to retrieve tokens from identity provider [" + providerId + "]."), clientModel);
|
return corsResponse(badRequest("Client [" + audience + "] not authorized to retrieve tokens from identity provider [" + providerId + "]."), clientModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientModel.isConsentRequired()) {
|
if (clientModel.isConsentRequired()) {
|
||||||
return corsResponse(Flows.forms(this.session, this.realmModel, clientModel, this.uriInfo, headers)
|
return corsResponse(session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(authManager.extractAuthorizationHeaderToken(this.request.getHttpHeaders()))
|
.setClientSessionCode(authManager.extractAuthorizationHeaderToken(this.request.getHttpHeaders()))
|
||||||
.setAccessRequest("Your information from " + providerId + " identity provider.")
|
.setAccessRequest("Your information from " + providerId + " identity provider.")
|
||||||
.setClient(clientModel)
|
|
||||||
.setActionUri(this.uriInfo.getRequestUri())
|
.setActionUri(this.uriInfo.getRequestUri())
|
||||||
.createOAuthGrant(null), clientModel);
|
.createOAuthGrant(null), clientModel);
|
||||||
}
|
}
|
||||||
|
@ -411,7 +414,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
}
|
}
|
||||||
|
|
||||||
fireErrorEvent(message, throwable);
|
fireErrorEvent(message, throwable);
|
||||||
return Flows.forwardToSecurityFailurePage(this.session, this.realmModel, this.uriInfo, headers, message, parameters);
|
return ErrorPage.error(this.session, message, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response redirectToLoginPage(Throwable t, ClientSessionCode clientCode) {
|
private Response redirectToLoginPage(Throwable t, ClientSessionCode clientCode) {
|
||||||
|
@ -422,7 +425,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
}
|
}
|
||||||
|
|
||||||
fireErrorEvent(message);
|
fireErrorEvent(message);
|
||||||
return Flows.forms(this.session, this.realmModel, clientCode.getClientSession().getClient(), this.uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
.setError(message)
|
.setError(message)
|
||||||
.createLogin();
|
.createLogin();
|
||||||
|
@ -430,7 +433,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
|
|
||||||
private Response badRequest(String message) {
|
private Response badRequest(String message) {
|
||||||
fireErrorEvent(message);
|
fireErrorEvent(message);
|
||||||
return Flows.errors().error(message, Status.BAD_REQUEST);
|
return ErrorResponse.error(message, Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IdentityProvider getIdentityProvider(KeycloakSession session, RealmModel realm, String alias) {
|
public static IdentityProvider getIdentityProvider(KeycloakSession session, RealmModel realm, String alias) {
|
||||||
|
|
|
@ -53,8 +53,8 @@ import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.ClientSessionCode;
|
import org.keycloak.services.managers.ClientSessionCode;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorPage;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.services.util.CookieHelper;
|
import org.keycloak.services.util.CookieHelper;
|
||||||
import org.keycloak.services.validation.Validation;
|
import org.keycloak.services.validation.Validation;
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ public class LoginActionsService {
|
||||||
return false;
|
return false;
|
||||||
} else if (!clientCode.isValid(requiredAction)) {
|
} else if (!clientCode.isValid(requiredAction)) {
|
||||||
event.error(Errors.INVALID_CODE);
|
event.error(Errors.INVALID_CODE);
|
||||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_CODE);
|
response = ErrorPage.error(session, Messages.INVALID_CODE);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
@ -174,7 +174,7 @@ public class LoginActionsService {
|
||||||
return false;
|
return false;
|
||||||
} else if (!(clientCode.isValid(requiredAction) || clientCode.isValid(alternativeRequiredAction))) {
|
} else if (!(clientCode.isValid(requiredAction) || clientCode.isValid(alternativeRequiredAction))) {
|
||||||
event.error(Errors.INVALID_CODE);
|
event.error(Errors.INVALID_CODE);
|
||||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo,headers, Messages.INVALID_CODE);
|
response = ErrorPage.error(session, Messages.INVALID_CODE);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
@ -184,20 +184,21 @@ public class LoginActionsService {
|
||||||
public boolean check(String code) {
|
public boolean check(String code) {
|
||||||
if (!checkSsl()) {
|
if (!checkSsl()) {
|
||||||
event.error(Errors.SSL_REQUIRED);
|
event.error(Errors.SSL_REQUIRED);
|
||||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
response = ErrorPage.error(session, Messages.HTTPS_REQUIRED);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!realm.isEnabled()) {
|
if (!realm.isEnabled()) {
|
||||||
event.error(Errors.REALM_DISABLED);
|
event.error(Errors.REALM_DISABLED);
|
||||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
response = ErrorPage.error(session, Messages.REALM_NOT_ENABLED);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
clientCode = ClientSessionCode.parse(code, session, realm);
|
clientCode = ClientSessionCode.parse(code, session, realm);
|
||||||
if (clientCode == null) {
|
if (clientCode == null) {
|
||||||
event.error(Errors.INVALID_CODE);
|
event.error(Errors.INVALID_CODE);
|
||||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_CODE);
|
response = ErrorPage.error(session, Messages.UNKNOWN_CODE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
session.getContext().setClient(clientCode.getClientSession().getClient());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,10 +227,9 @@ public class LoginActionsService {
|
||||||
clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE);
|
clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(clientSessionCode.getCode());
|
.setClientSessionCode(clientSessionCode.getCode())
|
||||||
|
.createLogin();
|
||||||
return forms.createLogin();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -244,7 +244,7 @@ public class LoginActionsService {
|
||||||
event.event(EventType.REGISTER);
|
event.event(EventType.REGISTER);
|
||||||
if (!realm.isRegistrationAllowed()) {
|
if (!realm.isRegistrationAllowed()) {
|
||||||
event.error(Errors.REGISTRATION_DISABLED);
|
event.error(Errors.REGISTRATION_DISABLED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REGISTRATION_NOT_ALLOWED);
|
return ErrorPage.error(session, Messages.REGISTRATION_NOT_ALLOWED);
|
||||||
}
|
}
|
||||||
|
|
||||||
Checks checks = new Checks();
|
Checks checks = new Checks();
|
||||||
|
@ -258,7 +258,7 @@ public class LoginActionsService {
|
||||||
|
|
||||||
authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
|
authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
|
||||||
|
|
||||||
return Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(clientSessionCode.getCode())
|
.setClientSessionCode(clientSessionCode.getCode())
|
||||||
.createRegistration();
|
.createRegistration();
|
||||||
}
|
}
|
||||||
|
@ -278,17 +278,17 @@ public class LoginActionsService {
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
if (!checkSsl()) {
|
if (!checkSsl()) {
|
||||||
event.error(Errors.SSL_REQUIRED);
|
event.error(Errors.SSL_REQUIRED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
return ErrorPage.error(session, Messages.HTTPS_REQUIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!realm.isEnabled()) {
|
if (!realm.isEnabled()) {
|
||||||
event.error(Errors.REALM_DISABLED);
|
event.error(Errors.REALM_DISABLED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
return ErrorPage.error(session, Messages.REALM_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
|
ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
|
||||||
if (clientCode == null) {
|
if (clientCode == null) {
|
||||||
event.error(Errors.INVALID_CODE);
|
event.error(Errors.INVALID_CODE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_CODE);
|
return ErrorPage.error(session, Messages.UNKNOWN_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientSessionModel clientSession = clientCode.getClientSession();
|
ClientSessionModel clientSession = clientCode.getClientSession();
|
||||||
|
@ -297,7 +297,8 @@ public class LoginActionsService {
|
||||||
if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE) || clientSession.getUserSession() != null) {
|
if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE) || clientSession.getUserSession() != null) {
|
||||||
clientCode.setAction(ClientSessionModel.Action.AUTHENTICATE);
|
clientCode.setAction(ClientSessionModel.Action.AUTHENTICATE);
|
||||||
event.client(clientSession.getClient()).error(Errors.EXPIRED_CODE);
|
event.client(clientSession.getClient()).error(Errors.EXPIRED_CODE);
|
||||||
return Flows.forms(this.session, realm, clientSession.getClient(), uriInfo, headers).setError(Messages.EXPIRED_CODE)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
|
.setError(Messages.EXPIRED_CODE)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
.createLogin();
|
.createLogin();
|
||||||
}
|
}
|
||||||
|
@ -320,13 +321,15 @@ public class LoginActionsService {
|
||||||
ClientModel client = clientSession.getClient();
|
ClientModel client = clientSession.getClient();
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
event.error(Errors.CLIENT_NOT_FOUND);
|
event.error(Errors.CLIENT_NOT_FOUND);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_LOGIN_REQUESTER);
|
return ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER);
|
||||||
}
|
}
|
||||||
if (!client.isEnabled()) {
|
if (!client.isEnabled()) {
|
||||||
event.error(Errors.CLIENT_NOT_FOUND);
|
event.error(Errors.CLIENT_NOT_FOUND);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.LOGIN_REQUESTER_NOT_ENABLED);
|
return ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.getContext().setClient(clientSession.getClient());
|
||||||
|
|
||||||
if (formData.containsKey("cancel")) {
|
if (formData.containsKey("cancel")) {
|
||||||
event.error(Errors.REJECTED_BY_USER);
|
event.error(Errors.REJECTED_BY_USER);
|
||||||
LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
|
LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
|
||||||
|
@ -358,14 +361,14 @@ public class LoginActionsService {
|
||||||
return authManager.nextActionAfterAuthentication(session, userSession, clientSession, clientConnection, request, uriInfo, event);
|
return authManager.nextActionAfterAuthentication(session, userSession, clientSession, clientConnection, request, uriInfo, event);
|
||||||
case ACCOUNT_TEMPORARILY_DISABLED:
|
case ACCOUNT_TEMPORARILY_DISABLED:
|
||||||
event.error(Errors.USER_TEMPORARILY_DISABLED);
|
event.error(Errors.USER_TEMPORARILY_DISABLED);
|
||||||
return Flows.forms(this.session, realm, client, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setError(Messages.ACCOUNT_TEMPORARILY_DISABLED)
|
.setError(Messages.ACCOUNT_TEMPORARILY_DISABLED)
|
||||||
.setFormData(formData)
|
.setFormData(formData)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
.createLogin();
|
.createLogin();
|
||||||
case ACCOUNT_DISABLED:
|
case ACCOUNT_DISABLED:
|
||||||
event.error(Errors.USER_DISABLED);
|
event.error(Errors.USER_DISABLED);
|
||||||
return Flows.forms(this.session, realm, client, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setError(Messages.ACCOUNT_DISABLED)
|
.setError(Messages.ACCOUNT_DISABLED)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
.setFormData(formData).createLogin();
|
.setFormData(formData).createLogin();
|
||||||
|
@ -375,19 +378,21 @@ public class LoginActionsService {
|
||||||
String passwordToken = new JWSBuilder().jsonContent(new PasswordToken(realm.getName(), user.getId())).rsa256(realm.getPrivateKey());
|
String passwordToken = new JWSBuilder().jsonContent(new PasswordToken(realm.getName(), user.getId())).rsa256(realm.getPrivateKey());
|
||||||
formData.add(CredentialRepresentation.PASSWORD_TOKEN, passwordToken);
|
formData.add(CredentialRepresentation.PASSWORD_TOKEN, passwordToken);
|
||||||
|
|
||||||
return Flows.forms(this.session, realm, client, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setFormData(formData)
|
.setFormData(formData)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
.createLoginTotp();
|
.createLoginTotp();
|
||||||
case INVALID_USER:
|
case INVALID_USER:
|
||||||
event.error(Errors.USER_NOT_FOUND);
|
event.error(Errors.USER_NOT_FOUND);
|
||||||
return Flows.forms(this.session, realm, client, uriInfo, headers).setError(Messages.INVALID_USER)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
|
.setError(Messages.INVALID_USER)
|
||||||
.setFormData(formData)
|
.setFormData(formData)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
.createLogin();
|
.createLogin();
|
||||||
default:
|
default:
|
||||||
event.error(Errors.INVALID_USER_CREDENTIALS);
|
event.error(Errors.INVALID_USER_CREDENTIALS);
|
||||||
return Flows.forms(this.session, realm, client, uriInfo, headers).setError(Messages.INVALID_USER)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
|
.setError(Messages.INVALID_USER)
|
||||||
.setFormData(formData)
|
.setFormData(formData)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
.createLogin();
|
.createLogin();
|
||||||
|
@ -409,25 +414,25 @@ public class LoginActionsService {
|
||||||
event.event(EventType.REGISTER);
|
event.event(EventType.REGISTER);
|
||||||
if (!checkSsl()) {
|
if (!checkSsl()) {
|
||||||
event.error(Errors.SSL_REQUIRED);
|
event.error(Errors.SSL_REQUIRED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
return ErrorPage.error(session, Messages.HTTPS_REQUIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!realm.isEnabled()) {
|
if (!realm.isEnabled()) {
|
||||||
event.error(Errors.REALM_DISABLED);
|
event.error(Errors.REALM_DISABLED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
return ErrorPage.error(session, Messages.REALM_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
if (!realm.isRegistrationAllowed()) {
|
if (!realm.isRegistrationAllowed()) {
|
||||||
event.error(Errors.REGISTRATION_DISABLED);
|
event.error(Errors.REGISTRATION_DISABLED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REGISTRATION_NOT_ALLOWED);
|
return ErrorPage.error(session, Messages.REGISTRATION_NOT_ALLOWED);
|
||||||
}
|
}
|
||||||
ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
|
ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
|
||||||
if (clientCode == null) {
|
if (clientCode == null) {
|
||||||
event.error(Errors.INVALID_CODE);
|
event.error(Errors.INVALID_CODE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_CODE);
|
return ErrorPage.error(session, Messages.UNKNOWN_CODE);
|
||||||
}
|
}
|
||||||
if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE)) {
|
if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE)) {
|
||||||
event.error(Errors.INVALID_CODE);
|
event.error(Errors.INVALID_CODE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_CODE);
|
return ErrorPage.error(session, Messages.INVALID_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
String username = formData.getFirst(Validation.FIELD_USERNAME);
|
String username = formData.getFirst(Validation.FIELD_USERNAME);
|
||||||
|
@ -446,19 +451,20 @@ public class LoginActionsService {
|
||||||
|
|
||||||
if (!realm.isEnabled()) {
|
if (!realm.isEnabled()) {
|
||||||
event.error(Errors.REALM_DISABLED);
|
event.error(Errors.REALM_DISABLED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
return ErrorPage.error(session, Messages.REALM_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
ClientModel client = clientSession.getClient();
|
ClientModel client = clientSession.getClient();
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
event.error(Errors.CLIENT_NOT_FOUND);
|
event.error(Errors.CLIENT_NOT_FOUND);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_LOGIN_REQUESTER);
|
return ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!client.isEnabled()) {
|
if (!client.isEnabled()) {
|
||||||
event.error(Errors.CLIENT_DISABLED);
|
event.error(Errors.CLIENT_DISABLED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.LOGIN_REQUESTER_NOT_ENABLED);
|
return ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.getContext().setClient(client);
|
||||||
|
|
||||||
List<String> requiredCredentialTypes = new LinkedList<String>();
|
List<String> requiredCredentialTypes = new LinkedList<String>();
|
||||||
for (RequiredCredentialModel m : realm.getRequiredCredentials()) {
|
for (RequiredCredentialModel m : realm.getRequiredCredentials()) {
|
||||||
|
@ -470,7 +476,7 @@ public class LoginActionsService {
|
||||||
|
|
||||||
if (errors != null && !errors.isEmpty()) {
|
if (errors != null && !errors.isEmpty()) {
|
||||||
event.error(Errors.INVALID_REGISTRATION);
|
event.error(Errors.INVALID_REGISTRATION);
|
||||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setErrors(errors)
|
.setErrors(errors)
|
||||||
.setFormData(formData)
|
.setFormData(formData)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
|
@ -480,7 +486,7 @@ public class LoginActionsService {
|
||||||
// Validate that user with this username doesn't exist in realm or any federation provider
|
// Validate that user with this username doesn't exist in realm or any federation provider
|
||||||
if (session.users().getUserByUsername(username, realm) != null) {
|
if (session.users().getUserByUsername(username, realm) != null) {
|
||||||
event.error(Errors.USERNAME_IN_USE);
|
event.error(Errors.USERNAME_IN_USE);
|
||||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setError(Messages.USERNAME_EXISTS)
|
.setError(Messages.USERNAME_EXISTS)
|
||||||
.setFormData(formData)
|
.setFormData(formData)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
|
@ -490,7 +496,7 @@ public class LoginActionsService {
|
||||||
// Validate that user with this email doesn't exist in realm or any federation provider
|
// Validate that user with this email doesn't exist in realm or any federation provider
|
||||||
if (email != null && session.users().getUserByEmail(email, realm) != null) {
|
if (email != null && session.users().getUserByEmail(email, realm) != null) {
|
||||||
event.error(Errors.EMAIL_IN_USE);
|
event.error(Errors.EMAIL_IN_USE);
|
||||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setError(Messages.EMAIL_EXISTS)
|
.setError(Messages.EMAIL_EXISTS)
|
||||||
.setFormData(formData)
|
.setFormData(formData)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
|
@ -527,7 +533,7 @@ public class LoginActionsService {
|
||||||
// User already registered, but force him to update password
|
// User already registered, but force him to update password
|
||||||
if (!passwordUpdateSuccessful) {
|
if (!passwordUpdateSuccessful) {
|
||||||
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
|
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
|
||||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setError(passwordUpdateError, passwordUpdateErrorParameters)
|
.setError(passwordUpdateError, passwordUpdateErrorParameters)
|
||||||
.setClientSessionCode(clientCode.getCode())
|
.setClientSessionCode(clientCode.getCode())
|
||||||
.createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
|
.createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
|
||||||
|
@ -556,7 +562,7 @@ public class LoginActionsService {
|
||||||
|
|
||||||
|
|
||||||
if (!checkSsl()) {
|
if (!checkSsl()) {
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
return ErrorPage.error(session, Messages.HTTPS_REQUIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
String code = formData.getFirst("code");
|
String code = formData.getFirst("code");
|
||||||
|
@ -564,7 +570,7 @@ public class LoginActionsService {
|
||||||
ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
|
ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
|
||||||
if (accessCode == null || !accessCode.isValid(ClientSessionModel.Action.OAUTH_GRANT)) {
|
if (accessCode == null || !accessCode.isValid(ClientSessionModel.Action.OAUTH_GRANT)) {
|
||||||
event.error(Errors.INVALID_CODE);
|
event.error(Errors.INVALID_CODE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.INVALID_ACCESS_CODE);
|
return ErrorPage.error(session, Messages.INVALID_ACCESS_CODE);
|
||||||
}
|
}
|
||||||
ClientSessionModel clientSession = accessCode.getClientSession();
|
ClientSessionModel clientSession = accessCode.getClientSession();
|
||||||
event.detail(Details.CODE_ID, clientSession.getId());
|
event.detail(Details.CODE_ID, clientSession.getId());
|
||||||
|
@ -588,7 +594,7 @@ public class LoginActionsService {
|
||||||
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
|
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
|
||||||
AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||||
event.error(Errors.INVALID_CODE);
|
event.error(Errors.INVALID_CODE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.SESSION_NOT_ACTIVE);
|
return ErrorPage.error(session, Messages.SESSION_NOT_ACTIVE);
|
||||||
}
|
}
|
||||||
event.session(userSession);
|
event.session(userSession);
|
||||||
|
|
||||||
|
@ -625,8 +631,10 @@ public class LoginActionsService {
|
||||||
|
|
||||||
List<FormMessage> errors = Validation.validateUpdateProfileForm(formData);
|
List<FormMessage> errors = Validation.validateUpdateProfileForm(formData);
|
||||||
if (errors != null && !errors.isEmpty()) {
|
if (errors != null && !errors.isEmpty()) {
|
||||||
return Flows.forms(session, realm, null, uriInfo, headers).setUser(user).setErrors(errors)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(accessCode.getCode())
|
.setClientSessionCode(accessCode.getCode())
|
||||||
|
.setUser(user)
|
||||||
|
.setErrors(errors)
|
||||||
.createResponse(RequiredAction.UPDATE_PROFILE);
|
.createResponse(RequiredAction.UPDATE_PROFILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,7 +651,9 @@ public class LoginActionsService {
|
||||||
|
|
||||||
// check for duplicated email
|
// check for duplicated email
|
||||||
if (userByEmail != null && !userByEmail.getId().equals(user.getId())) {
|
if (userByEmail != null && !userByEmail.getId().equals(user.getId())) {
|
||||||
return Flows.forms(session, realm, null, uriInfo, headers).setUser(user).setError(Messages.EMAIL_EXISTS)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
|
.setUser(user)
|
||||||
|
.setError(Messages.EMAIL_EXISTS)
|
||||||
.setClientSessionCode(accessCode.getCode())
|
.setClientSessionCode(accessCode.getCode())
|
||||||
.createResponse(RequiredAction.UPDATE_PROFILE);
|
.createResponse(RequiredAction.UPDATE_PROFILE);
|
||||||
}
|
}
|
||||||
|
@ -682,7 +692,7 @@ public class LoginActionsService {
|
||||||
String totp = formData.getFirst("totp");
|
String totp = formData.getFirst("totp");
|
||||||
String totpSecret = formData.getFirst("totpSecret");
|
String totpSecret = formData.getFirst("totpSecret");
|
||||||
|
|
||||||
LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo, headers).setUser(user);
|
LoginFormsProvider loginForms = session.getProvider(LoginFormsProvider.class).setUser(user);
|
||||||
if (Validation.isEmpty(totp)) {
|
if (Validation.isEmpty(totp)) {
|
||||||
return loginForms.setError(Messages.MISSING_TOTP)
|
return loginForms.setError(Messages.MISSING_TOTP)
|
||||||
.setClientSessionCode(accessCode.getCode())
|
.setClientSessionCode(accessCode.getCode())
|
||||||
|
@ -727,7 +737,8 @@ public class LoginActionsService {
|
||||||
String passwordNew = formData.getFirst("password-new");
|
String passwordNew = formData.getFirst("password-new");
|
||||||
String passwordConfirm = formData.getFirst("password-confirm");
|
String passwordConfirm = formData.getFirst("password-confirm");
|
||||||
|
|
||||||
LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo, headers).setUser(user);
|
LoginFormsProvider loginForms = session.getProvider(LoginFormsProvider.class)
|
||||||
|
.setUser(user);
|
||||||
if (Validation.isEmpty(passwordNew)) {
|
if (Validation.isEmpty(passwordNew)) {
|
||||||
return loginForms.setError(Messages.MISSING_PASSWORD)
|
return loginForms.setError(Messages.MISSING_PASSWORD)
|
||||||
.setClientSessionCode(accessCode.getCode())
|
.setClientSessionCode(accessCode.getCode())
|
||||||
|
@ -757,7 +768,9 @@ public class LoginActionsService {
|
||||||
if (clientSession.getAction().equals(ClientSessionModel.Action.RECOVER_PASSWORD)) {
|
if (clientSession.getAction().equals(ClientSessionModel.Action.RECOVER_PASSWORD)) {
|
||||||
String actionCookieValue = getActionCookie();
|
String actionCookieValue = getActionCookie();
|
||||||
if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) {
|
if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) {
|
||||||
return Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers).setSuccess(Messages.ACCOUNT_PASSWORD_UPDATED).createInfoPage();
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
|
.setSuccess(Messages.ACCOUNT_PASSWORD_UPDATED)
|
||||||
|
.createInfoPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,7 +802,9 @@ public class LoginActionsService {
|
||||||
|
|
||||||
String actionCookieValue = getActionCookie();
|
String actionCookieValue = getActionCookie();
|
||||||
if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) {
|
if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) {
|
||||||
return Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers).setSuccess(Messages.EMAIL_VERIFIED).createInfoPage();
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
|
.setSuccess(Messages.EMAIL_VERIFIED)
|
||||||
|
.createInfoPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
event = event.clone().removeDetail(Details.EMAIL).event(EventType.LOGIN);
|
event = event.clone().removeDetail(Details.EMAIL).event(EventType.LOGIN);
|
||||||
|
@ -807,7 +822,7 @@ public class LoginActionsService {
|
||||||
|
|
||||||
createActionCookie(realm, uriInfo, clientConnection, userSession.getId());
|
createActionCookie(realm, uriInfo, clientConnection, userSession.getId());
|
||||||
|
|
||||||
return Flows.forms(session, realm, null, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(accessCode.getCode())
|
.setClientSessionCode(accessCode.getCode())
|
||||||
.setUser(userSession.getUser())
|
.setUser(userSession.getUser())
|
||||||
.createResponse(RequiredAction.VERIFY_EMAIL);
|
.createResponse(RequiredAction.VERIFY_EMAIL);
|
||||||
|
@ -824,11 +839,11 @@ public class LoginActionsService {
|
||||||
return checks.response;
|
return checks.response;
|
||||||
}
|
}
|
||||||
ClientSessionCode accessCode = checks.clientCode;
|
ClientSessionCode accessCode = checks.clientCode;
|
||||||
return Flows.forms(session, realm, null, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(accessCode.getCode())
|
.setClientSessionCode(accessCode.getCode())
|
||||||
.createResponse(RequiredAction.UPDATE_PASSWORD);
|
.createResponse(RequiredAction.UPDATE_PASSWORD);
|
||||||
} else {
|
} else {
|
||||||
return Flows.forms(session, realm, null, uriInfo, headers)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
.setClientSessionCode(code)
|
.setClientSessionCode(code)
|
||||||
.createPasswordReset();
|
.createPasswordReset();
|
||||||
}
|
}
|
||||||
|
@ -841,16 +856,16 @@ public class LoginActionsService {
|
||||||
final MultivaluedMap<String, String> formData) {
|
final MultivaluedMap<String, String> formData) {
|
||||||
event.event(EventType.SEND_RESET_PASSWORD);
|
event.event(EventType.SEND_RESET_PASSWORD);
|
||||||
if (!checkSsl()) {
|
if (!checkSsl()) {
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.HTTPS_REQUIRED);
|
return ErrorPage.error(session, Messages.HTTPS_REQUIRED);
|
||||||
}
|
}
|
||||||
if (!realm.isEnabled()) {
|
if (!realm.isEnabled()) {
|
||||||
event.error(Errors.REALM_DISABLED);
|
event.error(Errors.REALM_DISABLED);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.REALM_NOT_ENABLED);
|
return ErrorPage.error(session, Messages.REALM_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
|
ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
|
||||||
if (accessCode == null) {
|
if (accessCode == null) {
|
||||||
event.error(Errors.INVALID_CODE);
|
event.error(Errors.INVALID_CODE);
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_CODE);
|
return ErrorPage.error(session, Messages.UNKNOWN_CODE);
|
||||||
}
|
}
|
||||||
ClientSessionModel clientSession = accessCode.getClientSession();
|
ClientSessionModel clientSession = accessCode.getClientSession();
|
||||||
|
|
||||||
|
@ -858,12 +873,14 @@ public class LoginActionsService {
|
||||||
|
|
||||||
ClientModel client = clientSession.getClient();
|
ClientModel client = clientSession.getClient();
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNKNOWN_LOGIN_REQUESTER);
|
return ErrorPage.error(session, Messages.UNKNOWN_LOGIN_REQUESTER);
|
||||||
}
|
}
|
||||||
if (!client.isEnabled()) {
|
if (!client.isEnabled()) {
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.LOGIN_REQUESTER_NOT_ENABLED);
|
return ErrorPage.error(session, Messages.LOGIN_REQUESTER_NOT_ENABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.getContext().setClient(client);
|
||||||
|
|
||||||
event.client(client.getClientId())
|
event.client(client.getClientId())
|
||||||
.detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
|
.detail(Details.REDIRECT_URI, clientSession.getRedirectUri())
|
||||||
.detail(Details.RESPONSE_TYPE, "code")
|
.detail(Details.RESPONSE_TYPE, "code")
|
||||||
|
@ -904,7 +921,8 @@ public class LoginActionsService {
|
||||||
} catch (EmailException e) {
|
} catch (EmailException e) {
|
||||||
event.error(Errors.EMAIL_SEND_FAILED);
|
event.error(Errors.EMAIL_SEND_FAILED);
|
||||||
logger.error("Failed to send password reset email", e);
|
logger.error("Failed to send password reset email", e);
|
||||||
return Flows.forms(this.session, realm, client, uriInfo, headers).setError(Messages.EMAIL_SENT_ERROR)
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
|
.setError(Messages.EMAIL_SENT_ERROR)
|
||||||
.setClientSessionCode(accessCode.getCode())
|
.setClientSessionCode(accessCode.getCode())
|
||||||
.createErrorPage();
|
.createErrorPage();
|
||||||
}
|
}
|
||||||
|
@ -912,7 +930,10 @@ public class LoginActionsService {
|
||||||
createActionCookie(realm, uriInfo, clientConnection, userSession.getId());
|
createActionCookie(realm, uriInfo, clientConnection, userSession.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Flows.forms(session, realm, client, uriInfo, headers).setSuccess(Messages.EMAIL_SENT).setClientSessionCode(accessCode.getCode()).createPasswordReset();
|
return session.getProvider(LoginFormsProvider.class)
|
||||||
|
.setSuccess(Messages.EMAIL_SENT)
|
||||||
|
.setClientSessionCode(accessCode.getCode())
|
||||||
|
.createPasswordReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getActionCookie() {
|
private String getActionCookie() {
|
||||||
|
|
|
@ -24,7 +24,6 @@ import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
@ -38,17 +37,6 @@ import javax.ws.rs.core.UriInfo;
|
||||||
public class RealmsResource {
|
public class RealmsResource {
|
||||||
protected static Logger logger = Logger.getLogger(RealmsResource.class);
|
protected static Logger logger = Logger.getLogger(RealmsResource.class);
|
||||||
|
|
||||||
@Context
|
|
||||||
protected UriInfo uriInfo;
|
|
||||||
|
|
||||||
@Context
|
|
||||||
protected HttpHeaders headers;
|
|
||||||
|
|
||||||
/*
|
|
||||||
@Context
|
|
||||||
protected ResourceContext resourceContext;
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Context
|
@Context
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
|
|
||||||
|
@ -62,18 +50,10 @@ public class RealmsResource {
|
||||||
return uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(RealmsResource.class, "getRealmResource");
|
return uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(RealmsResource.class, "getRealmResource");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UriBuilder realmBaseUrl(UriBuilder base) {
|
|
||||||
return base.path(RealmsResource.class).path(RealmsResource.class, "getRealmResource");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UriBuilder accountUrl(UriBuilder base) {
|
public static UriBuilder accountUrl(UriBuilder base) {
|
||||||
return base.path(RealmsResource.class).path(RealmsResource.class, "getAccountService");
|
return base.path(RealmsResource.class).path(RealmsResource.class, "getAccountService");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UriBuilder protocolUrl(UriBuilder base) {
|
|
||||||
return base.path(RealmsResource.class).path(RealmsResource.class, "getProtocol");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UriBuilder protocolUrl(UriInfo uriInfo) {
|
public static UriBuilder protocolUrl(UriInfo uriInfo) {
|
||||||
return uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(RealmsResource.class, "getProtocol");
|
return uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(RealmsResource.class, "getProtocol");
|
||||||
}
|
}
|
||||||
|
@ -87,9 +67,8 @@ public class RealmsResource {
|
||||||
public Object getLoginStatusIframe(final @PathParam("realm") String name,
|
public Object getLoginStatusIframe(final @PathParam("realm") String name,
|
||||||
@QueryParam("client_id") String client_id,
|
@QueryParam("client_id") String client_id,
|
||||||
@QueryParam("origin") String origin) {
|
@QueryParam("origin") String origin) {
|
||||||
// backward compatibility
|
RealmModel realm = init(name);
|
||||||
RealmManager realmManager = new RealmManager(session);
|
|
||||||
RealmModel realm = locateRealm(name, realmManager);
|
|
||||||
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
||||||
AuthenticationManager authManager = new AuthenticationManager(protector);
|
AuthenticationManager authManager = new AuthenticationManager(protector);
|
||||||
|
|
||||||
|
@ -104,8 +83,8 @@ public class RealmsResource {
|
||||||
@Path("{realm}/protocol/{protocol}")
|
@Path("{realm}/protocol/{protocol}")
|
||||||
public Object getProtocol(final @PathParam("realm") String name,
|
public Object getProtocol(final @PathParam("realm") String name,
|
||||||
final @PathParam("protocol") String protocol) {
|
final @PathParam("protocol") String protocol) {
|
||||||
RealmManager realmManager = new RealmManager(session);
|
RealmModel realm = init(name);
|
||||||
RealmModel realm = locateRealm(name, realmManager);
|
|
||||||
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
||||||
AuthenticationManager authManager = new AuthenticationManager(protector);
|
AuthenticationManager authManager = new AuthenticationManager(protector);
|
||||||
|
|
||||||
|
@ -125,8 +104,7 @@ public class RealmsResource {
|
||||||
|
|
||||||
@Path("{realm}/login-actions")
|
@Path("{realm}/login-actions")
|
||||||
public LoginActionsService getLoginActionsService(final @PathParam("realm") String name) {
|
public LoginActionsService getLoginActionsService(final @PathParam("realm") String name) {
|
||||||
RealmManager realmManager = new RealmManager(session);
|
RealmModel realm = init(name);
|
||||||
RealmModel realm = locateRealm(name, realmManager);
|
|
||||||
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
||||||
AuthenticationManager authManager = new AuthenticationManager(protector);
|
AuthenticationManager authManager = new AuthenticationManager(protector);
|
||||||
LoginActionsService service = new LoginActionsService(realm, authManager, event);
|
LoginActionsService service = new LoginActionsService(realm, authManager, event);
|
||||||
|
@ -136,26 +114,26 @@ public class RealmsResource {
|
||||||
|
|
||||||
@Path("{realm}/clients-managements")
|
@Path("{realm}/clients-managements")
|
||||||
public ClientsManagementService getClientsManagementService(final @PathParam("realm") String name) {
|
public ClientsManagementService getClientsManagementService(final @PathParam("realm") String name) {
|
||||||
RealmManager realmManager = new RealmManager(session);
|
RealmModel realm = init(name);
|
||||||
RealmModel realm = locateRealm(name, realmManager);
|
|
||||||
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
||||||
ClientsManagementService service = new ClientsManagementService(realm, event);
|
ClientsManagementService service = new ClientsManagementService(realm, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(service);
|
ResteasyProviderFactory.getInstance().injectProperties(service);
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RealmModel locateRealm(String name, RealmManager realmManager) {
|
private RealmModel init(String realmName) {
|
||||||
RealmModel realm = realmManager.getRealmByName(name);
|
RealmManager realmManager = new RealmManager(session);
|
||||||
|
RealmModel realm = realmManager.getRealmByName(realmName);
|
||||||
if (realm == null) {
|
if (realm == null) {
|
||||||
throw new NotFoundException("Realm does not exist");
|
throw new NotFoundException("Realm does not exist");
|
||||||
}
|
}
|
||||||
|
session.getContext().setRealm(realm);
|
||||||
return realm;
|
return realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Path("{realm}/account")
|
@Path("{realm}/account")
|
||||||
public AccountService getAccountService(final @PathParam("realm") String name) {
|
public AccountService getAccountService(final @PathParam("realm") String name) {
|
||||||
RealmManager realmManager = new RealmManager(session);
|
RealmModel realm = init(name);
|
||||||
RealmModel realm = locateRealm(name, realmManager);
|
|
||||||
|
|
||||||
ClientModel client = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
ClientModel client = realm.getClientNameMap().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
|
||||||
if (client == null || !client.isEnabled()) {
|
if (client == null || !client.isEnabled()) {
|
||||||
|
@ -172,8 +150,7 @@ public class RealmsResource {
|
||||||
|
|
||||||
@Path("{realm}")
|
@Path("{realm}")
|
||||||
public PublicRealmResource getRealmResource(final @PathParam("realm") String name) {
|
public PublicRealmResource getRealmResource(final @PathParam("realm") String name) {
|
||||||
RealmManager realmManager = new RealmManager(session);
|
RealmModel realm = init(name);
|
||||||
RealmModel realm = locateRealm(name, realmManager);
|
|
||||||
PublicRealmResource realmResource = new PublicRealmResource(realm);
|
PublicRealmResource realmResource = new PublicRealmResource(realm);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(realmResource);
|
ResteasyProviderFactory.getInstance().injectProperties(realmResource);
|
||||||
return realmResource;
|
return realmResource;
|
||||||
|
@ -181,8 +158,7 @@ public class RealmsResource {
|
||||||
|
|
||||||
@Path("{realm}/broker")
|
@Path("{realm}/broker")
|
||||||
public IdentityBrokerService getBrokerService(final @PathParam("realm") String name) {
|
public IdentityBrokerService getBrokerService(final @PathParam("realm") String name) {
|
||||||
RealmManager realmManager = new RealmManager(session);
|
RealmModel realm = init(name);
|
||||||
RealmModel realm = locateRealm(name, realmManager);
|
|
||||||
|
|
||||||
IdentityBrokerService brokerService = new IdentityBrokerService(realm);
|
IdentityBrokerService brokerService = new IdentityBrokerService(realm);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(brokerService);
|
ResteasyProviderFactory.getInstance().injectProperties(brokerService);
|
||||||
|
@ -195,12 +171,12 @@ public class RealmsResource {
|
||||||
@GET
|
@GET
|
||||||
@Path("{realm}/.well-known/{provider}")
|
@Path("{realm}/.well-known/{provider}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Response getWellKnown(final @PathParam("realm") String realmName,
|
public Response getWellKnown(final @PathParam("realm") String name,
|
||||||
final @PathParam("provider") String providerName) {
|
final @PathParam("provider") String providerName) {
|
||||||
RealmManager realmManager = new RealmManager(session);
|
init(name);
|
||||||
RealmModel realm = locateRealm(realmName, realmManager);
|
|
||||||
WellKnownProvider wellKnown = session.getProvider(WellKnownProvider.class, providerName);
|
WellKnownProvider wellKnown = session.getProvider(WellKnownProvider.class, providerName);
|
||||||
return Response.ok(wellKnown.getConfig(realm, uriInfo)).build();
|
return Response.ok(wellKnown.getConfig()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.keycloak.services.managers.ClientManager;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.resources.KeycloakApplication;
|
import org.keycloak.services.resources.KeycloakApplication;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
|
@ -23,7 +23,7 @@ import org.keycloak.services.managers.ClientManager;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.managers.ResourceAdminManager;
|
import org.keycloak.services.managers.ResourceAdminManager;
|
||||||
import org.keycloak.services.resources.KeycloakApplication;
|
import org.keycloak.services.resources.KeycloakApplication;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorResponse;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
import org.keycloak.util.Time;
|
import org.keycloak.util.Time;
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public class ClientResource {
|
||||||
RepresentationToModel.updateClient(rep, client);
|
RepresentationToModel.updateClient(rep, client);
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Client " + rep.getClientId() + " already exists");
|
return ErrorResponse.exists("Client " + rep.getClientId() + " already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.utils.ModelToRepresentation;
|
import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
import org.keycloak.models.utils.RepresentationToModel;
|
import org.keycloak.models.utils.RepresentationToModel;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorResponse;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
@ -91,7 +91,7 @@ public class ClientsResource {
|
||||||
ClientModel clientModel = RepresentationToModel.createClient(session, realm, rep, true);
|
ClientModel clientModel = RepresentationToModel.createClient(session, realm, rep, true);
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(getClientPath(clientModel)).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(getClientPath(clientModel)).build()).build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Client " + rep.getClientId() + " already exists");
|
return ErrorResponse.exists("Client " + rep.getClientId() + " already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
import org.keycloak.models.utils.RepresentationToModel;
|
import org.keycloak.models.utils.RepresentationToModel;
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.ProviderFactory;
|
||||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorResponse;
|
||||||
import org.keycloak.social.SocialIdentityProvider;
|
import org.keycloak.social.SocialIdentityProvider;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -96,7 +96,7 @@ public class IdentityProviderResource {
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Identity Provider " + providerRep.getAlias() + " already exists");
|
return ErrorResponse.exists("Identity Provider " + providerRep.getAlias() + " already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ public class IdentityProviderResource {
|
||||||
IdentityProviderFactory factory = getIdentityProviderFactory();
|
IdentityProviderFactory factory = getIdentityProviderFactory();
|
||||||
return factory.create(identityProviderModel).export(uriInfo, realm, format);
|
return factory.create(identityProviderModel).export(uriInfo, realm, format);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return Flows.errors().error("Could not export public broker configuration for identity provider [" + identityProviderModel.getProviderId() + "].", Response.Status.NOT_FOUND);
|
return ErrorResponse.error("Could not export public broker configuration for identity provider [" + identityProviderModel.getProviderId() + "].", Response.Status.NOT_FOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import org.keycloak.models.utils.RepresentationToModel;
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.ProviderFactory;
|
||||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||||
import org.keycloak.services.managers.ResourceAdminManager;
|
import org.keycloak.services.managers.ResourceAdminManager;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorResponse;
|
||||||
import org.keycloak.social.SocialIdentityProvider;
|
import org.keycloak.social.SocialIdentityProvider;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -132,7 +132,7 @@ public class IdentityProvidersResource {
|
||||||
|
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getProviderId()).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getProviderId()).build()).build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Identity Provider " + representation.getAlias() + " already exists");
|
return ErrorResponse.exists("Identity Provider " + representation.getAlias() + " already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ import org.keycloak.services.managers.LDAPConnectionTestManager;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.managers.ResourceAdminManager;
|
import org.keycloak.services.managers.ResourceAdminManager;
|
||||||
import org.keycloak.services.managers.UsersSyncManager;
|
import org.keycloak.services.managers.UsersSyncManager;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorResponse;
|
||||||
import org.keycloak.timer.TimerProvider;
|
import org.keycloak.timer.TimerProvider;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -191,11 +191,11 @@ public class RealmAdminResource {
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (PatternSyntaxException e) {
|
} catch (PatternSyntaxException e) {
|
||||||
return Flows.errors().exists("Specified regex pattern(s) is invalid.");
|
return ErrorResponse.exists("Specified regex pattern(s) is invalid.");
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Realm " + rep.getRealm() + " already exists.");
|
return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return Flows.errors().exists("Failed to update " + rep.getRealm() + " Realm.");
|
return ErrorResponse.exists("Failed to update " + rep.getRealm() + " Realm.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +442,7 @@ public class RealmAdminResource {
|
||||||
auth.init(RealmAuth.Resource.REALM).requireManage();
|
auth.init(RealmAuth.Resource.REALM).requireManage();
|
||||||
|
|
||||||
boolean result = new LDAPConnectionTestManager().testLDAP(action, connectionUrl, bindDn, bindCredential);
|
boolean result = new LDAPConnectionTestManager().testLDAP(action, connectionUrl, bindDn, bindCredential);
|
||||||
return result ? Response.noContent().build() : Flows.errors().error("LDAP test error", Response.Status.BAD_REQUEST);
|
return result ? Response.noContent().build() : ErrorResponse.error("LDAP test error", Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Path("identity-provider")
|
@Path("identity-provider")
|
||||||
|
|
|
@ -18,7 +18,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.services.ForbiddenException;
|
import org.keycloak.services.ForbiddenException;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.resources.KeycloakApplication;
|
import org.keycloak.services.resources.KeycloakApplication;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorResponse;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -131,7 +131,7 @@ public class RealmsAdminResource {
|
||||||
|
|
||||||
return Response.created(location).build();
|
return Response.created(location).build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
|
return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ public class RealmsAdminResource {
|
||||||
try {
|
try {
|
||||||
realm = realmManager.importRealm(rep);
|
realm = realmManager.importRealm(rep);
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
|
return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
grantPermissionsToRealmCreator(realm);
|
grantPermissionsToRealmCreator(realm);
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.keycloak.models.RoleContainerModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.utils.ModelToRepresentation;
|
import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
import org.keycloak.representations.idm.RoleRepresentation;
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorResponse;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
|
@ -79,7 +79,7 @@ public class RoleContainerResource extends RoleResource {
|
||||||
role.setDescription(rep.getDescription());
|
role.setDescription(rep.getDescription());
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Role with name " + rep.getName() + " already exists");
|
return ErrorResponse.exists("Role with name " + rep.getName() + " already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ public class RoleContainerResource extends RoleResource {
|
||||||
updateRole(rep, role);
|
updateRole(rep, role);
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Role with name " + rep.getName() + " already exists");
|
return ErrorResponse.exists("Role with name " + rep.getName() + " already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@ import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.ClientSessionCode;
|
import org.keycloak.services.managers.ClientSessionCode;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.managers.UserManager;
|
import org.keycloak.services.managers.UserManager;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorResponse;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
|
@ -123,9 +123,9 @@ public class UsersResource {
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("User exists with same username or email");
|
return ErrorResponse.exists("User exists with same username or email");
|
||||||
} catch (ModelReadOnlyException re) {
|
} catch (ModelReadOnlyException re) {
|
||||||
return Flows.errors().exists("User is read only!");
|
return ErrorResponse.exists("User is read only!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,10 +143,10 @@ public class UsersResource {
|
||||||
|
|
||||||
// Double-check duplicated username and email here due to federation
|
// Double-check duplicated username and email here due to federation
|
||||||
if (session.users().getUserByUsername(rep.getUsername(), realm) != null) {
|
if (session.users().getUserByUsername(rep.getUsername(), realm) != null) {
|
||||||
return Flows.errors().exists("User exists with same username");
|
return ErrorResponse.exists("User exists with same username");
|
||||||
}
|
}
|
||||||
if (rep.getEmail() != null && session.users().getUserByEmail(rep.getEmail(), realm) != null) {
|
if (rep.getEmail() != null && session.users().getUserByEmail(rep.getEmail(), realm) != null) {
|
||||||
return Flows.errors().exists("User exists with same email");
|
return ErrorResponse.exists("User exists with same email");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -162,7 +162,7 @@ public class UsersResource {
|
||||||
if (session.getTransaction().isActive()) {
|
if (session.getTransaction().isActive()) {
|
||||||
session.getTransaction().setRollbackOnly();
|
session.getTransaction().setRollbackOnly();
|
||||||
}
|
}
|
||||||
return Flows.errors().exists("User exists with same username or email");
|
return ErrorResponse.exists("User exists with same username or email");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ public class UsersResource {
|
||||||
throw new NotFoundException("User not found");
|
throw new NotFoundException("User not found");
|
||||||
}
|
}
|
||||||
if (session.users().getFederatedIdentity(user, provider, realm) != null) {
|
if (session.users().getFederatedIdentity(user, provider, realm) != null) {
|
||||||
return Flows.errors().exists("User is already linked with provider");
|
return ErrorResponse.exists("User is already linked with provider");
|
||||||
}
|
}
|
||||||
|
|
||||||
FederatedIdentityModel socialLink = new FederatedIdentityModel(provider, rep.getUserId(), rep.getUserName());
|
FederatedIdentityModel socialLink = new FederatedIdentityModel(provider, rep.getUserId(), rep.getUserName());
|
||||||
|
@ -352,7 +352,7 @@ public class UsersResource {
|
||||||
if (removed) {
|
if (removed) {
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} else {
|
} else {
|
||||||
return Flows.errors().error("User couldn't be deleted", Response.Status.BAD_REQUEST);
|
return ErrorResponse.error("User couldn't be deleted", Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,19 +702,19 @@ public class UsersResource {
|
||||||
|
|
||||||
UserModel user = session.users().getUserByUsername(username, realm);
|
UserModel user = session.users().getUserByUsername(username, realm);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
return Flows.errors().error("User not found", Response.Status.NOT_FOUND);
|
return ErrorResponse.error("User not found", Response.Status.NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.isEnabled()) {
|
if (!user.isEnabled()) {
|
||||||
return Flows.errors().error("User is disabled", Response.Status.BAD_REQUEST);
|
return ErrorResponse.error("User is disabled", Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.getEmail() == null) {
|
if (user.getEmail() == null) {
|
||||||
return Flows.errors().error("User email missing", Response.Status.BAD_REQUEST);
|
return ErrorResponse.error("User email missing", Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(redirectUri != null && clientId == null){
|
if(redirectUri != null && clientId == null){
|
||||||
return Flows.errors().error("Client id missing", Response.Status.BAD_REQUEST);
|
return ErrorResponse.error("Client id missing", Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(clientId == null){
|
if(clientId == null){
|
||||||
|
@ -723,14 +723,14 @@ public class UsersResource {
|
||||||
|
|
||||||
ClientModel client = realm.getClientByClientId(clientId);
|
ClientModel client = realm.getClientByClientId(clientId);
|
||||||
if (client == null || !client.isEnabled()) {
|
if (client == null || !client.isEnabled()) {
|
||||||
return Flows.errors().error(clientId + " not enabled", Response.Status.INTERNAL_SERVER_ERROR);
|
return ErrorResponse.error(clientId + " not enabled", Response.Status.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
String redirect;
|
String redirect;
|
||||||
if(redirectUri != null){
|
if(redirectUri != null){
|
||||||
redirect = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri, realm, client);
|
redirect = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri, realm, client);
|
||||||
if(redirect == null){
|
if(redirect == null){
|
||||||
return Flows.errors().error("Invalid redirect uri.", Response.Status.BAD_REQUEST);
|
return ErrorResponse.error("Invalid redirect uri.", Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
redirect = Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName()).toString();
|
redirect = Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName()).toString();
|
||||||
|
@ -760,7 +760,7 @@ public class UsersResource {
|
||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
} catch (EmailException e) {
|
} catch (EmailException e) {
|
||||||
logger.error("Failed to send password reset email", e);
|
logger.error("Failed to send password reset email", e);
|
||||||
return Flows.errors().error("Failed to send email", Response.Status.INTERNAL_SERVER_ERROR);
|
return ErrorResponse.error("Failed to send email", Response.Status.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
package org.keycloak.services.resources.flows;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.jboss.resteasy.spi.BadRequestException;
|
|
||||||
import org.keycloak.AbstractOAuthClient;
|
|
||||||
import org.keycloak.OAuth2Constants;
|
|
||||||
|
|
||||||
import javax.ws.rs.core.Cookie;
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
import javax.ws.rs.core.NewCookie;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper code to obtain oauth access tokens via browser redirects
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
|
||||||
* @version $Revision: 1 $
|
|
||||||
*/
|
|
||||||
public class OAuthRedirect extends AbstractOAuthClient {
|
|
||||||
protected static final Logger logger = Logger.getLogger(OAuthRedirect.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* closes client
|
|
||||||
*/
|
|
||||||
public void stop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Response redirect(UriInfo uriInfo, String redirectUri) {
|
|
||||||
String state = getStateCode();
|
|
||||||
|
|
||||||
UriBuilder uriBuilder = UriBuilder.fromUri(authUrl)
|
|
||||||
.queryParam(OAuth2Constants.CLIENT_ID, clientId)
|
|
||||||
.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri)
|
|
||||||
.queryParam(OAuth2Constants.STATE, state)
|
|
||||||
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE);
|
|
||||||
if (scope != null) {
|
|
||||||
uriBuilder.queryParam(OAuth2Constants.SCOPE, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
URI url = uriBuilder.build();
|
|
||||||
|
|
||||||
// todo httpOnly!
|
|
||||||
NewCookie cookie = new NewCookie(getStateCookieName(), state, getStateCookiePath(uriInfo), null, null, -1, isSecure);
|
|
||||||
logger.debug("NewCookie: " + cookie.toString());
|
|
||||||
logger.debug("Oauth Redirect to: " + url);
|
|
||||||
return Response.status(302)
|
|
||||||
.location(url)
|
|
||||||
.cookie(cookie).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStateCookiePath(UriInfo uriInfo) {
|
|
||||||
if (stateCookiePath != null) return stateCookiePath;
|
|
||||||
return uriInfo.getBaseUri().getRawPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getError(UriInfo uriInfo) {
|
|
||||||
return uriInfo.getQueryParameters().getFirst(OAuth2Constants.ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAccessCode(UriInfo uriInfo) {
|
|
||||||
return uriInfo.getQueryParameters().getFirst(OAuth2Constants.CODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkStateCookie(UriInfo uriInfo, HttpHeaders headers) {
|
|
||||||
Cookie stateCookie = headers.getCookies().get(stateCookieName);
|
|
||||||
if (stateCookie == null) throw new BadRequestException("state cookie not set");
|
|
||||||
String state = uriInfo.getQueryParameters().getFirst(OAuth2Constants.STATE);
|
|
||||||
if (state == null) throw new BadRequestException("state parameter was null");
|
|
||||||
if (!state.equals(stateCookie.getValue())) {
|
|
||||||
throw new BadRequestException("state parameter invalid");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +1,12 @@
|
||||||
package org.keycloak.wellknown;
|
package org.keycloak.wellknown;
|
||||||
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public interface WellKnownProvider extends Provider {
|
public interface WellKnownProvider extends Provider {
|
||||||
|
|
||||||
Object getConfig(RealmModel realm, UriInfo uriInfo);
|
Object getConfig();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.services.managers.ClientSessionCode;
|
import org.keycloak.services.managers.ClientSessionCode;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.ErrorPage;
|
||||||
import org.keycloak.social.SocialIdentityProvider;
|
import org.keycloak.social.SocialIdentityProvider;
|
||||||
import twitter4j.Twitter;
|
import twitter4j.Twitter;
|
||||||
import twitter4j.TwitterFactory;
|
import twitter4j.TwitterFactory;
|
||||||
|
@ -158,7 +158,7 @@ public class TwitterIdentityProvider extends AbstractIdentityProvider<OAuth2Iden
|
||||||
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
EventBuilder event = new EventBuilder(realm, session, clientConnection);
|
||||||
event.event(EventType.LOGIN);
|
event.event(EventType.LOGIN);
|
||||||
event.error("twitter_login_failed");
|
event.error("twitter_login_failed");
|
||||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, headers, Messages.UNEXPECTED_ERROR_HANDLING_RESPONSE);
|
return ErrorPage.error(session, Messages.UNEXPECTED_ERROR_HANDLING_RESPONSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientSessionCode parseClientSessionCode(String code) {
|
private ClientSessionCode parseClientSessionCode(String code) {
|
||||||
|
|
|
@ -43,6 +43,11 @@
|
||||||
<artifactId>keycloak-admin-client</artifactId>
|
<artifactId>keycloak-admin-client</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>event-listener-sysout-example</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
|
|
|
@ -7,6 +7,13 @@
|
||||||
"provider": "${keycloak.eventStore.provider:jpa}"
|
"provider": "${keycloak.eventStore.provider:jpa}"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"eventsListener": {
|
||||||
|
"jboss-logging" : {
|
||||||
|
"success-level": "debug",
|
||||||
|
"error-level": "warn"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"realm": {
|
"realm": {
|
||||||
"provider": "${keycloak.realm.provider:jpa}"
|
"provider": "${keycloak.realm.provider:jpa}"
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,6 +6,9 @@ log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] %m%n
|
||||||
|
|
||||||
log4j.logger.org.keycloak=info
|
log4j.logger.org.keycloak=info
|
||||||
|
|
||||||
|
# Enable to view events
|
||||||
|
# log4j.logger.org.keycloak.events=debug
|
||||||
|
|
||||||
# Enable to view loaded SPI and Providers
|
# Enable to view loaded SPI and Providers
|
||||||
# log4j.logger.org.keycloak.services.DefaultKeycloakSessionFactory=debug
|
# log4j.logger.org.keycloak.services.DefaultKeycloakSessionFactory=debug
|
||||||
# log4j.logger.org.keycloak.provider.ProviderManager=debug
|
# log4j.logger.org.keycloak.provider.ProviderManager=debug
|
||||||
|
|
|
@ -38,7 +38,7 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserModel.RequiredAction;
|
import org.keycloak.models.UserModel.RequiredAction;
|
||||||
import org.keycloak.representations.IDToken;
|
import org.keycloak.representations.IDToken;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
import org.keycloak.testsuite.OAuthClient;
|
||||||
import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
|
import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
|
||||||
import org.keycloak.testsuite.broker.util.UserSessionStatusServlet.UserSessionStatus;
|
import org.keycloak.testsuite.broker.util.UserSessionStatusServlet.UserSessionStatus;
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.keycloak.testsuite.pages;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.testsuite.Constants;
|
import org.keycloak.testsuite.Constants;
|
||||||
import org.openqa.selenium.By;
|
import org.openqa.selenium.By;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.pages;
|
package org.keycloak.testsuite.pages;
|
||||||
|
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.testsuite.Constants;
|
import org.keycloak.testsuite.Constants;
|
||||||
import org.openqa.selenium.By;
|
import org.openqa.selenium.By;
|
||||||
import org.openqa.selenium.WebElement;
|
import org.openqa.selenium.WebElement;
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.pages;
|
package org.keycloak.testsuite.pages;
|
||||||
|
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.Urls;
|
||||||
import org.keycloak.testsuite.Constants;
|
import org.keycloak.testsuite.Constants;
|
||||||
import org.openqa.selenium.By;
|
import org.openqa.selenium.By;
|
||||||
import org.openqa.selenium.WebElement;
|
import org.openqa.selenium.WebElement;
|
||||||
|
|
|
@ -103,11 +103,6 @@ public class LoginPage extends AbstractPage {
|
||||||
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
|
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWarning() {
|
|
||||||
return loginWarningMessage != null ? loginWarningMessage.getText() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isCurrent() {
|
public boolean isCurrent() {
|
||||||
return driver.getTitle().equals("Log in to test") || driver.getTitle().equals("Anmeldung bei test");
|
return driver.getTitle().equals("Log in to test") || driver.getTitle().equals("Anmeldung bei test");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue