commit
8121a9391f
16 files changed
+220
-248
No files matched your search
@@ -2,16 +2,15 @@ package org.keycloak.services;
|
||||
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.keycloak.ClientConnection;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakContext;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.utils.RealmImporter;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.keycloak.services.util.LocaleHelper;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
@@ -87,4 +86,9 @@ public class DefaultKeycloakContext implements KeycloakContext {
|
||||
manager.setContextPath(getContextPath());
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale resolveLocale(UserModel user) {
|
||||
return LocaleHelper.getLocale(session, realm, user);
|
||||
}
|
||||
}
|
||||
@@ -33,42 +33,24 @@ import org.keycloak.events.EventBuilder;
|
||||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.jose.jws.JWSBuilder;
|
||||
import org.keycloak.login.LoginFormsProvider;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.RequiredActionProviderModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.protocol.LoginProtocol;
|
||||
import org.keycloak.protocol.RestartLoginCookie;
|
||||
import org.keycloak.protocol.oidc.TokenManager;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.services.Urls;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
import org.keycloak.services.resources.IdentityBrokerService;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.services.Urls;
|
||||
import org.keycloak.services.util.CookieHelper;
|
||||
import org.keycloak.util.Time;
|
||||
|
||||
import javax.ws.rs.core.Cookie;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.core.NewCookie;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import javax.ws.rs.core.*;
|
||||
import java.net.URI;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import org.keycloak.freemarker.LocaleHelper;
|
||||
import org.keycloak.util.TokenUtil;
|
||||
|
||||
/**
|
||||
* Stateless object that manages authentication
|
||||
@@ -413,7 +395,8 @@ public class AuthenticationManager {
|
||||
}
|
||||
}
|
||||
|
||||
handleLoginLocale(realm, userSession, request, uriInfo);
|
||||
// Updates users locale if required
|
||||
session.getContext().resolveLocale(userSession.getUser());
|
||||
|
||||
// refresh the cookies!
|
||||
createLoginCookie(realm, userSession.getUser(), userSession, uriInfo, clientConnection);
|
||||
@@ -428,17 +411,6 @@ public class AuthenticationManager {
|
||||
|
||||
}
|
||||
|
||||
// If a locale has been set on the login screen, associate that locale with the user
|
||||
private static void handleLoginLocale(RealmModel realm, UserSessionModel userSession,
|
||||
HttpRequest request, UriInfo uriInfo) {
|
||||
Cookie localeCookie = request.getHttpHeaders().getCookies().get(LocaleHelper.LOCALE_COOKIE);
|
||||
if (localeCookie == null) return;
|
||||
|
||||
UserModel user = userSession.getUser();
|
||||
Locale locale = LocaleHelper.getLocale(realm, user, uriInfo, request.getHttpHeaders());
|
||||
user.setSingleAttribute(UserModel.LOCALE, locale.toLanguageTag());
|
||||
}
|
||||
|
||||
public static Response nextActionAfterAuthentication(KeycloakSession session, UserSessionModel userSession, ClientSessionModel clientSession,
|
||||
ClientConnection clientConnection,
|
||||
HttpRequest request, UriInfo uriInfo, EventBuilder event) {
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.services.util;
|
||||
|
||||
import org.jboss.resteasy.spi.HttpResponse;
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.util.ServerCookie;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
|
||||
*/
|
||||
public class LocaleHelper {
|
||||
|
||||
private static final String LOCALE_COOKIE = "KEYCLOAK_LOCALE";
|
||||
private static final String UI_LOCALES_PARAM = "ui_locales";
|
||||
private static final String KC_LOCALE_PARAM = "kc_locale";
|
||||
|
||||
public static Locale getLocale(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||
if (!realm.isInternationalizationEnabled()) {
|
||||
return Locale.ENGLISH;
|
||||
} else {
|
||||
Locale locale = getUserLocale(session, realm, user);
|
||||
return locale != null ? locale : Locale.forLanguageTag(realm.getDefaultLocale());
|
||||
}
|
||||
}
|
||||
|
||||
private static Locale getUserLocale(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||
UriInfo uriInfo = session.getContext().getUri();
|
||||
HttpHeaders httpHeaders = session.getContext().getRequestHeaders();
|
||||
|
||||
// kc_locale query parameter
|
||||
if (uriInfo != null && uriInfo.getQueryParameters().containsKey(KC_LOCALE_PARAM)) {
|
||||
String localeString = uriInfo.getQueryParameters().getFirst(KC_LOCALE_PARAM);
|
||||
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
||||
if (locale != null) {
|
||||
updateLocaleCookie(session, realm, localeString);
|
||||
if (user != null) {
|
||||
updateUsersLocale(user, localeString);
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
// User profile
|
||||
if (user != null && user.getAttributes().containsKey(UserModel.LOCALE)) {
|
||||
String localeString = user.getFirstAttribute(UserModel.LOCALE);
|
||||
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
||||
if (locale != null) {
|
||||
updateLocaleCookie(session, realm, localeString);
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
// Locale cookie
|
||||
if (httpHeaders != null && httpHeaders.getCookies().containsKey(LOCALE_COOKIE)) {
|
||||
String localeString = httpHeaders.getCookies().get(LOCALE_COOKIE).getValue();
|
||||
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
||||
if (locale != null) {
|
||||
if (user != null) {
|
||||
updateUsersLocale(user, localeString);
|
||||
}
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
// ui_locales query parameter
|
||||
if (uriInfo != null && uriInfo.getQueryParameters().containsKey(UI_LOCALES_PARAM)) {
|
||||
String localeString = uriInfo.getQueryParameters().getFirst(UI_LOCALES_PARAM);
|
||||
Locale locale = findLocale(realm.getSupportedLocales(), localeString.split(" "));
|
||||
if (locale != null) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
// Accept-Language http header
|
||||
if (httpHeaders != null && httpHeaders.getAcceptableLanguages() != null && !httpHeaders.getAcceptableLanguages().isEmpty()) {
|
||||
for (Locale l : httpHeaders.getAcceptableLanguages()) {
|
||||
String localeString = l.toLanguageTag();
|
||||
Locale locale = findLocale(realm.getSupportedLocales(), localeString);
|
||||
if (locale != null) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void updateLocaleCookie(KeycloakSession session,
|
||||
RealmModel realm,
|
||||
String locale) {
|
||||
boolean secure = realm.getSslRequired().isRequired(session.getContext().getUri().getRequestUri().getHost());
|
||||
addCookie(LOCALE_COOKIE, locale, AuthenticationManager.getRealmCookiePath(realm, session.getContext().getUri()), null, null, -1, secure, true);
|
||||
}
|
||||
|
||||
private static void addCookie(String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly) {
|
||||
HttpResponse response = ResteasyProviderFactory.getContextData(HttpResponse.class);
|
||||
StringBuffer cookieBuf = new StringBuffer();
|
||||
ServerCookie.appendCookieValue(cookieBuf, 1, name, value, path, domain, comment, maxAge, secure, httpOnly);
|
||||
String cookie = cookieBuf.toString();
|
||||
response.getOutputHeaders().add(HttpHeaders.SET_COOKIE, cookie);
|
||||
}
|
||||
|
||||
private static Locale findLocale(Set<String> supportedLocales, String... localeStrings) {
|
||||
for (String localeString : localeStrings) {
|
||||
Locale result = null;
|
||||
Locale search = Locale.forLanguageTag(localeString);
|
||||
for (String languageTag : supportedLocales) {
|
||||
Locale locale = Locale.forLanguageTag(languageTag);
|
||||
if (locale.getLanguage().equals(search.getLanguage())) {
|
||||
if (locale.getCountry().equals("") && result == null) {
|
||||
result = locale;
|
||||
}
|
||||
if (locale.getCountry().equals(search.getCountry())) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void updateUsersLocale(UserModel user, String locale) {
|
||||
if (!locale.equals(user.getFirstAttribute("locale"))) {
|
||||
user.setSingleAttribute(UserModel.LOCALE, locale);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user