Merge pull request #1143 from stianst/kc-context

Added KeycloakContext
This commit is contained in:
Stian Thorgersen 2015-04-15 14:02:14 +02:00
commit 5ef1ddb9f1
64 changed files with 479 additions and 434 deletions

View file

@ -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) {

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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>

View file

@ -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>

View file

@ -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());
} }
} }

View file

@ -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

View file

@ -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>

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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>

View file

@ -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);
}

View file

@ -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);

View file

@ -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()));

View file

@ -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);
} }
} }

View file

@ -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) {

View file

@ -14,6 +14,13 @@
} }
}, },
"eventsListener": {
"jboss-logging" : {
"success-level": "debug",
"error-level": "warn"
}
},
"realm": { "realm": {
"provider": "jpa" "provider": "jpa"
}, },

View file

@ -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 {

View file

@ -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();

View file

@ -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

View file

@ -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();
} }

View file

@ -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);
} }
} }

View file

@ -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;

View file

@ -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;

View file

@ -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.*;

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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() {

View file

@ -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();
} }

View file

@ -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);
} }
} }

View file

@ -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();
} }
} }

View file

@ -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;

View file

@ -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;

View file

@ -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);
} }

View file

@ -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);

View file

@ -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) {

View file

@ -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();
}
}
} }

View file

@ -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) {

View file

@ -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() {

View file

@ -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();
} }
} }

View file

@ -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;

View file

@ -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");
} }
} }

View file

@ -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");
} }
} }

View file

@ -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);
} }
} }

View file

@ -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");
} }
} }

View file

@ -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")

View file

@ -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);

View file

@ -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");
} }
} }

View file

@ -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);
} }
} }

View file

@ -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");
}
}
}

View file

@ -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();
} }

View file

@ -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) {

View file

@ -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>

View file

@ -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}"
}, },

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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");
} }