Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Bill Burke committed 2014-05-17 14:24:37 -04:00
commit c2bf6c3822
100 files changed
+1414 -1383

No files matched your search

+1
View File
@@ -102,6 +102,7 @@
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
@@ -6,6 +6,8 @@ import org.keycloak.provider.ProviderSession;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -13,6 +15,7 @@ import java.util.Set;
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class DefaultProviderSession implements ProviderSession {
private DefaultProviderSessionFactory factory;
private Map<Integer, Provider> providers = new HashMap<Integer, Provider>();
@@ -21,8 +24,16 @@ public class DefaultProviderSession implements ProviderSession {
}
public <T extends Provider> T getProvider(Class<T> clazz) {
String id = factory.getDefaultProvider(clazz);
return id != null ? getProvider(clazz, id) : null;
Integer hash = clazz.hashCode();
T provider = (T) providers.get(hash);
if (provider == null) {
ProviderFactory<T> providerFactory = factory.getProviderFactory(clazz);
if (providerFactory != null) {
provider = providerFactory.create(this);
providers.put(hash, provider);
}
}
return provider;
}
public <T extends Provider> T getProvider(Class<T> clazz, String id) {
@@ -39,15 +50,14 @@ public class DefaultProviderSession implements ProviderSession {
}
public <T extends Provider> Set<String> listProviderIds(Class<T> clazz) {
return factory.providerIds(clazz);
return factory.getAllProviderIds(clazz);
}
@Override
public <T extends Provider> Set<T> getAllProviders(Class<T> clazz) {
Set<String> providerIds = listProviderIds(clazz);
Set<T> providers = new HashSet<T>();
for (String providerId : providerIds) {
providers.add(getProvider(clazz, providerId));
for (String id : listProviderIds(clazz)) {
providers.add(getProvider(clazz, id));
}
return providers;
}
@@ -1,71 +1,99 @@
package org.keycloak.services;
import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.ProviderFactoryLoader;
import org.keycloak.provider.ProviderSession;
import org.keycloak.provider.ProviderSessionFactory;
import org.keycloak.provider.Spi;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
public class DefaultProviderSessionFactory implements ProviderSessionFactory {
private Map<Class<? extends Provider>, ProviderFactoryLoader> loaders = new HashMap<Class<? extends Provider>, ProviderFactoryLoader>();
private Map<Class<? extends Provider>, String> defaultFactories = new HashMap<Class<? extends Provider>, String>();
private static final Logger log = Logger.getLogger(DefaultProviderSessionFactory.class);
private Map<Class<? extends Provider>, String> provider = new HashMap<Class<? extends Provider>, String>();
private Map<Class<? extends Provider>, Map<String, ProviderFactory>> factoriesMap = new HashMap<Class<? extends Provider>, Map<String, ProviderFactory>>();
public void init() {
for (Spi spi : ServiceLoader.load(Spi.class)) {
Map<String, ProviderFactory> factories = new HashMap<String, ProviderFactory>();
factoriesMap.put(spi.getProviderClass(), factories);
String provider = Config.getProvider(spi.getName());
if (provider != null) {
this.provider.put(spi.getProviderClass(), provider);
ProviderFactory factory = loadProviderFactory(spi, provider);
Config.Scope scope = Config.scope(spi.getName(), provider);
factory.init(scope);
log.debug("Initialized " + factory.getClass().getName() + " (config = " + scope + ")");
factories.put(factory.getId(), factory);
log.info("Loaded SPI " + spi.getName() + " (provider = " + provider + ")");
} else {
for (ProviderFactory factory : ServiceLoader.load(spi.getProviderFactoryClass())) {
Config.Scope scope = Config.scope(spi.getName(), factory.getId());
factory.init(scope);
log.debug("Initialized " + factory.getClass().getName() + " (config = " + scope + ")");
factories.put(factory.getId(), factory);
}
if (factories.size() == 1) {
provider = factories.values().iterator().next().getId();
this.provider.put(spi.getProviderClass(), provider);
log.info("Loaded SPI " + spi.getName() + " (provider = " + provider + ")");
} else {
log.info("Loaded SPI " + spi.getName() + " (providers = " + factories.keySet() + ")");
}
}
}
}
private ProviderFactory loadProviderFactory(Spi spi, String id) {
for (ProviderFactory factory : ServiceLoader.load(spi.getProviderFactoryClass())) {
if (factory.getId().equals(id)){
return factory;
}
}
throw new RuntimeException("Failed to find provider " + id + " for " + spi.getName());
}
public ProviderSession createSession() {
return new DefaultProviderSession(this);
}
<T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz) {
return getProviderFactory(clazz, provider.get(clazz));
}
<T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz, String id) {
return factoriesMap.get(clazz).get(id);
}
<T extends Provider> Set<String> getAllProviderIds(Class<T> clazz) {
Set<String> ids = new HashSet<String>();
for (ProviderFactory f : factoriesMap.get(clazz).values()) {
ids.add(f.getId());
}
return ids;
}
public void close() {
for (ProviderFactoryLoader loader : loaders.values()) {
loader.close();
for (Map<String, ProviderFactory> factories : factoriesMap.values()) {
for (ProviderFactory factory : factories.values()) {
factory.close();
}
}
}
public <T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz) {
String id = defaultFactories.get(clazz);
if (id == null) {
return null;
}
return getProviderFactory(clazz, id);
}
public <T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz, String id) {
ProviderFactoryLoader loader = getLoader(clazz);
return loader != null ? loader.find(id) : null;
}
public Set<String> providerIds(Class<? extends Provider> clazz) {
ProviderFactoryLoader loader = getLoader(clazz);
return loader != null ? loader.providerIds() : null;
}
public String getDefaultProvider(Class<? extends Provider> clazz) {
return defaultFactories.get(clazz);
}
public void registerLoader(Class<? extends Provider> clazz, ProviderFactoryLoader loader) {
loaders.put(clazz, loader);
}
public void registerLoader(Class<? extends Provider> clazz, ProviderFactoryLoader loader, String defaultProvider) {
loaders.put(clazz, loader);
defaultFactories.put(clazz, defaultProvider);
}
public void init() {
for (ProviderFactoryLoader l : loaders.values()) {
l.init();
}
}
private <T extends Provider> ProviderFactoryLoader getLoader(Class<T> clazz) {
return loaders.get(clazz);
}
}
@@ -32,9 +32,7 @@ public class KeycloakSessionServletFilter implements Filter {
ResteasyProviderFactory.pushContext(ProviderSession.class, providerSession);
KeycloakSessionFactory factory = (KeycloakSessionFactory) servletRequest.getServletContext().getAttribute(KeycloakSessionFactory.class.getName());
if (factory == null) throw new ServletException("Factory was null");
KeycloakSession session = factory.createSession();
KeycloakSession session = providerSession.getProvider(KeycloakSession.class);
ResteasyProviderFactory.pushContext(KeycloakSession.class, session);
KeycloakTransaction tx = session.getTransaction();
ResteasyProviderFactory.pushContext(KeycloakTransaction.class, tx);
@@ -56,7 +54,6 @@ public class KeycloakSessionServletFilter implements Filter {
if (tx.isActive()) tx.rollback();
throw ex;
} finally {
session.close();
providerSession.close();
ResteasyProviderFactory.clearContextData();
}
@@ -6,14 +6,15 @@ import org.jboss.logging.Logger;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.Config;
import org.keycloak.Config;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.provider.ProviderSession;
import org.keycloak.provider.ProviderSessionFactory;
import org.keycloak.representations.idm.CredentialRepresentation;
import java.util.Collections;
@@ -26,26 +27,25 @@ public class ApplianceBootstrap {
private static final Logger logger = Logger.getLogger(ApplianceBootstrap.class);
public void bootstrap(KeycloakSessionFactory factory, String contextPath) {
KeycloakSession session = factory.createSession();
public void bootstrap(ProviderSessionFactory factory, String contextPath) {
ProviderSession providerSession = factory.createSession();
KeycloakSession session = providerSession.getProvider(KeycloakSession.class);
session.getTransaction().begin();
try {
bootstrap(session, contextPath);
session.getTransaction().commit();
} finally {
session.close();
providerSession.close();
}
}
public void bootstrap(KeycloakSession session, String contextPath) {
if (session.getRealm(Config.getAdminRealm()) != null) {
String adminRealmName = Config.getAdminRealm();
if (session.getRealm(adminRealmName) != null) {
return;
}
String adminRealmName = Config.getAdminRealm();
logger.info("Initializing " + adminRealmName + " realm");
RealmManager manager = new RealmManager(session);
@@ -6,6 +6,8 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UsernameLoginFailureModel;
import org.keycloak.provider.ProviderSession;
import org.keycloak.provider.ProviderSessionFactory;
import org.keycloak.services.ClientConnection;
import java.util.ArrayList;
@@ -25,7 +27,7 @@ public class BruteForceProtector implements Runnable {
protected volatile boolean run = true;
protected int maxDeltaTimeSeconds = 60 * 60 * 12; // 12 hours
protected KeycloakSessionFactory factory;
protected ProviderSessionFactory factory;
protected CountDownLatch shutdownLatch = new CountDownLatch(1);
protected volatile long failures;
@@ -73,7 +75,7 @@ public class BruteForceProtector implements Runnable {
}
}
public BruteForceProtector(KeycloakSessionFactory factory) {
public BruteForceProtector(ProviderSessionFactory factory) {
this.factory = factory;
}
@@ -160,7 +162,8 @@ public class BruteForceProtector implements Runnable {
events.add(take);
queue.drainTo(events, TRANSACTION_SIZE);
Collections.sort(events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking this.
KeycloakSession session = factory.createSession();
ProviderSession providerSession = factory.createSession();
KeycloakSession session = providerSession.getProvider(KeycloakSession.class);
session.getTransaction().begin();
try {
for (LoginEvent event : events) {
@@ -179,7 +182,7 @@ public class BruteForceProtector implements Runnable {
}
}
events.clear();
session.close();
providerSession.close();
}
} catch (Exception e) {
logger.error("Failed processing event", e);
@@ -7,7 +7,7 @@ import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.AuthenticationProviderModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Config;
import org.keycloak.Config;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
@@ -1,5 +1,7 @@
package org.keycloak.services.resources;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -8,7 +10,7 @@ import javax.ws.rs.core.Response.ResponseBuilder;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.models.ClientModel;
import org.keycloak.models.UserModel;
import org.keycloak.util.CollectionUtil;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -16,20 +18,25 @@ import org.keycloak.models.UserModel;
public class Cors {
public static final long DEFAULT_MAX_AGE = TimeUnit.HOURS.toSeconds(1);
public static final String DEFAULT_ALLOW_METHODS = "GET, OPTIONS";
public static final String DEFAULT_ALLOW_METHODS = "GET, HEAD, OPTIONS";
public static final String DEFAULT_ALLOW_HEADERS = "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers";
public static final String ORIGIN = "Origin";
public static final String ORIGIN_HEADER = "Origin";
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
public static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
public static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
public static final String ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
public static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
public static final String ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age";
private HttpRequest request;
private ResponseBuilder response;
private Set<String> allowedOrigins;
private String[] allowedMethods;
private Set<String> allowedMethods;
private Set<String> exposedHeaders;
private boolean preflight;
private boolean auth;
@@ -61,12 +68,17 @@ public class Cors {
}
public Cors allowedMethods(String... allowedMethods) {
this.allowedMethods = allowedMethods;
this.allowedMethods = new HashSet<String>(Arrays.asList(allowedMethods));
return this;
}
public Cors exposedHeaders(String... exposedHeaders) {
this.exposedHeaders = new HashSet<String>(Arrays.asList(exposedHeaders));
return this;
}
public Response build() {
String origin = request.getHttpHeaders().getRequestHeaders().getFirst(ORIGIN);
String origin = request.getHttpHeaders().getRequestHeaders().getFirst(ORIGIN_HEADER);
if (origin == null) {
return response.build();
}
@@ -78,21 +90,20 @@ public class Cors {
response.header(ACCESS_CONTROL_ALLOW_ORIGIN, origin);
if (allowedMethods != null) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < allowedMethods.length; i++) {
if (i > 0) {
sb.append(", ");
}
sb.append(allowedMethods[i]);
}
response.header(ACCESS_CONTROL_ALLOW_METHODS, sb.toString());
response.header(ACCESS_CONTROL_ALLOW_METHODS, CollectionUtil.join(allowedMethods));
} else {
response.header(ACCESS_CONTROL_ALLOW_METHODS, DEFAULT_ALLOW_METHODS);
}
if (exposedHeaders != null) {
response.header(ACCESS_CONTROL_EXPOSE_HEADERS, CollectionUtil.join(exposedHeaders));
}
response.header(ACCESS_CONTROL_ALLOW_CREDENTIALS, Boolean.toString(auth));
if (auth) {
response.header(ACCESS_CONTROL_ALLOW_HEADERS, "Authorization");
response.header(ACCESS_CONTROL_ALLOW_HEADERS, String.format("%s, %s", DEFAULT_ALLOW_HEADERS, AUTHORIZATION_HEADER));
} else {
response.header(ACCESS_CONTROL_ALLOW_HEADERS, DEFAULT_ALLOW_HEADERS);
}
response.header(ACCESS_CONTROL_MAX_AGE, DEFAULT_MAX_AGE);
@@ -1,39 +1,30 @@
package org.keycloak.services.resources;
import org.jboss.resteasy.core.Dispatcher;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.jboss.logging.Logger;
import org.jboss.resteasy.core.Dispatcher;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.Config;
import org.keycloak.SkeletonKeyContextResolver;
import org.keycloak.audit.AuditListener;
import org.keycloak.audit.AuditListenerFactory;
import org.keycloak.audit.AuditProvider;
import org.keycloak.audit.AuditProviderFactory;
import org.keycloak.authentication.AuthenticationProvider;
import org.keycloak.authentication.AuthenticationProviderFactory;
import org.keycloak.exportimport.ExportImportProvider;
import org.keycloak.models.Config;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ModelProvider;
import org.keycloak.models.RealmModel;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.ProviderFactoryLoader;
import org.keycloak.provider.ProviderSession;
import org.keycloak.provider.ProviderSessionFactory;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.DefaultProviderSessionFactory;
import org.keycloak.provider.ProviderSessionFactory;
import org.keycloak.services.managers.ApplianceBootstrap;
import org.keycloak.services.managers.BruteForceProtector;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.SocialRequestManager;
import org.keycloak.services.managers.TokenManager;
import org.keycloak.services.resources.admin.AdminRoot;
import org.keycloak.models.utils.ModelProviderUtils;
import org.keycloak.services.scheduled.ClearExpiredAuditEvents;
import org.keycloak.services.scheduled.ClearExpiredUserSessions;
import org.keycloak.services.scheduled.ScheduledTaskRunner;
import org.keycloak.services.util.JsonConfigProvider;
import org.keycloak.timer.TimerProvider;
import org.keycloak.timer.TimerProviderFactory;
import org.keycloak.util.JsonSerialization;
import org.keycloak.util.ProviderLoader;
@@ -41,12 +32,13 @@ import javax.servlet.ServletContext;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Date;
import java.net.URL;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
@@ -63,22 +55,21 @@ public class KeycloakApplication extends Application {
protected Set<Object> singletons = new HashSet<Object>();
protected Set<Class<?>> classes = new HashSet<Class<?>>();
protected KeycloakSessionFactory factory;
protected ProviderSessionFactory providerSessionFactory;
protected String contextPath;
public KeycloakApplication(@Context ServletContext context, @Context Dispatcher dispatcher) {
loadConfig();
this.providerSessionFactory = createProviderSessionFactory();
dispatcher.getDefaultContextObjects().put(KeycloakApplication.class, this);
this.contextPath = context.getContextPath();
this.factory = createSessionFactory();
BruteForceProtector protector = new BruteForceProtector(factory);
BruteForceProtector protector = new BruteForceProtector(providerSessionFactory);
dispatcher.getDefaultContextObjects().put(BruteForceProtector.class, protector);
ResteasyProviderFactory.pushContext(BruteForceProtector.class, protector); // for injection
protector.start();
context.setAttribute(BruteForceProtector.class.getName(), protector);
this.providerSessionFactory = createProviderSessionFactory();
context.setAttribute(KeycloakSessionFactory.class.getName(), factory);
context.setAttribute(ProviderSessionFactory.class.getName(), this.providerSessionFactory);
TokenManager tokenManager = new TokenManager();
@@ -95,7 +86,7 @@ public class KeycloakApplication extends Application {
setupDefaultRealm(context.getContextPath());
setupScheduledTasks(providerSessionFactory, factory);
setupScheduledTasks(providerSessionFactory);
importRealms(context);
checkExportImportProvider();
@@ -115,55 +106,38 @@ public class KeycloakApplication extends Application {
return uriInfo.getBaseUriBuilder().replacePath(getContextPath()).build();
}
protected void setupDefaultRealm(String contextPath) {
new ApplianceBootstrap().bootstrap(factory, contextPath);
protected void loadConfig() {
try {
URL config = Thread.currentThread().getContextClassLoader().getResource("META-INF/keycloak-server.json");
if (config != null) {
JsonNode node = new ObjectMapper().readTree(config);
Config.init(new JsonConfigProvider(node));
log.info("Loaded config from " + config);
return;
}
} catch (IOException e) {
throw new RuntimeException("Failed to load config", e);
}
}
public static KeycloakSessionFactory createSessionFactory() {
ModelProvider provider = ModelProviderUtils.getConfiguredModelProvider();
if (provider != null) {
log.debug("Model provider: " + provider.getId());
return provider.createFactory();
}
throw new RuntimeException("Model provider not found");
protected void setupDefaultRealm(String contextPath) {
new ApplianceBootstrap().bootstrap(providerSessionFactory, contextPath);
}
public static DefaultProviderSessionFactory createProviderSessionFactory() {
DefaultProviderSessionFactory factory = new DefaultProviderSessionFactory();
factory.registerLoader(AuditProvider.class, ProviderFactoryLoader.create(AuditProviderFactory.class), Config.getAuditProvider());
factory.registerLoader(AuditListener.class, ProviderFactoryLoader.create(AuditListenerFactory.class));
factory.registerLoader(TimerProvider.class, ProviderFactoryLoader.create(TimerProviderFactory.class), Config.getTimerProvider());
try {
Class identityManagerProvider = Class.forName("org.keycloak.picketlink.IdentityManagerProvider");
Class identityManagerProviderFactory = Class.forName("org.keycloak.picketlink.IdentityManagerProviderFactory");
factory.registerLoader(identityManagerProvider, ProviderFactoryLoader.create(identityManagerProviderFactory), Config.getIdentityManagerProvider());
} catch (ClassNotFoundException e) {
log.warn("Picketlink libraries not installed for IdentityManagerProviderFactory");
}
factory.registerLoader(AuthenticationProvider.class, ProviderFactoryLoader.create(AuthenticationProviderFactory.class));
factory.init();
return factory;
}
public static void setupScheduledTasks(final ProviderSessionFactory providerSessionFactory, final KeycloakSessionFactory keycloakSessionFactory) {
ProviderFactory<TimerProvider> timerFactory = providerSessionFactory.getProviderFactory(TimerProvider.class);
if (timerFactory == null) {
log.error("Can't setup schedule tasks, no timer provider found");
return;
}
TimerProvider timer = timerFactory.create(null);
timer.schedule(new ScheduledTaskRunner(keycloakSessionFactory, providerSessionFactory, new ClearExpiredAuditEvents()), Config.getAuditExpirationSchedule());
timer.schedule(new ScheduledTaskRunner(keycloakSessionFactory, providerSessionFactory, new ClearExpiredUserSessions()), Config.getUserExpirationSchedule());
}
public static void setupScheduledTasks(final ProviderSessionFactory providerSessionFactory) {
long interval = Config.scope("scheduled").getLong("interval") * 1000;
public KeycloakSessionFactory getFactory() {
return factory;
TimerProvider timer = providerSessionFactory.createSession().getProvider(TimerProvider.class);
timer.schedule(new ScheduledTaskRunner(providerSessionFactory, new ClearExpiredAuditEvents()), interval);
timer.schedule(new ScheduledTaskRunner(providerSessionFactory, new ClearExpiredUserSessions()), interval);
}
public ProviderSessionFactory getProviderSessionFactory() {
@@ -215,7 +189,8 @@ public class KeycloakApplication extends Application {
}
public void importRealm(RealmRepresentation rep, String from) {
KeycloakSession session = factory.createSession();
ProviderSession providerSession = providerSessionFactory.createSession();
KeycloakSession session = providerSession.getProvider(KeycloakSession.class);
try {
session.getTransaction().begin();
RealmManager manager = new RealmManager(session);
@@ -238,7 +213,7 @@ public class KeycloakApplication extends Application {
session.getTransaction().commit();
} finally {
session.close();
providerSession.close();
}
}
@@ -255,7 +230,7 @@ public class KeycloakApplication extends Application {
if (providers.hasNext()) {
ExportImportProvider exportImport = providers.next();
exportImport.checkExportImport(factory);
exportImport.checkExportImport(providerSessionFactory);
} else {
log.warn("No ExportImportProvider found!");
}
@@ -125,8 +125,7 @@ public class TokenService {
}
public static UriBuilder tokenServiceBaseUrl(UriBuilder baseUriBuilder) {
UriBuilder base = baseUriBuilder.path(RealmsResource.class).path(RealmsResource.class, "getTokenService");
return base;
return baseUriBuilder.path(RealmsResource.class).path(RealmsResource.class, "getTokenService");
}
public static UriBuilder accessCodeToTokenUrl(UriInfo uriInfo) {
@@ -295,7 +294,7 @@ public class TokenService {
ClientModel client = authorizeClient(authorizationHeader, form, audit);
String refreshToken = form.getFirst(OAuth2Constants.REFRESH_TOKEN);
AccessToken accessToken = null;
AccessToken accessToken;
try {
accessToken = tokenManager.refreshAccessToken(uriInfo, realm, client, refreshToken, audit);
} catch (OAuthErrorException e) {
@@ -314,7 +313,7 @@ public class TokenService {
audit.success();
return Cors.add(request, Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).auth().allowedOrigins(client).allowedMethods("POST").build();
return Cors.add(request, Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).auth().allowedOrigins(client).allowedMethods("POST").exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS).build();
}
@Path("auth/request/login")
@@ -502,7 +501,7 @@ public class TokenService {
credentials.setValue(formData.getFirst("password"));
boolean passwordUpdateSuccessful;
String passwordUpdateError = null;
String passwordUpdateError;
try {
passwordUpdateSuccessful = AuthenticationProviderManager.getManager(realm, providerSession).updatePassword(user, formData.getFirst("password"));
passwordUpdateError = "Password update failed";
@@ -658,12 +657,12 @@ public class TokenService {
audit.success();
return Cors.add(request, Response.ok(res)).auth().allowedOrigins(client).allowedMethods("POST").build();
return Cors.add(request, Response.ok(res)).auth().allowedOrigins(client).allowedMethods("POST").exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS).build();
}
protected ClientModel authorizeClient(String authorizationHeader, MultivaluedMap<String, String> formData, Audit audit) {
String client_id = null;
String clientSecret = null;
String client_id;
String clientSecret;
if (authorizationHeader != null) {
String[] usernameSecret = BasicAuthHelper.parseHeader(authorizationHeader);
if (usernameSecret == null) {
@@ -1008,11 +1007,7 @@ public class TokenService {
}
private boolean checkSsl() {
if (realm.isSslNotRequired()) {
return true;
}
return uriInfo.getBaseUri().getScheme().equals("https");
return realm.isSslNotRequired() || uriInfo.getBaseUri().getScheme().equals("https");
}
}
@@ -10,14 +10,12 @@ import org.keycloak.freemarker.Theme;
import org.keycloak.freemarker.ThemeLoader;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Config;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.provider.ProviderSession;
import org.keycloak.services.ForbiddenException;
import org.keycloak.services.managers.AppAuthManager;
import org.keycloak.services.managers.ApplicationManager;
import org.keycloak.services.managers.RealmManager;
@@ -280,12 +278,7 @@ public class AdminConsole {
try {
//logger.info("getting resource: " + path + " uri: " + uriInfo.getRequestUri().toString());
String themeName = realm.getAdminTheme();
if (themeName == null || themeName.trim().equals("")) {
themeName = Config.getThemeAdmin();
}
Theme theme = ThemeLoader.createTheme(themeName, Theme.Type.ADMIN);
Theme theme = ThemeLoader.createTheme(realm.getAdminTheme(), Theme.Type.ADMIN);
InputStream resource = theme.getResourceAsStream(path);
if (resource != null) {
String contentType = mimeTypes.getContentType(path);
@@ -13,20 +13,18 @@ public class ScheduledTaskRunner implements Runnable {
private static final Logger logger = Logger.getLogger(ScheduledTaskRunner.class);
private final KeycloakSessionFactory keycloakSessionFactory;
private final ProviderSessionFactory providerSessionFactory;
private final ScheduledTask task;
public ScheduledTaskRunner(KeycloakSessionFactory keycloakSessionFactory, ProviderSessionFactory providerSessionFactory, ScheduledTask task) {
this.keycloakSessionFactory = keycloakSessionFactory;
public ScheduledTaskRunner(ProviderSessionFactory providerSessionFactory, ScheduledTask task) {
this.providerSessionFactory = providerSessionFactory;
this.task = task;
}
@Override
public void run() {
KeycloakSession keycloakSession = keycloakSessionFactory.createSession();
ProviderSession providerSession = providerSessionFactory.createSession();
KeycloakSession keycloakSession = providerSession.getProvider(KeycloakSession.class);
try {
keycloakSession.getTransaction().begin();
task.run(keycloakSession, providerSession);
@@ -38,11 +36,6 @@ public class ScheduledTaskRunner implements Runnable {
keycloakSession.getTransaction().rollback();
} finally {
try {
keycloakSession.close();
} catch (Throwable t) {
logger.error("Failed to close KeycloakSession", t);
}
try {
providerSession.close();
} catch (Throwable t) {
@@ -0,0 +1,129 @@
package org.keycloak.services.util;
import org.codehaus.jackson.JsonNode;
import org.keycloak.Config;
import org.keycloak.util.StringPropertyReplacer;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class JsonConfigProvider implements Config.ConfigProvider {
private JsonNode config;
public JsonConfigProvider(JsonNode config) {
this.config = config;
}
@Override
public String getProvider(String spi) {
JsonNode n = getNode(spi, "provider");
return n != null ? StringPropertyReplacer.replaceProperties(n.getTextValue()) : null;
}
@Override
public Config.Scope scope(String... path) {
return new JsonScope(getNode(path));
}
private JsonNode getNode(String... path) {
JsonNode n = config;
for (String p : path) {
n = n.get(p);
if (n == null) {
return null;
}
}
return n;
}
public class JsonScope implements Config.Scope {
private JsonNode config;
public JsonScope(JsonNode config) {
this.config = config;
}
@Override
public String get(String key) {
return get(key, null);
}
@Override
public String get(String key, String defaultValue) {
if (config == null) {
return defaultValue;
}
JsonNode n = config.get(key);
if (n == null) {
return defaultValue;
}
return StringPropertyReplacer.replaceProperties(n.getTextValue());
}
@Override
public Integer getInt(String key) {
return getInt(key, null);
}
@Override
public Integer getInt(String key, Integer defaultValue) {
if (config == null) {
return defaultValue;
}
JsonNode n = config.get(key);
if (n == null) {
return defaultValue;
}
if (n.isTextual()) {
return Integer.parseInt(StringPropertyReplacer.replaceProperties(n.getTextValue()));
} else {
return n.getIntValue();
}
}
@Override
public Long getLong(String key) {
return getLong(key, null);
}
@Override
public Long getLong(String key, Long defaultValue) {
if (config == null) {
return defaultValue;
}
JsonNode n = config.get(key);
if (n == null) {
return defaultValue;
}
if (n.isTextual()) {
return Long.parseLong(StringPropertyReplacer.replaceProperties(n.getTextValue()));
} else {
return n.getLongValue();
}
}
@Override
public Boolean getBoolean(String key) {
return getBoolean(key, null);
}
@Override
public Boolean getBoolean(String key, Boolean defaultValue) {
if (config == null) {
return defaultValue;
}
JsonNode n = config.get(key);
if (n == null) {
return defaultValue;
}
if (n.isTextual()) {
return Boolean.parseBoolean(StringPropertyReplacer.replaceProperties(n.getTextValue()));
} else {
return n.getBooleanValue();
}
}
}
}