mirror of
https://github.com/keycloak/keycloak.git
synced 2026-02-09 16:58:58 -06:00
add HttpHeaders
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package org.keycloak.freemarker;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by michigerber on 23.02.15.
|
||||
*/
|
||||
public class LocaleHelper {
|
||||
private final static String LOCALE_COOKIE = "KEYCLOAK_LOCALE";
|
||||
private final static Logger LOGGER = Logger.getLogger(LocaleHelper.class);
|
||||
private static final String LOCALE_PARAM = "ui_locale";
|
||||
|
||||
public static Locale getLocale(RealmModel realm, UserModel user, UriInfo uriInfo, HttpHeaders httpHeaders) {
|
||||
|
||||
//1. Locale cookie
|
||||
if(httpHeaders.getCookies().containsKey(LOCALE_COOKIE)){
|
||||
String localeString = httpHeaders.getCookies().get(LOCALE_COOKIE).getValue();
|
||||
Locale locale = findLocale(localeString, realm.getSupportedLocales());
|
||||
if(locale != null){
|
||||
return locale;
|
||||
}else{
|
||||
LOGGER.infof("Locale %s is not supported.", localeString);
|
||||
}
|
||||
}
|
||||
|
||||
//2. User profile
|
||||
if(user.getAttributes().containsKey(UserModel.LOCALE)){
|
||||
String localeString = user.getAttribute(UserModel.LOCALE);
|
||||
Locale locale = findLocale(localeString, realm.getSupportedLocales());
|
||||
if(locale != null){
|
||||
return locale;
|
||||
}else{
|
||||
LOGGER.infof("Locale %s is not supported.", localeString);
|
||||
}
|
||||
}
|
||||
|
||||
//3. ui_locales query parameter
|
||||
if(uriInfo.getQueryParameters().containsKey(LOCALE_PARAM)){
|
||||
String localeString = uriInfo.getQueryParameters().getFirst(LOCALE_PARAM);
|
||||
Locale locale = findLocale(localeString, realm.getSupportedLocales());
|
||||
if(locale != null){
|
||||
return locale;
|
||||
}else{
|
||||
LOGGER.infof("Locale %s is not supported.", localeString);
|
||||
}
|
||||
}
|
||||
|
||||
//4. Accept-Language http header
|
||||
if(httpHeaders.getLanguage() != null){
|
||||
String localeString =httpHeaders.getLanguage().toLanguageTag();
|
||||
Locale locale = findLocale(localeString, realm.getSupportedLocales());
|
||||
if(locale != null){
|
||||
return locale;
|
||||
}else{
|
||||
LOGGER.infof("Locale %s is not supported.", localeString);
|
||||
}
|
||||
}
|
||||
|
||||
//5. Default realm locale
|
||||
return Locale.forLanguageTag(realm.getDefaultLocale());
|
||||
}
|
||||
|
||||
private static Locale findLocale(String localeString, Set<String> supportedLocales) {
|
||||
List<Locale> locales = new ArrayList<Locale>();
|
||||
for(String l : supportedLocales) {
|
||||
locales.add(Locale.forLanguageTag(l));
|
||||
}
|
||||
return Locale.lookup(Locale.LanguageRange.parse(localeString),locales);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.keycloak.theme;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.freemarker.Theme;
|
||||
|
||||
import java.io.File;
|
||||
@@ -9,14 +8,13 @@ import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class ClassLoaderTheme implements Theme {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ClassLoaderTheme.class);
|
||||
|
||||
private String name;
|
||||
|
||||
private String parentName;
|
||||
@@ -110,20 +108,14 @@ public class ClassLoaderTheme implements Theme {
|
||||
public Properties getMessages(Locale locale) throws IOException {
|
||||
Properties m = new Properties();
|
||||
|
||||
URL url = null;
|
||||
if(locale != null) {
|
||||
URL messageFile = classLoader.getResource(this.messageRoot + "messages_" + locale.toString() + ".properties");
|
||||
if(messageFile != null){
|
||||
url = messageFile;
|
||||
}else{
|
||||
LOGGER.warnf("Can not find message file %s", messageFile);
|
||||
}
|
||||
}
|
||||
|
||||
if(url == null){
|
||||
url = classLoader.getResource(this.messageRoot + "messages.properties");
|
||||
String message = null;
|
||||
if(locale != null){
|
||||
message = this.messageRoot + "messages_" + locale.toString() + ".properties";
|
||||
}else{
|
||||
message = this.messageRoot + "messages.properties";
|
||||
}
|
||||
|
||||
URL url = classLoader.getResource(message);
|
||||
if (url != null) {
|
||||
m.load(url.openStream());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.keycloak.theme;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.freemarker.Theme;
|
||||
|
||||
import java.io.File;
|
||||
@@ -16,7 +15,6 @@ import java.util.Properties;
|
||||
*/
|
||||
public class FolderTheme implements Theme {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(FolderTheme.class);
|
||||
private String parentName;
|
||||
private String importName;
|
||||
private File themeDir;
|
||||
@@ -87,20 +85,14 @@ public class FolderTheme implements Theme {
|
||||
public Properties getMessages(Locale locale) throws IOException {
|
||||
Properties m = new Properties();
|
||||
|
||||
File file = null;
|
||||
if(locale != null) {
|
||||
File messageFile = new File(themeDir, "messages" + File.separator + "messages_" + locale.toString() + ".properties");
|
||||
if (messageFile.isFile()) {
|
||||
file = messageFile;
|
||||
} else {
|
||||
LOGGER.warnf("Can not find message file %s", messageFile);
|
||||
}
|
||||
}
|
||||
|
||||
if(file == null){
|
||||
file = new File(themeDir, "messages" + File.separator + "messages.properties");
|
||||
String message = null;
|
||||
if(locale != null){
|
||||
message = "messages_" + locale.toString() + ".properties";
|
||||
}else{
|
||||
message = "messages.properties";
|
||||
}
|
||||
|
||||
File file = new File(themeDir, "messages" + File.separator + message);
|
||||
if (file.isFile()) {
|
||||
m.load(new FileInputStream(file));
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
@@ -21,6 +22,8 @@ public interface LoginFormsProvider extends Provider {
|
||||
|
||||
public LoginFormsProvider setUriInfo(UriInfo uriInfo);
|
||||
|
||||
public LoginFormsProvider setHttpHeaders(HttpHeaders httpHeaders);
|
||||
|
||||
public Response createResponse(UserModel.RequiredAction action);
|
||||
|
||||
public Response createLogin();
|
||||
|
||||
@@ -5,11 +5,7 @@ import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.email.EmailException;
|
||||
import org.keycloak.email.EmailProvider;
|
||||
import org.keycloak.freemarker.BrowserSecurityHeaderSetup;
|
||||
import org.keycloak.freemarker.FreeMarkerException;
|
||||
import org.keycloak.freemarker.FreeMarkerUtil;
|
||||
import org.keycloak.freemarker.Theme;
|
||||
import org.keycloak.freemarker.ThemeProvider;
|
||||
import org.keycloak.freemarker.*;
|
||||
import org.keycloak.login.LoginFormsPages;
|
||||
import org.keycloak.login.LoginFormsProvider;
|
||||
import org.keycloak.login.freemarker.model.ClientBean;
|
||||
@@ -31,11 +27,7 @@ import org.keycloak.models.UserModel;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.services.resources.flows.Urls;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import javax.ws.rs.core.*;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.*;
|
||||
@@ -74,6 +66,8 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
private UriInfo uriInfo;
|
||||
|
||||
private HttpHeaders httpHeaders;
|
||||
|
||||
public FreeMarkerLoginFormsProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
|
||||
this.session = session;
|
||||
this.freeMarker = freeMarker;
|
||||
@@ -89,6 +83,12 @@ import java.util.concurrent.TimeUnit;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginFormsProvider setHttpHeaders(HttpHeaders httpHeaders) {
|
||||
this.httpHeaders = httpHeaders;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Response createResponse(UserModel.RequiredAction action) {
|
||||
String actionMessage;
|
||||
LoginFormsPages page;
|
||||
@@ -170,7 +170,7 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
Properties messages;
|
||||
try {
|
||||
messages = theme.getMessages(Locale.GERMAN);
|
||||
messages = theme.getMessages(LocaleHelper.getLocale(realm, user, uriInfo, httpHeaders));
|
||||
attributes.put("rb", messages);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Failed to load messages", e);
|
||||
|
||||
@@ -13,6 +13,7 @@ public interface UserModel {
|
||||
public static final String LAST_NAME = "lastName";
|
||||
public static final String FIRST_NAME = "firstName";
|
||||
public static final String EMAIL = "email";
|
||||
public static final String LOCALE = "locale";
|
||||
|
||||
String getId();
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||
|
||||
protected UriInfo uriInfo;
|
||||
|
||||
protected HttpHeaders headers;
|
||||
|
||||
|
||||
@Override
|
||||
@@ -102,6 +103,12 @@ public class SamlProtocol implements LoginProtocol {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SamlProtocol setHttpHeaders(HttpHeaders headers){
|
||||
this.headers = headers;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response cancelLogin(ClientSessionModel clientSession) {
|
||||
return getErrorResponse(clientSession, JBossSAMLURIConstants.STATUS_REQUEST_DENIED.get());
|
||||
@@ -129,7 +136,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||
return builder.redirectBinding().response();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Failed to process response");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Failed to process response", headers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +286,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||
publicKey = SamlProtocolUtils.getEncryptionValidationKey(client);
|
||||
} catch (Exception e) {
|
||||
logger.error("failed", e);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Failed to process response");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Failed to process response", headers);
|
||||
}
|
||||
builder.encrypt(publicKey);
|
||||
}
|
||||
@@ -291,7 +298,7 @@ public class SamlProtocol implements LoginProtocol {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("failed", e);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Failed to process response");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Failed to process response", headers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,18 +101,18 @@ public class SamlService {
|
||||
if (!checkSsl()) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
event.event(EventType.LOGIN_ERROR);
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled", headers);
|
||||
}
|
||||
|
||||
if (samlRequest == null && samlResponse == null) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request", headers);
|
||||
|
||||
}
|
||||
return null;
|
||||
@@ -124,7 +124,7 @@ public class SamlService {
|
||||
logger.warn("Unknown saml response.");
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request", headers);
|
||||
}
|
||||
// assume this is a logout response
|
||||
UserSessionModel userSession = authResult.getSession();
|
||||
@@ -133,10 +133,10 @@ public class SamlService {
|
||||
logger.warn("UserSession is not tagged as logging out.");
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request", headers);
|
||||
}
|
||||
logger.debug("logout response");
|
||||
return authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection);
|
||||
return authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||
}
|
||||
|
||||
protected Response handleSamlRequest(String samlRequest, String relayState) {
|
||||
@@ -144,7 +144,7 @@ public class SamlService {
|
||||
if (documentHolder == null) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request", headers);
|
||||
}
|
||||
|
||||
SAML2Object samlObject = documentHolder.getSamlObject();
|
||||
@@ -156,23 +156,23 @@ public class SamlService {
|
||||
if (client == null) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.CLIENT_NOT_FOUND);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.", headers);
|
||||
}
|
||||
|
||||
if (!client.isEnabled()) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.CLIENT_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.", headers);
|
||||
}
|
||||
if ((client instanceof ApplicationModel) && ((ApplicationModel)client).isBearerOnly()) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.NOT_ALLOWED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Bearer-only applications are not allowed to initiate browser login");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Bearer-only applications are not allowed to initiate browser login", headers);
|
||||
}
|
||||
if (client.isDirectGrantsOnly()) {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.NOT_ALLOWED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "direct-grants-only clients are not allowed to initiate browser login");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "direct-grants-only clients are not allowed to initiate browser login", headers);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -181,7 +181,7 @@ public class SamlService {
|
||||
SamlService.logger.error("request validation failed", e);
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_SIGNATURE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid requester.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid requester.", headers);
|
||||
}
|
||||
logger.debug("verified request");
|
||||
if (samlObject instanceof AuthnRequestType) {
|
||||
@@ -199,7 +199,7 @@ public class SamlService {
|
||||
} else {
|
||||
event.event(EventType.LOGIN);
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid Request", headers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ public class SamlService {
|
||||
|
||||
if (redirect == null) {
|
||||
event.error(Errors.INVALID_REDIRECT_URI);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect_uri.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect_uri.", headers);
|
||||
}
|
||||
|
||||
|
||||
@@ -251,14 +251,14 @@ public class SamlService {
|
||||
clientSession.setNote(GeneralConstants.NAMEID_FORMAT, nameIdFormat);
|
||||
} else {
|
||||
event.error(Errors.INVALID_TOKEN);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unsupported NameIDFormat.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unsupported NameIDFormat.", headers);
|
||||
}
|
||||
}
|
||||
|
||||
Response response = authManager.checkNonFormAuthentication(session, clientSession, realm, uriInfo, request, clientConnection, headers, event);
|
||||
if (response != null) return response;
|
||||
|
||||
LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo)
|
||||
LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers)
|
||||
.setClientSessionCode(new ClientSessionCode(realm, clientSession).getCode());
|
||||
|
||||
String rememberMeUsername = AuthenticationManager.getRememberMeUsername(realm, headers);
|
||||
@@ -327,7 +327,7 @@ public class SamlService {
|
||||
}
|
||||
}
|
||||
logger.debug("browser Logout");
|
||||
return authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection);
|
||||
return authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||
}
|
||||
|
||||
|
||||
@@ -340,7 +340,7 @@ public class SamlService {
|
||||
if (redirectUri != null) {
|
||||
redirectUri = OIDCLoginProtocolService.verifyRedirectUri(uriInfo, redirectUri, realm, client);
|
||||
if (redirectUri == null) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect uri.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect uri.", headers);
|
||||
}
|
||||
}
|
||||
if (redirectUri != null) {
|
||||
@@ -352,7 +352,7 @@ public class SamlService {
|
||||
}
|
||||
|
||||
private Response logout(UserSessionModel userSession) {
|
||||
Response response = authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection);
|
||||
Response response = authManager.browserLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||
if (response == null) event.user(userSession.getUser()).session(userSession).success();
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.services.managers.ClientSessionCode;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
@@ -21,6 +22,8 @@ public interface LoginProtocol extends Provider {
|
||||
|
||||
LoginProtocol setUriInfo(UriInfo uriInfo);
|
||||
|
||||
LoginProtocol setHttpHeaders(HttpHeaders headers);
|
||||
|
||||
Response cancelLogin(ClientSessionModel clientSession);
|
||||
Response invalidSessionError(ClientSessionModel clientSession);
|
||||
Response authenticated(UserSessionModel userSession, ClientSessionCode accessCode);
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.keycloak.protocol.LoginProtocol;
|
||||
import org.keycloak.services.managers.ClientSessionCode;
|
||||
import org.keycloak.services.managers.ResourceAdminManager;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
@@ -59,13 +60,17 @@ public class OIDCLoginProtocol implements LoginProtocol {
|
||||
|
||||
protected UriInfo uriInfo;
|
||||
|
||||
public OIDCLoginProtocol(KeycloakSession session, RealmModel realm, UriInfo uriInfo) {
|
||||
protected HttpHeaders headers;
|
||||
|
||||
public OIDCLoginProtocol(KeycloakSession session, RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
|
||||
this.session = session;
|
||||
this.realm = realm;
|
||||
this.uriInfo = uriInfo;
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
public OIDCLoginProtocol() {
|
||||
public OIDCLoginProtocol(){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,6 +91,12 @@ public class OIDCLoginProtocol implements LoginProtocol {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OIDCLoginProtocol setHttpHeaders(HttpHeaders headers){
|
||||
this.headers = headers;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response cancelLogin(ClientSessionModel clientSession) {
|
||||
String redirect = clientSession.getRedirectUri();
|
||||
|
||||
@@ -508,7 +508,7 @@ public class OIDCLoginProtocolService {
|
||||
}
|
||||
AccessToken accessToken;
|
||||
try {
|
||||
accessToken = tokenManager.refreshAccessToken(session, uriInfo, clientConnection, realm, client, refreshToken, event);
|
||||
accessToken = tokenManager.refreshAccessToken(session, uriInfo, clientConnection, realm, client, refreshToken, event, headers);
|
||||
} catch (OAuthErrorException e) {
|
||||
Map<String, String> error = new HashMap<String, String>();
|
||||
error.put(OAuth2Constants.ERROR, e.getError());
|
||||
@@ -648,7 +648,7 @@ public class OIDCLoginProtocolService {
|
||||
}
|
||||
|
||||
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
|
||||
AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection);
|
||||
AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||
Map<String, String> res = new HashMap<String, String>();
|
||||
res.put(OAuth2Constants.ERROR, "invalid_grant");
|
||||
res.put(OAuth2Constants.ERROR_DESCRIPTION, "Session not active");
|
||||
@@ -785,37 +785,37 @@ public class OIDCLoginProtocolService {
|
||||
event.client(clientId).detail(Details.REDIRECT_URI, redirect).detail(Details.RESPONSE_TYPE, "code");
|
||||
if (!checkSsl()) {
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled", headers);
|
||||
}
|
||||
|
||||
clientSession = null;
|
||||
ClientModel client = realm.findClient(clientId);
|
||||
if (client == null) {
|
||||
event.error(Errors.CLIENT_NOT_FOUND);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.", headers);
|
||||
}
|
||||
|
||||
if (!client.isEnabled()) {
|
||||
event.error(Errors.CLIENT_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.", headers);
|
||||
}
|
||||
if ((client instanceof ApplicationModel) && ((ApplicationModel)client).isBearerOnly()) {
|
||||
event.error(Errors.NOT_ALLOWED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Bearer-only applications are not allowed to initiate browser login");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Bearer-only applications are not allowed to initiate browser login", headers);
|
||||
}
|
||||
if (client.isDirectGrantsOnly()) {
|
||||
event.error(Errors.NOT_ALLOWED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "direct-grants-only clients are not allowed to initiate browser login");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "direct-grants-only clients are not allowed to initiate browser login", headers);
|
||||
}
|
||||
String redirectUriParam = redirect;
|
||||
redirect = verifyRedirectUri(uriInfo, redirect, realm, client);
|
||||
if (redirect == null) {
|
||||
event.error(Errors.INVALID_REDIRECT_URI);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect_uri.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect_uri.", headers);
|
||||
}
|
||||
clientSession = session.sessions().createClientSession(realm, client);
|
||||
clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
|
||||
@@ -874,7 +874,7 @@ public class OIDCLoginProtocolService {
|
||||
IdentityProviderModel identityProviderModel = realm.getIdentityProviderById(idpHint);
|
||||
|
||||
if (identityProviderModel == null) {
|
||||
return Flows.forms(session, realm, null, uriInfo)
|
||||
return Flows.forms(session, realm, null, uriInfo, headers)
|
||||
.setError("Could not find an identity provider with the identifier [" + idpHint + "].")
|
||||
.createErrorPage();
|
||||
}
|
||||
@@ -886,11 +886,11 @@ public class OIDCLoginProtocolService {
|
||||
|
||||
// SPNEGO/Kerberos authentication TODO: This should be somehow pluggable instead of hardcoded this way (Authentication interceptors?)
|
||||
HttpAuthenticationManager httpAuthManager = new HttpAuthenticationManager(session, clientSession, realm, uriInfo, request, clientConnection, event);
|
||||
HttpAuthenticationManager.HttpAuthOutput httpAuthOutput = httpAuthManager.spnegoAuthenticate();
|
||||
HttpAuthenticationManager.HttpAuthOutput httpAuthOutput = httpAuthManager.spnegoAuthenticate(headers);
|
||||
if (httpAuthOutput.getResponse() != null) return httpAuthOutput.getResponse();
|
||||
|
||||
if (prompt != null && prompt.equals("none")) {
|
||||
OIDCLoginProtocol oauth = new OIDCLoginProtocol(session, realm, uriInfo);
|
||||
OIDCLoginProtocol oauth = new OIDCLoginProtocol(session, realm, uriInfo, headers);
|
||||
return oauth.cancelLogin(clientSession);
|
||||
}
|
||||
|
||||
@@ -908,13 +908,13 @@ public class OIDCLoginProtocolService {
|
||||
return redirectToIdentityProvider(identityProviders.get(0).getId(), accessCode);
|
||||
}
|
||||
|
||||
return Flows.forms(session, realm, null, uriInfo).setError("Realm [" + this.realm.getName() + "] supports multiple identity providers. Could not determine which identity provider should be used to authenticate with.").createErrorPage();
|
||||
return Flows.forms(session, realm, null, uriInfo, headers).setError("Realm [" + this.realm.getName() + "] supports multiple identity providers. Could not determine which identity provider should be used to authenticate with.").createErrorPage();
|
||||
}
|
||||
|
||||
return Flows.forms(session, realm, null, uriInfo).setError("Realm [" + this.realm.getName() + "] does not support any credential type.").createErrorPage();
|
||||
return Flows.forms(session, realm, null, uriInfo, headers).setError("Realm [" + this.realm.getName() + "] does not support any credential type.").createErrorPage();
|
||||
}
|
||||
|
||||
LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo)
|
||||
LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers)
|
||||
.setClientSessionCode(accessCode);
|
||||
|
||||
// Attach state from SPNEGO authentication
|
||||
@@ -960,7 +960,7 @@ public class OIDCLoginProtocolService {
|
||||
event.event(EventType.REGISTER);
|
||||
if (!realm.isRegistrationAllowed()) {
|
||||
event.error(Errors.REGISTRATION_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed", headers);
|
||||
}
|
||||
|
||||
FrontPageInitializer pageInitializer = new FrontPageInitializer();
|
||||
@@ -976,7 +976,7 @@ public class OIDCLoginProtocolService {
|
||||
|
||||
authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
|
||||
|
||||
return Flows.forms(session, realm, clientSession.getClient(), uriInfo)
|
||||
return Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers)
|
||||
.setClientSessionCode(new ClientSessionCode(realm, clientSession).getCode())
|
||||
.createRegistration();
|
||||
}
|
||||
@@ -1004,7 +1004,7 @@ public class OIDCLoginProtocolService {
|
||||
if (redirectUri != null) {
|
||||
String validatedRedirect = verifyRealmRedirectUri(uriInfo, redirectUri, realm);
|
||||
if (validatedRedirect == null) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect uri.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid redirect uri.", headers);
|
||||
}
|
||||
return Response.status(302).location(UriBuilder.fromUri(validatedRedirect).build()).build();
|
||||
} else {
|
||||
@@ -1065,14 +1065,14 @@ public class OIDCLoginProtocolService {
|
||||
}
|
||||
|
||||
private void logout(UserSessionModel userSession) {
|
||||
authManager.logout(session, realm, userSession, uriInfo, clientConnection);
|
||||
authManager.logout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||
event.user(userSession.getUser()).session(userSession).success();
|
||||
}
|
||||
|
||||
@Path("oauth/oob")
|
||||
@GET
|
||||
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);
|
||||
LoginFormsProvider forms = Flows.forms(session, realm, null, uriInfo, headers);
|
||||
if (code != null) {
|
||||
return forms.setClientSessionCode(code).createCode();
|
||||
} else {
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.keycloak.representations.RefreshToken;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.util.Time;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
@@ -57,7 +58,7 @@ public class TokenManager {
|
||||
}
|
||||
}
|
||||
|
||||
public AccessToken refreshAccessToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel client, String encodedRefreshToken, EventBuilder event) throws OAuthErrorException {
|
||||
public AccessToken refreshAccessToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel client, String encodedRefreshToken, EventBuilder event, HttpHeaders headers) throws OAuthErrorException {
|
||||
RefreshToken refreshToken = verifyRefreshToken(realm, encodedRefreshToken);
|
||||
|
||||
event.user(refreshToken.getSubject()).session(refreshToken.getSessionState()).detail(Details.REFRESH_TOKEN_ID, refreshToken.getId());
|
||||
@@ -74,7 +75,7 @@ public class TokenManager {
|
||||
UserSessionModel userSession = session.sessions().getUserSession(realm, refreshToken.getSessionState());
|
||||
int currentTime = Time.currentTime();
|
||||
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
|
||||
AuthenticationManager.logout(session, realm, userSession, uriInfo, connection);
|
||||
AuthenticationManager.logout(session, realm, userSession, uriInfo, connection, headers);
|
||||
throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Session not active", "Session not active");
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public class AppAuthManager extends AuthenticationManager {
|
||||
public AuthResult authenticateBearerToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
|
||||
String tokenString = extractAuthorizationHeaderToken(headers);
|
||||
if (tokenString == null) return null;
|
||||
AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, connection, true, tokenString);
|
||||
AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, connection, true, tokenString, headers);
|
||||
return authResult;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class AuthenticationManager {
|
||||
return userSession != null && userSession.getLastSessionRefresh() + realm.getSsoSessionIdleTimeout() > currentTime && max > currentTime;
|
||||
}
|
||||
|
||||
public static void logout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection) {
|
||||
public static void logout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
|
||||
if (userSession == null) return;
|
||||
UserModel user = userSession.getUser();
|
||||
userSession.setState(UserSessionModel.State.LOGGING_OUT);
|
||||
@@ -94,6 +94,7 @@ public class AuthenticationManager {
|
||||
if (authMethod == null) continue; // must be a keycloak service like account
|
||||
LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
|
||||
protocol.setRealm(realm)
|
||||
.setHttpHeaders(headers)
|
||||
.setUriInfo(uriInfo);
|
||||
protocol.backchannelLogout(userSession, clientSession);
|
||||
clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT);
|
||||
@@ -104,7 +105,7 @@ public class AuthenticationManager {
|
||||
}
|
||||
|
||||
|
||||
public static Response browserLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection) {
|
||||
public static Response browserLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
|
||||
if (userSession == null) return null;
|
||||
UserModel user = userSession.getUser();
|
||||
|
||||
@@ -127,6 +128,7 @@ public class AuthenticationManager {
|
||||
if (authMethod == null) continue; // must be a keycloak service like account
|
||||
LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
|
||||
protocol.setRealm(realm)
|
||||
.setHttpHeaders(headers)
|
||||
.setUriInfo(uriInfo);
|
||||
try {
|
||||
logger.debugv("backchannel logout to: {0}", client.getClientId());
|
||||
@@ -139,12 +141,13 @@ public class AuthenticationManager {
|
||||
}
|
||||
|
||||
if (redirectClients.size() == 0) {
|
||||
return finishBrowserLogout(session, realm, userSession, uriInfo, connection);
|
||||
return finishBrowserLogout(session, realm, userSession, uriInfo, connection, headers);
|
||||
}
|
||||
for (ClientSessionModel nextRedirectClient : redirectClients) {
|
||||
String authMethod = nextRedirectClient.getAuthMethod();
|
||||
LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
|
||||
protocol.setRealm(realm)
|
||||
.setHttpHeaders(headers)
|
||||
.setUriInfo(uriInfo);
|
||||
// setting this to logged out cuz I"m not sure protocols can always verify that the client was logged out or not
|
||||
nextRedirectClient.setAction(ClientSessionModel.Action.LOGGED_OUT);
|
||||
@@ -160,16 +163,17 @@ public class AuthenticationManager {
|
||||
}
|
||||
|
||||
}
|
||||
return finishBrowserLogout(session, realm, userSession, uriInfo, connection);
|
||||
return finishBrowserLogout(session, realm, userSession, uriInfo, connection, headers);
|
||||
}
|
||||
|
||||
protected static Response finishBrowserLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection) {
|
||||
protected static Response finishBrowserLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
|
||||
expireIdentityCookie(realm, uriInfo, connection);
|
||||
expireRememberMeCookie(realm, uriInfo, connection);
|
||||
userSession.setState(UserSessionModel.State.LOGGED_OUT);
|
||||
String method = userSession.getNote(KEYCLOAK_LOGOUT_PROTOCOL);
|
||||
LoginProtocol protocol = session.getProvider(LoginProtocol.class, method);
|
||||
protocol.setRealm(realm)
|
||||
.setHttpHeaders(headers)
|
||||
.setUriInfo(uriInfo);
|
||||
Response response = protocol.finishLogout(userSession);
|
||||
session.sessions().removeUserSession(realm, userSession);
|
||||
@@ -284,7 +288,7 @@ public class AuthenticationManager {
|
||||
}
|
||||
|
||||
String tokenString = cookie.getValue();
|
||||
AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, connection, checkActive, tokenString);
|
||||
AuthResult authResult = verifyIdentityToken(session, realm, uriInfo, connection, checkActive, tokenString, headers);
|
||||
if (authResult == null) {
|
||||
expireIdentityCookie(realm, uriInfo, connection);
|
||||
return null;
|
||||
@@ -334,6 +338,7 @@ public class AuthenticationManager {
|
||||
if (userSession.isRememberMe()) createRememberMeCookie(realm, userSession.getUser().getUsername(), uriInfo, clientConnection);
|
||||
LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
|
||||
protocol.setRealm(realm)
|
||||
.setHttpHeaders(request.getHttpHeaders())
|
||||
.setUriInfo(uriInfo);
|
||||
return protocol.authenticated(userSession, new ClientSessionCode(realm, clientSession));
|
||||
|
||||
@@ -363,7 +368,7 @@ public class AuthenticationManager {
|
||||
UserModel.RequiredAction action = user.getRequiredActions().iterator().next();
|
||||
accessCode.setRequiredAction(action);
|
||||
|
||||
LoginFormsProvider loginFormsProvider = Flows.forms(session, realm, client, uriInfo).setClientSessionCode(accessCode.getCode()).setUser(user);
|
||||
LoginFormsProvider loginFormsProvider = Flows.forms(session, realm, client, uriInfo, request.getHttpHeaders()).setClientSessionCode(accessCode.getCode()).setUser(user);
|
||||
if (action.equals(UserModel.RequiredAction.VERIFY_EMAIL)) {
|
||||
event.clone().event(EventType.SEND_VERIFY_EMAIL).detail(Details.EMAIL, user.getEmail()).success();
|
||||
}
|
||||
@@ -385,7 +390,7 @@ public class AuthenticationManager {
|
||||
}
|
||||
}
|
||||
|
||||
return Flows.forms(session, realm, client, uriInfo)
|
||||
return Flows.forms(session, realm, client, uriInfo, request.getHttpHeaders())
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
.setAccessRequest(realmRoles, resourceRoles)
|
||||
.setClient(client)
|
||||
@@ -413,7 +418,7 @@ public class AuthenticationManager {
|
||||
}
|
||||
}
|
||||
|
||||
protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, boolean checkActive, String tokenString) {
|
||||
protected AuthResult verifyIdentityToken(KeycloakSession session, RealmModel realm, UriInfo uriInfo, ClientConnection connection, boolean checkActive, String tokenString, HttpHeaders headers) {
|
||||
try {
|
||||
AccessToken token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName(), checkActive);
|
||||
if (checkActive) {
|
||||
@@ -433,7 +438,7 @@ public class AuthenticationManager {
|
||||
|
||||
UserSessionModel userSession = session.sessions().getUserSession(realm, token.getSessionState());
|
||||
if (!isSessionValid(realm, userSession)) {
|
||||
if (userSession != null) logout(session, realm, userSession, uriInfo, connection);
|
||||
if (userSession != null) logout(session, realm, userSession, uriInfo, connection, headers);
|
||||
logger.debug("User session not active");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class HttpAuthenticationManager {
|
||||
}
|
||||
|
||||
|
||||
public HttpAuthOutput spnegoAuthenticate() {
|
||||
public HttpAuthOutput spnegoAuthenticate(HttpHeaders headers) {
|
||||
boolean kerberosSupported = false;
|
||||
for (RequiredCredentialModel c : realm.getRequiredCredentials()) {
|
||||
if (c.getType().equals(CredentialRepresentation.KERBEROS)) {
|
||||
@@ -94,7 +94,7 @@ public class HttpAuthenticationManager {
|
||||
CredentialValidationOutput output = session.users().validCredentials(realm, spnegoCredential);
|
||||
|
||||
if (output.getAuthStatus() == CredentialValidationOutput.Status.AUTHENTICATED) {
|
||||
return sendResponse(output.getAuthenticatedUser(), "spnego");
|
||||
return sendResponse(output.getAuthenticatedUser(), "spnego", headers);
|
||||
} else {
|
||||
String spnegoResponseToken = (String) output.getState().get(KerberosConstants.RESPONSE_TOKEN);
|
||||
return challengeNegotiation(spnegoResponseToken);
|
||||
@@ -104,7 +104,7 @@ public class HttpAuthenticationManager {
|
||||
|
||||
|
||||
// Send response after successful authentication
|
||||
private HttpAuthOutput sendResponse(UserModel user, String authMethod) {
|
||||
private HttpAuthOutput sendResponse(UserModel user, String authMethod, HttpHeaders headers) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("User " + user.getUsername() + " authenticated with " + authMethod);
|
||||
}
|
||||
@@ -112,7 +112,7 @@ public class HttpAuthenticationManager {
|
||||
Response response;
|
||||
if (!user.isEnabled()) {
|
||||
event.error(Errors.USER_DISABLED);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, Messages.ACCOUNT_DISABLED);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, Messages.ACCOUNT_DISABLED, headers);
|
||||
} else {
|
||||
UserSessionModel userSession = session.sessions().createUserSession(realm, user, user.getUsername(), clientConnection.getRemoteAddr(), authMethod, false);
|
||||
TokenManager.attachClientSession(userSession, clientSession);
|
||||
|
||||
@@ -241,7 +241,7 @@ public class AccountService {
|
||||
try {
|
||||
require(AccountRoles.MANAGE_ACCOUNT);
|
||||
} catch (ForbiddenException e) {
|
||||
return Flows.forms(session, realm, null, uriInfo).setError("No access").createErrorPage();
|
||||
return Flows.forms(session, realm, null, uriInfo, headers).setError("No access").createErrorPage();
|
||||
}
|
||||
|
||||
setReferrerOnPage();
|
||||
|
||||
@@ -57,13 +57,8 @@ import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.*;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -97,6 +92,10 @@ public class IdentityBrokerService {
|
||||
|
||||
@Context
|
||||
private HttpRequest request;
|
||||
|
||||
@Context
|
||||
private HttpHeaders headers;
|
||||
|
||||
private EventBuilder event;
|
||||
|
||||
public IdentityBrokerService(RealmModel realmModel) {
|
||||
@@ -187,11 +186,10 @@ public class IdentityBrokerService {
|
||||
}
|
||||
|
||||
if (OAuthClientModel.class.isInstance(clientModel) && !forceRetrieval) {
|
||||
return corsResponse(Flows.forms(this.session, this.realmModel, clientModel, this.uriInfo)
|
||||
return corsResponse(Flows.forms(this.session, this.realmModel, clientModel, this.uriInfo, headers)
|
||||
.setClientSessionCode(authManager.extractAuthorizationHeaderToken(this.request.getHttpHeaders()))
|
||||
.setAccessRequest("Your information from " + providerId + " identity provider.")
|
||||
.setClient(clientModel)
|
||||
.setUriInfo(this.uriInfo)
|
||||
.setActionUri(this.uriInfo.getRequestUri())
|
||||
.createOAuthGrant(), clientModel);
|
||||
}
|
||||
@@ -439,7 +437,7 @@ public class IdentityBrokerService {
|
||||
|
||||
private Response redirectToErrorPage(String message, Throwable throwable) {
|
||||
fireErrorEvent(message, throwable);
|
||||
return Flows.forwardToSecurityFailurePage(this.session, this.realmModel, this.uriInfo, message);
|
||||
return Flows.forwardToSecurityFailurePage(this.session, this.realmModel, this.uriInfo, message, headers);
|
||||
}
|
||||
|
||||
private Response badRequest(String message) {
|
||||
@@ -449,7 +447,7 @@ public class IdentityBrokerService {
|
||||
|
||||
private Response redirectToLoginPage(String message, ClientSessionCode clientCode) {
|
||||
fireErrorEvent(message);
|
||||
return Flows.forms(this.session, this.realmModel, clientCode.getClientSession().getClient(), this.uriInfo)
|
||||
return Flows.forms(this.session, this.realmModel, clientCode.getClientSession().getClient(), this.uriInfo, headers)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
.setError(message)
|
||||
.createLogin();
|
||||
|
||||
@@ -156,7 +156,7 @@ public class LoginActionsService {
|
||||
return false;
|
||||
} else if (!clientCode.isValid(requiredAction)) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.");
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.", headers);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -166,18 +166,18 @@ public class LoginActionsService {
|
||||
public boolean check(String code) {
|
||||
if (!checkSsl()) {
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
return false;
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.", headers);
|
||||
return false;
|
||||
}
|
||||
clientCode = ClientSessionCode.parse(code, session, realm);
|
||||
if (clientCode == null) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.");
|
||||
response = Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.", headers);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -208,7 +208,7 @@ public class LoginActionsService {
|
||||
clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE);
|
||||
}
|
||||
|
||||
LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo)
|
||||
LoginFormsProvider forms = Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers)
|
||||
.setClientSessionCode(clientSessionCode.getCode());
|
||||
|
||||
return forms.createLogin();
|
||||
@@ -226,7 +226,7 @@ public class LoginActionsService {
|
||||
event.event(EventType.REGISTER);
|
||||
if (!realm.isRegistrationAllowed()) {
|
||||
event.error(Errors.REGISTRATION_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed", headers);
|
||||
}
|
||||
|
||||
Checks checks = new Checks();
|
||||
@@ -240,7 +240,7 @@ public class LoginActionsService {
|
||||
|
||||
authManager.expireIdentityCookie(realm, uriInfo, clientConnection);
|
||||
|
||||
return Flows.forms(session, realm, clientSession.getClient(), uriInfo)
|
||||
return Flows.forms(session, realm, clientSession.getClient(), uriInfo, headers)
|
||||
.setClientSessionCode(clientSessionCode.getCode())
|
||||
.createRegistration();
|
||||
}
|
||||
@@ -260,23 +260,23 @@ public class LoginActionsService {
|
||||
event.event(EventType.LOGIN);
|
||||
if (!checkSsl()) {
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
}
|
||||
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.", headers);
|
||||
}
|
||||
ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
|
||||
if (clientCode == null) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.", headers);
|
||||
}
|
||||
ClientSessionModel clientSession = clientCode.getClientSession();
|
||||
if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE) || clientSession.getUserSession() != null) {
|
||||
clientCode.setAction(ClientSessionModel.Action.AUTHENTICATE);
|
||||
event.client(clientSession.getClient()).error(Errors.EXPIRED_CODE);
|
||||
return Flows.forms(this.session, realm, clientSession.getClient(), uriInfo).setError(Messages.EXPIRED_CODE)
|
||||
return Flows.forms(this.session, realm, clientSession.getClient(), uriInfo, headers).setError(Messages.EXPIRED_CODE)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
.createLogin();
|
||||
}
|
||||
@@ -300,17 +300,18 @@ public class LoginActionsService {
|
||||
ClientModel client = clientSession.getClient();
|
||||
if (client == null) {
|
||||
event.error(Errors.CLIENT_NOT_FOUND);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.", headers);
|
||||
}
|
||||
if (!client.isEnabled()) {
|
||||
event.error(Errors.CLIENT_NOT_FOUND);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.", headers);
|
||||
}
|
||||
|
||||
if (formData.containsKey("cancel")) {
|
||||
event.error(Errors.REJECTED_BY_USER);
|
||||
LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
|
||||
protocol.setRealm(realm)
|
||||
.setHttpHeaders(headers)
|
||||
.setUriInfo(uriInfo);
|
||||
return protocol.cancelLogin(clientSession);
|
||||
}
|
||||
@@ -337,14 +338,14 @@ public class LoginActionsService {
|
||||
return authManager.nextActionAfterAuthentication(session, userSession, clientSession, clientConnection, request, uriInfo, event);
|
||||
case ACCOUNT_TEMPORARILY_DISABLED:
|
||||
event.error(Errors.USER_TEMPORARILY_DISABLED);
|
||||
return Flows.forms(this.session, realm, client, uriInfo)
|
||||
return Flows.forms(this.session, realm, client, uriInfo, headers)
|
||||
.setError(Messages.ACCOUNT_TEMPORARILY_DISABLED)
|
||||
.setFormData(formData)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
.createLogin();
|
||||
case ACCOUNT_DISABLED:
|
||||
event.error(Errors.USER_DISABLED);
|
||||
return Flows.forms(this.session, realm, client, uriInfo)
|
||||
return Flows.forms(this.session, realm, client, uriInfo, headers)
|
||||
.setError(Messages.ACCOUNT_DISABLED)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
.setFormData(formData).createLogin();
|
||||
@@ -354,19 +355,19 @@ public class LoginActionsService {
|
||||
String passwordToken = new JWSBuilder().jsonContent(new PasswordToken(realm.getName(), user.getId())).rsa256(realm.getPrivateKey());
|
||||
formData.add(CredentialRepresentation.PASSWORD_TOKEN, passwordToken);
|
||||
|
||||
return Flows.forms(this.session, realm, client, uriInfo)
|
||||
return Flows.forms(this.session, realm, client, uriInfo, headers)
|
||||
.setFormData(formData)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
.createLoginTotp();
|
||||
case INVALID_USER:
|
||||
event.error(Errors.USER_NOT_FOUND);
|
||||
return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.INVALID_USER)
|
||||
return Flows.forms(this.session, realm, client, uriInfo, headers).setError(Messages.INVALID_USER)
|
||||
.setFormData(formData)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
.createLogin();
|
||||
default:
|
||||
event.error(Errors.INVALID_USER_CREDENTIALS);
|
||||
return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.INVALID_USER)
|
||||
return Flows.forms(this.session, realm, client, uriInfo, headers).setError(Messages.INVALID_USER)
|
||||
.setFormData(formData)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
.createLogin();
|
||||
@@ -388,25 +389,25 @@ public class LoginActionsService {
|
||||
event.event(EventType.REGISTER);
|
||||
if (!checkSsl()) {
|
||||
event.error(Errors.SSL_REQUIRED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
}
|
||||
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.", headers);
|
||||
}
|
||||
if (!realm.isRegistrationAllowed()) {
|
||||
event.error(Errors.REGISTRATION_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Registration not allowed", headers);
|
||||
}
|
||||
ClientSessionCode clientCode = ClientSessionCode.parse(code, session, realm);
|
||||
if (clientCode == null) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.", headers);
|
||||
}
|
||||
if (!clientCode.isValid(ClientSessionModel.Action.AUTHENTICATE)) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid code, please login again through your application.", headers);
|
||||
}
|
||||
|
||||
String username = formData.getFirst("username");
|
||||
@@ -421,17 +422,17 @@ public class LoginActionsService {
|
||||
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled", headers);
|
||||
}
|
||||
ClientModel client = clientSession.getClient();
|
||||
if (client == null) {
|
||||
event.error(Errors.CLIENT_NOT_FOUND);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown login requester.", headers);
|
||||
}
|
||||
|
||||
if (!client.isEnabled()) {
|
||||
event.error(Errors.CLIENT_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Login requester not enabled.", headers);
|
||||
}
|
||||
|
||||
|
||||
@@ -448,7 +449,7 @@ public class LoginActionsService {
|
||||
|
||||
if (error != null) {
|
||||
event.error(Errors.INVALID_REGISTRATION);
|
||||
return Flows.forms(session, realm, client, uriInfo)
|
||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
||||
.setError(error)
|
||||
.setFormData(formData)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
@@ -458,7 +459,7 @@ public class LoginActionsService {
|
||||
// Validate that user with this username doesn't exist in realm or any federation provider
|
||||
if (session.users().getUserByUsername(username, realm) != null) {
|
||||
event.error(Errors.USERNAME_IN_USE);
|
||||
return Flows.forms(session, realm, client, uriInfo)
|
||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
||||
.setError(Messages.USERNAME_EXISTS)
|
||||
.setFormData(formData)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
@@ -468,7 +469,7 @@ public class LoginActionsService {
|
||||
// Validate that user with this email doesn't exist in realm or any federation provider
|
||||
if (session.users().getUserByEmail(email, realm) != null) {
|
||||
event.error(Errors.EMAIL_IN_USE);
|
||||
return Flows.forms(session, realm, client, uriInfo)
|
||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
||||
.setError(Messages.EMAIL_EXISTS)
|
||||
.setFormData(formData)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
@@ -500,7 +501,7 @@ public class LoginActionsService {
|
||||
// User already registered, but force him to update password
|
||||
if (!passwordUpdateSuccessful) {
|
||||
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
|
||||
return Flows.forms(session, realm, client, uriInfo)
|
||||
return Flows.forms(session, realm, client, uriInfo, headers)
|
||||
.setError(passwordUpdateError)
|
||||
.setClientSessionCode(clientCode.getCode())
|
||||
.createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
|
||||
@@ -527,7 +528,7 @@ public class LoginActionsService {
|
||||
|
||||
|
||||
if (!checkSsl()) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
}
|
||||
|
||||
String code = formData.getFirst("code");
|
||||
@@ -535,7 +536,7 @@ public class LoginActionsService {
|
||||
ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
|
||||
if (accessCode == null || !accessCode.isValid(ClientSessionModel.Action.OAUTH_GRANT)) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid access code.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Invalid access code.", headers);
|
||||
}
|
||||
ClientSessionModel clientSession = accessCode.getClientSession();
|
||||
event.detail(Details.CODE_ID, clientSession.getId());
|
||||
@@ -557,14 +558,15 @@ public class LoginActionsService {
|
||||
}
|
||||
|
||||
if (!AuthenticationManager.isSessionValid(realm, userSession)) {
|
||||
AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection);
|
||||
AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Session not active");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Session not active", headers);
|
||||
}
|
||||
event.session(userSession);
|
||||
|
||||
LoginProtocol protocol = session.getProvider(LoginProtocol.class, clientSession.getAuthMethod());
|
||||
protocol.setRealm(realm)
|
||||
.setHttpHeaders(headers)
|
||||
.setUriInfo(uriInfo);
|
||||
if (formData.containsKey("cancel")) {
|
||||
event.error(Errors.REJECTED_BY_USER);
|
||||
@@ -598,7 +600,7 @@ public class LoginActionsService {
|
||||
|
||||
String error = Validation.validateUpdateProfileForm(formData);
|
||||
if (error != null) {
|
||||
return Flows.forms(session, realm, null, uriInfo).setUser(user).setError(error)
|
||||
return Flows.forms(session, realm, null, uriInfo, headers).setUser(user).setError(error)
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
.createResponse(RequiredAction.UPDATE_PROFILE);
|
||||
}
|
||||
@@ -616,7 +618,7 @@ public class LoginActionsService {
|
||||
|
||||
// check for duplicated email
|
||||
if (userByEmail != null && !userByEmail.getId().equals(user.getId())) {
|
||||
return Flows.forms(session, realm, null, uriInfo).setUser(user).setError(Messages.EMAIL_EXISTS)
|
||||
return Flows.forms(session, realm, null, uriInfo, headers).setUser(user).setError(Messages.EMAIL_EXISTS)
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
.createResponse(RequiredAction.UPDATE_PROFILE);
|
||||
}
|
||||
@@ -655,7 +657,7 @@ public class LoginActionsService {
|
||||
String totp = formData.getFirst("totp");
|
||||
String totpSecret = formData.getFirst("totpSecret");
|
||||
|
||||
LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo).setUser(user);
|
||||
LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo, headers).setUser(user);
|
||||
if (Validation.isEmpty(totp)) {
|
||||
return loginForms.setError(Messages.MISSING_TOTP)
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
@@ -700,7 +702,7 @@ public class LoginActionsService {
|
||||
String passwordNew = formData.getFirst("password-new");
|
||||
String passwordConfirm = formData.getFirst("password-confirm");
|
||||
|
||||
LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo).setUser(user);
|
||||
LoginFormsProvider loginForms = Flows.forms(session, realm, null, uriInfo, headers).setUser(user);
|
||||
if (Validation.isEmpty(passwordNew)) {
|
||||
return loginForms.setError(Messages.MISSING_PASSWORD)
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
@@ -757,7 +759,7 @@ public class LoginActionsService {
|
||||
UserSessionModel userSession = clientSession.getUserSession();
|
||||
initEvent(clientSession);
|
||||
|
||||
return Flows.forms(session, realm, null, uriInfo)
|
||||
return Flows.forms(session, realm, null, uriInfo, headers)
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
.setUser(userSession.getUser())
|
||||
.createResponse(RequiredAction.VERIFY_EMAIL);
|
||||
@@ -775,11 +777,11 @@ public class LoginActionsService {
|
||||
}
|
||||
ClientSessionCode accessCode = checks.clientCode;
|
||||
accessCode.setRequiredAction(RequiredAction.UPDATE_PASSWORD);
|
||||
return Flows.forms(session, realm, null, uriInfo)
|
||||
return Flows.forms(session, realm, null, uriInfo, headers)
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
.createResponse(RequiredAction.UPDATE_PASSWORD);
|
||||
} else {
|
||||
return Flows.forms(session, realm, null, uriInfo)
|
||||
return Flows.forms(session, realm, null, uriInfo, headers)
|
||||
.setClientSessionCode(code)
|
||||
.createPasswordReset();
|
||||
}
|
||||
@@ -792,16 +794,16 @@ public class LoginActionsService {
|
||||
final MultivaluedMap<String, String> formData) {
|
||||
event.event(EventType.SEND_RESET_PASSWORD);
|
||||
if (!checkSsl()) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "HTTPS required", headers);
|
||||
}
|
||||
if (!realm.isEnabled()) {
|
||||
event.error(Errors.REALM_DISABLED);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Realm not enabled.", headers);
|
||||
}
|
||||
ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
|
||||
if (accessCode == null) {
|
||||
event.error(Errors.INVALID_CODE);
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.");
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo, "Unknown code, please login again through your application.", headers);
|
||||
}
|
||||
ClientSessionModel clientSession = accessCode.getClientSession();
|
||||
|
||||
@@ -810,11 +812,11 @@ public class LoginActionsService {
|
||||
ClientModel client = clientSession.getClient();
|
||||
if (client == null) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
|
||||
"Unknown login requester.");
|
||||
"Unknown login requester.", headers);
|
||||
}
|
||||
if (!client.isEnabled()) {
|
||||
return Flows.forwardToSecurityFailurePage(session, realm, uriInfo,
|
||||
"Login requester not enabled.");
|
||||
"Login requester not enabled.", headers);
|
||||
}
|
||||
|
||||
event.client(client.getClientId())
|
||||
@@ -857,13 +859,13 @@ public class LoginActionsService {
|
||||
} catch (EmailException e) {
|
||||
event.error(Errors.EMAIL_SEND_FAILED);
|
||||
logger.error("Failed to send password reset email", e);
|
||||
return Flows.forms(this.session, realm, client, uriInfo).setError("emailSendError")
|
||||
return Flows.forms(this.session, realm, client, uriInfo, headers).setError("emailSendError")
|
||||
.setClientSessionCode(accessCode.getCode())
|
||||
.createErrorPage();
|
||||
}
|
||||
}
|
||||
|
||||
return Flows.forms(session, realm, client, uriInfo).setSuccess("emailSent").setClientSessionCode(accessCode.getCode()).createPasswordReset();
|
||||
return Flows.forms(session, realm, client, uriInfo, headers).setSuccess("emailSent").setClientSessionCode(accessCode.getCode()).createPasswordReset();
|
||||
}
|
||||
|
||||
private Response redirectOauth(UserModel user, ClientSessionCode accessCode, ClientSessionModel clientSession, UserSessionModel userSession) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.keycloak.models.ClientModel;
|
||||
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.UriInfo;
|
||||
|
||||
@@ -37,16 +38,16 @@ public class Flows {
|
||||
private Flows() {
|
||||
}
|
||||
|
||||
public static LoginFormsProvider forms(KeycloakSession session, RealmModel realm, ClientModel client, UriInfo uriInfo) {
|
||||
return session.getProvider(LoginFormsProvider.class).setRealm(realm).setUriInfo(uriInfo).setClient(client);
|
||||
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, String message) {
|
||||
return Flows.forms(session, realm, null, uriInfo).setError(message).createErrorPage();
|
||||
public static Response forwardToSecurityFailurePage(KeycloakSession session, RealmModel realm, UriInfo uriInfo, String message, HttpHeaders headers) {
|
||||
return Flows.forms(session, realm, null, uriInfo, headers).setError(message).createErrorPage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user