application refactor
This commit is contained in:
parent
562f6703b6
commit
2d1dc4a874
5 changed files with 99 additions and 188 deletions
|
@ -1,84 +0,0 @@
|
||||||
package org.keycloak.server;
|
|
||||||
|
|
||||||
import org.jboss.resteasy.core.Dispatcher;
|
|
||||||
import org.jboss.resteasy.logging.Logger;
|
|
||||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
|
||||||
import org.keycloak.models.Config;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.services.resources.KeycloakApplication;
|
|
||||||
import org.keycloak.util.JsonSerialization;
|
|
||||||
import org.keycloak.util.KeycloakUriBuilder;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.ws.rs.core.Context;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class KeycloakServerApplication extends KeycloakApplication {
|
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(KeycloakServerApplication.class);
|
|
||||||
|
|
||||||
public KeycloakServerApplication(@Context ServletContext servletContext,@Context Dispatcher dispatcher) throws FileNotFoundException {
|
|
||||||
super(servletContext, dispatcher);
|
|
||||||
KeycloakSession session = factory.createSession();
|
|
||||||
session.getTransaction().begin();
|
|
||||||
try {
|
|
||||||
InputStream is = servletContext.getResourceAsStream("/WEB-INF/testrealm.json");
|
|
||||||
RealmRepresentation rep = loadJson(is, RealmRepresentation.class);
|
|
||||||
RealmModel realm = importRealm(session, rep);
|
|
||||||
AdapterDeploymentContext deploymentContext = (AdapterDeploymentContext)servletContext.getAttribute(AdapterDeploymentContext.class.getName());
|
|
||||||
AdapterConfig adapterConfig = new AdapterConfig();
|
|
||||||
String host = (String)servletContext.getInitParameter("host-port");
|
|
||||||
String uri = KeycloakUriBuilder.fromUri("http://" + host).path(servletContext.getContextPath()).build().toString();
|
|
||||||
log.info("**** auth server url: " + uri);
|
|
||||||
adapterConfig.setRealm("demo");
|
|
||||||
adapterConfig.setResource("customer-portal");
|
|
||||||
adapterConfig.setRealmKey(realm.getPublicKeyPem());
|
|
||||||
Map<String, String> creds = new HashMap<String, String>();
|
|
||||||
creds.put(CredentialRepresentation.SECRET, "password");
|
|
||||||
adapterConfig.setCredentials(creds);
|
|
||||||
adapterConfig.setAuthServerUrl(uri);
|
|
||||||
adapterConfig.setSslNotRequired(true);
|
|
||||||
deploymentContext.updateDeployment(adapterConfig);
|
|
||||||
session.getTransaction().commit();
|
|
||||||
} finally {
|
|
||||||
session.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public RealmModel importRealm(KeycloakSession session, RealmRepresentation rep) {
|
|
||||||
RealmManager manager = new RealmManager(session);
|
|
||||||
|
|
||||||
RealmModel realm = manager.getRealmByName(rep.getRealm());
|
|
||||||
if (realm != null) {
|
|
||||||
log.info("Not importing realm " + rep.getRealm() + " realm already exists");
|
|
||||||
return realm;
|
|
||||||
}
|
|
||||||
|
|
||||||
realm = manager.createRealm(rep.getId(), rep.getRealm());
|
|
||||||
manager.importRealm(rep, realm);
|
|
||||||
|
|
||||||
log.info("Imported realm " + realm.getName());
|
|
||||||
return realm;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> T loadJson(InputStream is, Class<T> type) {
|
|
||||||
try {
|
|
||||||
return JsonSerialization.readValue(is, type);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Failed to parse json", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -10,16 +10,21 @@
|
||||||
<param-value>localhost:8080</param-value>
|
<param-value>localhost:8080</param-value>
|
||||||
</context-param>
|
</context-param>
|
||||||
|
|
||||||
|
<context-param>
|
||||||
|
<param-name>keycloak.import.realm.resources</param-name>
|
||||||
|
<param-value>/WEB-INF/testrealm.json</param-value>
|
||||||
|
</context-param>
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>Keycloak REST Interface</servlet-name>
|
<servlet-name>Keycloak REST Interface</servlet-name>
|
||||||
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher</servlet-class>
|
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher</servlet-class>
|
||||||
<init-param>
|
<init-param>
|
||||||
<param-name>javax.ws.rs.Application</param-name>
|
<param-name>javax.ws.rs.Application</param-name>
|
||||||
<param-value>org.keycloak.server.KeycloakServerApplication</param-value>
|
<param-value>org.keycloak.services.resources.KeycloakApplication</param-value>
|
||||||
</init-param>
|
</init-param>
|
||||||
<init-param>
|
<init-param>
|
||||||
<param-name>resteasy.servlet.mapping.prefix</param-name>
|
<param-name>resteasy.servlet.mapping.prefix</param-name>
|
||||||
<param-value>/rest</param-value>
|
<param-value>/</param-value>
|
||||||
</init-param>
|
</init-param>
|
||||||
<load-on-startup>1</load-on-startup>
|
<load-on-startup>1</load-on-startup>
|
||||||
<async-supported>true</async-supported>
|
<async-supported>true</async-supported>
|
||||||
|
@ -40,19 +45,10 @@
|
||||||
<async-supported>true</async-supported>
|
<async-supported>true</async-supported>
|
||||||
</servlet>
|
</servlet>
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>TmpAdminRedirectServlet</servlet-name>
|
|
||||||
<servlet-class>org.keycloak.services.tmp.TmpAdminRedirectServlet</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<listener>
|
<listener>
|
||||||
<listener-class>org.keycloak.services.listeners.KeycloakSessionDestroyListener</listener-class>
|
<listener-class>org.keycloak.services.listeners.KeycloakSessionDestroyListener</listener-class>
|
||||||
</listener>
|
</listener>
|
||||||
|
|
||||||
<welcome-file-list>
|
|
||||||
<welcome-file>index.html</welcome-file>
|
|
||||||
</welcome-file-list>
|
|
||||||
|
|
||||||
<filter>
|
<filter>
|
||||||
<filter-name>Keycloak Client Connection Filter</filter-name>
|
<filter-name>Keycloak Client Connection Filter</filter-name>
|
||||||
<filter-class>org.keycloak.services.filters.ClientConnectionFilter</filter-class>
|
<filter-class>org.keycloak.services.filters.ClientConnectionFilter</filter-class>
|
||||||
|
@ -75,32 +71,22 @@
|
||||||
|
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>Keycloak REST Interface</servlet-name>
|
<servlet-name>Keycloak REST Interface</servlet-name>
|
||||||
<url-pattern>/rest/*</url-pattern>
|
<url-pattern>/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
|
||||||
|
<welcome-file-list>
|
||||||
|
<welcome-file>index.html</welcome-file>
|
||||||
|
</welcome-file-list>
|
||||||
|
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>Customer REST Interface</servlet-name>
|
<servlet-name>Customer REST Interface</servlet-name>
|
||||||
<url-pattern>/database/*</url-pattern>
|
<url-pattern>/database/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>TmpAdminRedirectServlet</servlet-name>
|
|
||||||
<url-pattern>/admin</url-pattern>
|
|
||||||
<url-pattern>/admin/</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
<security-constraint>
|
|
||||||
<web-resource-collection>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</web-resource-collection>
|
|
||||||
<user-data-constraint>
|
|
||||||
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
|
||||||
</user-data-constraint>
|
|
||||||
</security-constraint>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<security-constraint>
|
<security-constraint>
|
||||||
<web-resource-collection>
|
<web-resource-collection>
|
||||||
<web-resource-name>Customers</web-resource-name>
|
<web-resource-name>Customers</web-resource-name>
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
package org.keycloak.server;
|
|
||||||
|
|
||||||
import org.jboss.resteasy.core.Dispatcher;
|
|
||||||
import org.jboss.resteasy.logging.Logger;
|
|
||||||
import org.keycloak.models.Config;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.services.resources.KeycloakApplication;
|
|
||||||
import org.keycloak.util.JsonSerialization;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.ws.rs.core.Context;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
public class KeycloakServerApplication extends KeycloakApplication {
|
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(KeycloakServerApplication.class);
|
|
||||||
|
|
||||||
public KeycloakServerApplication(@Context ServletContext servletContext, @Context Dispatcher dispatcher) throws FileNotFoundException {
|
|
||||||
super(servletContext, dispatcher);
|
|
||||||
|
|
||||||
String importRealm = System.getProperty("keycloak.import");
|
|
||||||
if (importRealm != null) {
|
|
||||||
KeycloakSession session = factory.createSession();
|
|
||||||
session.getTransaction().begin();
|
|
||||||
RealmRepresentation rep = loadJson(new FileInputStream(importRealm), RealmRepresentation.class);
|
|
||||||
importRealm(session, rep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void importRealm(KeycloakSession session, RealmRepresentation rep) {
|
|
||||||
try {
|
|
||||||
RealmManager manager = new RealmManager(session);
|
|
||||||
|
|
||||||
if (rep.getId() != null && manager.getRealm(rep.getId()) != null) {
|
|
||||||
log.info("Not importing realm " + rep.getRealm() + " realm already exists");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (manager.getRealmByName(rep.getRealm()) != null) {
|
|
||||||
log.info("Not importing realm " + rep.getRealm() + " realm already exists");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RealmModel realm = manager.createRealm(rep.getId(), rep.getRealm());
|
|
||||||
manager.importRealm(rep, realm);
|
|
||||||
|
|
||||||
log.info("Imported realm " + realm.getName());
|
|
||||||
|
|
||||||
session.getTransaction().commit();
|
|
||||||
} finally {
|
|
||||||
session.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> T loadJson(InputStream is, Class<T> type) {
|
|
||||||
try {
|
|
||||||
return JsonSerialization.readValue(is, type);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Failed to parse json", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -7,11 +7,11 @@
|
||||||
<module-name>auth</module-name>
|
<module-name>auth</module-name>
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>Resteasy</servlet-name>
|
<servlet-name>Keycloak REST Interface</servlet-name>
|
||||||
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher</servlet-class>
|
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher</servlet-class>
|
||||||
<init-param>
|
<init-param>
|
||||||
<param-name>javax.ws.rs.Application</param-name>
|
<param-name>javax.ws.rs.Application</param-name>
|
||||||
<param-value>org.keycloak.server.KeycloakServerApplication</param-value>
|
<param-value>org.keycloak.services.resources.KeycloakApplication</param-value>
|
||||||
</init-param>
|
</init-param>
|
||||||
<init-param>
|
<init-param>
|
||||||
<param-name>resteasy.servlet.mapping.prefix</param-name>
|
<param-name>resteasy.servlet.mapping.prefix</param-name>
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
</filter-mapping>
|
</filter-mapping>
|
||||||
|
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>Resteasy</servlet-name>
|
<servlet-name>Keycloak REST Interface</servlet-name>
|
||||||
<url-pattern>/*</url-pattern>
|
<url-pattern>/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
|
|
@ -18,27 +18,35 @@ import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.ProviderFactory;
|
||||||
import org.keycloak.provider.ProviderFactoryLoader;
|
import org.keycloak.provider.ProviderFactoryLoader;
|
||||||
import org.keycloak.provider.ProviderSession;
|
import org.keycloak.provider.ProviderSession;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.services.DefaultProviderSessionFactory;
|
import org.keycloak.services.DefaultProviderSessionFactory;
|
||||||
import org.keycloak.picketlink.IdentityManagerProvider;
|
import org.keycloak.picketlink.IdentityManagerProvider;
|
||||||
import org.keycloak.picketlink.IdentityManagerProviderFactory;
|
import org.keycloak.picketlink.IdentityManagerProviderFactory;
|
||||||
import org.keycloak.provider.ProviderSessionFactory;
|
import org.keycloak.provider.ProviderSessionFactory;
|
||||||
import org.keycloak.services.managers.ApplianceBootstrap;
|
import org.keycloak.services.managers.ApplianceBootstrap;
|
||||||
import org.keycloak.services.managers.BruteForceProtector;
|
import org.keycloak.services.managers.BruteForceProtector;
|
||||||
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.managers.SocialRequestManager;
|
import org.keycloak.services.managers.SocialRequestManager;
|
||||||
import org.keycloak.services.managers.TokenManager;
|
import org.keycloak.services.managers.TokenManager;
|
||||||
import org.keycloak.services.resources.admin.AdminService;
|
import org.keycloak.services.resources.admin.AdminService;
|
||||||
import org.keycloak.models.utils.ModelProviderUtils;
|
import org.keycloak.models.utils.ModelProviderUtils;
|
||||||
import org.keycloak.timer.TimerProvider;
|
import org.keycloak.timer.TimerProvider;
|
||||||
import org.keycloak.timer.TimerProviderFactory;
|
import org.keycloak.timer.TimerProviderFactory;
|
||||||
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -66,7 +74,6 @@ public class KeycloakApplication extends Application {
|
||||||
context.setAttribute(BruteForceProtector.class.getName(), protector);
|
context.setAttribute(BruteForceProtector.class.getName(), protector);
|
||||||
this.providerSessionFactory = createProviderSessionFactory();
|
this.providerSessionFactory = createProviderSessionFactory();
|
||||||
context.setAttribute(KeycloakSessionFactory.class.getName(), factory);
|
context.setAttribute(KeycloakSessionFactory.class.getName(), factory);
|
||||||
//classes.add(KeycloakSessionCleanupFilter.class);
|
|
||||||
|
|
||||||
context.setAttribute(ProviderSessionFactory.class.getName(), this.providerSessionFactory);
|
context.setAttribute(ProviderSessionFactory.class.getName(), this.providerSessionFactory);
|
||||||
|
|
||||||
|
@ -86,6 +93,7 @@ public class KeycloakApplication extends Application {
|
||||||
setupDefaultRealm(context.getContextPath());
|
setupDefaultRealm(context.getContextPath());
|
||||||
|
|
||||||
setupScheduledTasks(providerSessionFactory, factory);
|
setupScheduledTasks(providerSessionFactory, factory);
|
||||||
|
importRealms(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContextPath() {
|
public String getContextPath() {
|
||||||
|
@ -184,4 +192,75 @@ public class KeycloakApplication extends Application {
|
||||||
return singletons;
|
return singletons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void importRealms(ServletContext context) {
|
||||||
|
importRealmFile();
|
||||||
|
importRealmResources(context);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void importRealmResources(ServletContext context) {
|
||||||
|
String resources = context.getInitParameter("keycloak.import.realm.resources");
|
||||||
|
if (resources != null) {
|
||||||
|
StringTokenizer tokenizer = new StringTokenizer(resources, ",");
|
||||||
|
while (tokenizer.hasMoreTokens()) {
|
||||||
|
String resource = tokenizer.nextToken().trim();
|
||||||
|
InputStream is = context.getResourceAsStream(resource);
|
||||||
|
if (is == null) {
|
||||||
|
log.warn("Could not find realm resource to import: " + resource);
|
||||||
|
}
|
||||||
|
RealmRepresentation rep = loadJson(is, RealmRepresentation.class);
|
||||||
|
importRealm(rep, "resource " + resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void importRealmFile() {
|
||||||
|
String file = System.getProperty("keycloak.import");
|
||||||
|
if (file != null) {
|
||||||
|
RealmRepresentation rep = null;
|
||||||
|
try {
|
||||||
|
rep = loadJson(new FileInputStream(file), RealmRepresentation.class);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
importRealm(rep, "file " + file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void importRealm(RealmRepresentation rep, String from) {
|
||||||
|
KeycloakSession session = factory.createSession();
|
||||||
|
try {
|
||||||
|
session.getTransaction().begin();
|
||||||
|
RealmManager manager = new RealmManager(session);
|
||||||
|
|
||||||
|
if (rep.getId() != null && manager.getRealm(rep.getId()) != null) {
|
||||||
|
log.info("Not importing realm " + rep.getRealm() + " from " + from + ". It already exists.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manager.getRealmByName(rep.getRealm()) != null) {
|
||||||
|
log.info("Not importing realm " + rep.getRealm() + " from " + from + ". It already exists.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RealmModel realm = manager.createRealm(rep.getId(), rep.getRealm());
|
||||||
|
manager.importRealm(rep, realm);
|
||||||
|
|
||||||
|
log.info("Imported realm " + realm.getName() + " from " + from);
|
||||||
|
|
||||||
|
session.getTransaction().commit();
|
||||||
|
} finally {
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> T loadJson(InputStream is, Class<T> type) {
|
||||||
|
try {
|
||||||
|
return JsonSerialization.readValue(is, type);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to parse json", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue