Merge pull request #337 from patriot1burke/master
app/keycloak self bootstrapping bundle
This commit is contained in:
commit
1aa58ec580
25 changed files with 965 additions and 17 deletions
16
bundled-war-example/README.md
Executable file
16
bundled-war-example/README.md
Executable file
|
@ -0,0 +1,16 @@
|
|||
Self Bootstrapping Keycloak Server and Bundled Application
|
||||
==========================================================
|
||||
|
||||
This is an example of bundling the Keycloak server with an app within the same WAR in an EAP 6.x environment.
|
||||
|
||||
* On bootup, a default realm is imported from WEB-INF/testrealm.json if it doesn't exist yet.
|
||||
* On bootup, the adapter config is created on the fly and configured with the testrealm imported.
|
||||
* The application is secured with keycloak (see jboss-web.xml)
|
||||
* web.xml security constraints are set for the secured URLs that are secured by keycloak
|
||||
* Because of weirdness with Resteasy 2.3.x, any secured JAX-RS urls from the application must have a security
|
||||
constraint that denies all as they will be reachable in two places. Under the Keycloak REST url "/rest" and under the
|
||||
application's REST url "/database".
|
||||
* Adapter config can be modified on the fly by getting the AdapterDeploymentContext from a servlet context attribute.
|
||||
* You must specify a host-port context param so that the auth url for AdapterConfig can be set correctly.
|
||||
|
||||
* Run this demo by going to http://localhost:8080/app-bundle. Then click on the url.
|
285
bundled-war-example/pom.xml
Executable file
285
bundled-war-example/pom.xml
Executable file
|
@ -0,0 +1,285 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.0-beta-1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>app-bundle</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>Keycloak Server and App Bundle EAP 6.x</name>
|
||||
<description/>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk16</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-jboss-adapter-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-as7-adapter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
<artifactId>base64</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core-jaxrs</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-services</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>javase</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-model-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-model-jpa</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-audit-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-audit-jpa</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-audit-jboss-logging</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- social -->
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social-github</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social-google</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social-twitter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.twitter4j</groupId>
|
||||
<artifactId>twitter4j-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-social-facebook</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- forms -->
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-forms-common-freemarker</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
<artifactId>freemarker</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-forms-common-themes</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-account-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-account-freemarker</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-login-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-login-freemarker</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-admin-ui</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-js-adapter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- authentication api -->
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-authentication-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-authentication-model</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-authentication-picketlink</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-impl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketlink</groupId>
|
||||
<artifactId>picketlink-idm-simple-schema</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- timer -->
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-timer-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-timer-basic</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- picketlink -->
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-picketlink-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-picketlink-realm</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- resteasy -->
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jaxrs</artifactId>
|
||||
<version>${resteasy.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-multipart-provider</artifactId>
|
||||
<version>${resteasy.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>async-http-servlet-3.0</artifactId>
|
||||
<version>${resteasy.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>jaxrs-api</artifactId>
|
||||
<version>${resteasy.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.resteasy</groupId>
|
||||
<artifactId>resteasy-jackson-provider</artifactId>
|
||||
<version>${resteasy.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>app-bundle</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jboss.as.plugins</groupId>
|
||||
<artifactId>jboss-as-maven-plugin</artifactId>
|
||||
<version>7.5.Final</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,72 @@
|
|||
package org.keycloak.example;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.keycloak.adapters.HttpClientBuilder;
|
||||
import org.keycloak.representations.IDToken;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class CustomerDatabaseClient {
|
||||
|
||||
static class TypedList extends ArrayList<String> {
|
||||
}
|
||||
|
||||
public static class Failure extends Exception {
|
||||
private int status;
|
||||
|
||||
public Failure(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
public static IDToken getIDToken(HttpServletRequest req) {
|
||||
KeycloakSecurityContext session = (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
return session.getIdToken();
|
||||
|
||||
}
|
||||
|
||||
public static List<String> getCustomers(HttpServletRequest req) throws Failure {
|
||||
KeycloakSecurityContext session = (KeycloakSecurityContext) req.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
|
||||
HttpClient client = new HttpClientBuilder()
|
||||
.disableTrustManager().build();
|
||||
try {
|
||||
HttpGet get = new HttpGet("http://localhost:8080/app-bundle/database/customers");
|
||||
get.addHeader("Authorization", "Bearer " + session.getTokenString());
|
||||
try {
|
||||
HttpResponse response = client.execute(get);
|
||||
if (response.getStatusLine().getStatusCode() != 200) {
|
||||
throw new Failure(response.getStatusLine().getStatusCode());
|
||||
}
|
||||
HttpEntity entity = response.getEntity();
|
||||
InputStream is = entity.getContent();
|
||||
try {
|
||||
return JsonSerialization.readValue(is, TypedList.class);
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} finally {
|
||||
client.getConnectionManager().shutdown();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package org.keycloak.example.oauth;
|
||||
|
||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Path("customers")
|
||||
public class CustomerService {
|
||||
@GET
|
||||
@Produces("application/json")
|
||||
@NoCache
|
||||
public List<String> getCustomers() {
|
||||
ArrayList<String> rtn = new ArrayList<String>();
|
||||
rtn.add("Bill Burke");
|
||||
rtn.add("Stian Thorgersen");
|
||||
rtn.add("Stan Silvert");
|
||||
rtn.add("Gabriel Cardoso");
|
||||
rtn.add("Viliam Rockai");
|
||||
rtn.add("Marek Posolda");
|
||||
rtn.add("Boleslaw Dawidowicz");
|
||||
return rtn;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.keycloak.example.oauth;
|
||||
|
||||
import javax.ws.rs.core.Application;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class DataApplication extends Application
|
||||
{
|
||||
@Override
|
||||
public Set<Class<?>> getClasses() {
|
||||
HashSet<Class<?>> set = new HashSet<Class<?>>();
|
||||
set.add(CustomerService.class);
|
||||
set.add(ProductService.class);
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Object> getSingletons() {
|
||||
return super.getSingletons(); //To change body of overridden methods use File | Settings | File Templates.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.keycloak.example.oauth;
|
||||
|
||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Path("products")
|
||||
public class ProductService {
|
||||
@GET
|
||||
@Produces("application/json")
|
||||
@NoCache
|
||||
public List<String> getProducts() {
|
||||
ArrayList<String> rtn = new ArrayList<String>();
|
||||
rtn.add("iphone");
|
||||
rtn.add("ipad");
|
||||
rtn.add("ipod");
|
||||
return rtn;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
39
bundled-war-example/src/main/resources/META-INF/persistence.xml
Executable file
39
bundled-war-example/src/main/resources/META-INF/persistence.xml
Executable file
|
@ -0,0 +1,39 @@
|
|||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
<persistence-unit name="jpa-keycloak-identity-store" transaction-type="RESOURCE_LOCAL">
|
||||
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
|
||||
<class>org.keycloak.models.jpa.entities.ApplicationEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.CredentialEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.OAuthClientEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RealmEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RequiredCredentialEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.AuthenticationProviderEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ApplicationRoleEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.RealmRoleEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.SocialLinkEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.AuthenticationLinkEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
|
||||
<class>org.keycloak.models.jpa.entities.ScopeMappingEntity</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
<properties>
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
<persistence-unit name="jpa-keycloak-audit-store" transaction-type="RESOURCE_LOCAL">
|
||||
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
|
||||
<class>org.keycloak.audit.jpa.EventEntity</class>
|
||||
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
<properties>
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
36
bundled-war-example/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
Executable file
36
bundled-war-example/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
Executable file
|
@ -0,0 +1,36 @@
|
|||
<jboss-deployment-structure>
|
||||
<deployment>
|
||||
<dependencies>
|
||||
<module name="org.apache.httpcomponents"/>
|
||||
<module name="org.codehaus.jackson.jackson-core-asl"/>
|
||||
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
|
||||
</dependencies>
|
||||
<exclusions>
|
||||
|
||||
<!-- Exclude keycloak modules -->
|
||||
<module name="org.keycloak.keycloak-core" />
|
||||
<module name="org.keycloak.keycloak-adapter-core" />
|
||||
<module name="org.keycloak.keycloak-undertow-adapter" />
|
||||
<module name="org.keycloak.keycloak-as7-adapter" />
|
||||
|
||||
<!--
|
||||
<module name="org.apache.cxf" />
|
||||
<module name="javaee.api" />
|
||||
<module name="javax.ws.rs.api"/>
|
||||
<module name="org.codehaus.jackson.jackson-core-asl" />
|
||||
<module name="org.jboss.resteasy.resteasy-atom-provider" />
|
||||
<module name="org.jboss.resteasy.resteasy-cdi" />
|
||||
<module name="org.jboss.resteasy.resteasy-crypto" />
|
||||
<module name="org.jboss.resteasy.resteasy-jackson-provider" />
|
||||
<module name="org.jboss.resteasy.resteasy-jaxb-provider" />
|
||||
<module name="org.jboss.resteasy.resteasy-jaxrs" />
|
||||
<module name="org.jboss.resteasy.resteasy-jettison-provider" />
|
||||
<module name="org.jboss.resteasy.resteasy-jsapi" />
|
||||
<module name="org.jboss.resteasy.resteasy-json-p-provider" />
|
||||
<module name="org.jboss.resteasy.resteasy-multipart-provider" />
|
||||
<module name="org.jboss.resteasy.resteasy-validator-provider-11" />
|
||||
<module name="org.jboss.resteasy.resteasy-yaml-provider" />
|
||||
-->
|
||||
</exclusions>
|
||||
</deployment>
|
||||
</jboss-deployment-structure>
|
5
bundled-war-example/src/main/webapp/WEB-INF/jboss-web.xml
Executable file
5
bundled-war-example/src/main/webapp/WEB-INF/jboss-web.xml
Executable file
|
@ -0,0 +1,5 @@
|
|||
<jboss-web>
|
||||
<valve>
|
||||
<class-name>org.keycloak.adapters.as7.KeycloakAuthenticatorValve</class-name>
|
||||
</valve>
|
||||
</jboss-web>
|
70
bundled-war-example/src/main/webapp/WEB-INF/testrealm.json
Executable file
70
bundled-war-example/src/main/webapp/WEB-INF/testrealm.json
Executable file
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"realm": "demo",
|
||||
"enabled": true,
|
||||
"accessTokenLifespan": 3000,
|
||||
"accessCodeLifespan": 10,
|
||||
"accessCodeLifespanUserAction": 6000,
|
||||
"sslNotRequired": true,
|
||||
"registrationAllowed": false,
|
||||
"social": false,
|
||||
"updateProfileOnInitialSocialLogin": false,
|
||||
"requiredCredentials": [ "password" ],
|
||||
"users" : [
|
||||
{
|
||||
"username" : "bburke@redhat.com",
|
||||
"enabled": true,
|
||||
"email" : "bburke@redhat.com",
|
||||
"firstName": "Bill",
|
||||
"lastName": "Burke",
|
||||
"credentials" : [
|
||||
{ "type" : "password",
|
||||
"value" : "password" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"roles" : {
|
||||
"realm" : [
|
||||
{
|
||||
"name": "user",
|
||||
"description": "User privileges"
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"description": "Administrator privileges"
|
||||
}
|
||||
]
|
||||
},
|
||||
"roleMappings": [
|
||||
{
|
||||
"username": "bburke@redhat.com",
|
||||
"roles": ["user"]
|
||||
}
|
||||
],
|
||||
"scopeMappings": [
|
||||
{
|
||||
"client": "customer-portal",
|
||||
"roles": ["user"]
|
||||
}
|
||||
],
|
||||
"applications": [
|
||||
{
|
||||
"name": "customer-portal",
|
||||
"enabled": true,
|
||||
"adminUrl": "http://localhost:8080/app-bundle",
|
||||
"baseUrl": "http://localhost:8080/app-bundle",
|
||||
"redirectUris": [
|
||||
"http://localhost:8080/app-bundle/*"
|
||||
],
|
||||
"secret": "password"
|
||||
}
|
||||
],
|
||||
"applicationRoleMappings": {
|
||||
"account": [
|
||||
{
|
||||
"username": "bburke@redhat.com",
|
||||
"roles": ["manage-account"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}
|
144
bundled-war-example/src/main/webapp/WEB-INF/web.xml
Executable file
144
bundled-war-example/src/main/webapp/WEB-INF/web.xml
Executable file
|
@ -0,0 +1,144 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||
version="3.0">
|
||||
|
||||
<module-name>app-bundle</module-name>
|
||||
<context-param>
|
||||
<param-name>host-port</param-name>
|
||||
<param-value>localhost:8080</param-value>
|
||||
</context-param>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>Keycloak REST Interface</servlet-name>
|
||||
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher</servlet-class>
|
||||
<init-param>
|
||||
<param-name>javax.ws.rs.Application</param-name>
|
||||
<param-value>org.keycloak.server.KeycloakServerApplication</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>resteasy.servlet.mapping.prefix</param-name>
|
||||
<param-value>/rest</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
<async-supported>true</async-supported>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>Customer REST Interface</servlet-name>
|
||||
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher</servlet-class>
|
||||
<init-param>
|
||||
<param-name>javax.ws.rs.Application</param-name>
|
||||
<param-value>org.keycloak.example.oauth.DataApplication</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>resteasy.servlet.mapping.prefix</param-name>
|
||||
<param-value>/database</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>2</load-on-startup>
|
||||
<async-supported>true</async-supported>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>TmpAdminRedirectServlet</servlet-name>
|
||||
<servlet-class>org.keycloak.services.tmp.TmpAdminRedirectServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<listener>
|
||||
<listener-class>org.keycloak.services.listeners.KeycloakSessionDestroyListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
<filter>
|
||||
<filter-name>Keycloak Client Connection Filter</filter-name>
|
||||
<filter-class>org.keycloak.services.filters.ClientConnectionFilter</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<filter-name>Keycloak Session Management</filter-name>
|
||||
<filter-class>org.keycloak.services.filters.KeycloakSessionServletFilter</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>Keycloak Session Management</filter-name>
|
||||
<url-pattern>/rest/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>Keycloak Client Connection Filter</filter-name>
|
||||
<url-pattern>/rest/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>Keycloak REST Interface</servlet-name>
|
||||
<url-pattern>/rest/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>Customer REST Interface</servlet-name>
|
||||
<url-pattern>/database/*</url-pattern>
|
||||
</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>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Customers</web-resource-name>
|
||||
<url-pattern>/customers/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>user</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Database</web-resource-name>
|
||||
<url-pattern>/database/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>user</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>deny</web-resource-name>
|
||||
<url-pattern>/rest/customers/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint/>
|
||||
</security-constraint>
|
||||
|
||||
<login-config>
|
||||
<auth-method>BASIC</auth-method>
|
||||
<realm-name>demo</realm-name>
|
||||
</login-config>
|
||||
|
||||
<security-role>
|
||||
<role-name>admin</role-name>
|
||||
</security-role>
|
||||
<security-role>
|
||||
<role-name>user</role-name>
|
||||
</security-role>
|
||||
|
||||
|
||||
</web-app>
|
47
bundled-war-example/src/main/webapp/customers/view.jsp
Executable file
47
bundled-war-example/src/main/webapp/customers/view.jsp
Executable file
|
@ -0,0 +1,47 @@
|
|||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1" %>
|
||||
<%@ page import="org.keycloak.example.CustomerDatabaseClient" %>
|
||||
<%@ page import="org.keycloak.util.KeycloakUriBuilder" %>
|
||||
<%@ page import="org.keycloak.representations.IDToken" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Customer View Page</title>
|
||||
</head>
|
||||
<body bgcolor="#E3F6CE">
|
||||
<%
|
||||
String logoutUri = KeycloakUriBuilder.fromUri("http://localhost:8080/app-bundle/rest/realms/demo/tokens/logout")
|
||||
.queryParam("redirect_uri", "http://localhost:8080/app-bundle").build().toString();
|
||||
String acctUri = "http://localhost:8080/app-bundle/rest/realms/demo/account?referrer=customer-portal";
|
||||
IDToken idToken = CustomerDatabaseClient.getIDToken(request);
|
||||
%>
|
||||
<p><a href="<%=logoutUri%>">logout</a> | <a
|
||||
href="<%=acctUri%>">manage acct</a></p>
|
||||
Servlet User Principal <b><%=request.getUserPrincipal().getName()%>
|
||||
</b> made this request.
|
||||
<p><b>Caller IDToken values</b> (<i>You can specify what is returned in IDToken in the customer-portal claims page in the admin console</i>:</p>
|
||||
<p>Username: <%=idToken.getPreferredUsername()%></p>
|
||||
<p>Email: <%=idToken.getEmail()%></p>
|
||||
<p>Full Name: <%=idToken.getName()%></p>
|
||||
<p>First: <%=idToken.getGivenName()%></p>
|
||||
<p>Last: <%=idToken.getFamilyName()%></p>
|
||||
<h2>Customer Listing</h2>
|
||||
<%
|
||||
java.util.List<String> list = null;
|
||||
try {
|
||||
list = CustomerDatabaseClient.getCustomers(request);
|
||||
} catch (CustomerDatabaseClient.Failure failure) {
|
||||
out.println("There was a failure processing request. You either didn't configure Keycloak properly, or maybe" +
|
||||
"you just forgot to secure the database service?");
|
||||
out.println("Status from database service invocation was: " + failure.getStatus());
|
||||
return;
|
||||
}
|
||||
for (String cust : list) {
|
||||
out.print("<p>");
|
||||
out.print(cust);
|
||||
out.println("</p>");
|
||||
|
||||
}
|
||||
%>
|
||||
<br><br>
|
||||
</body>
|
||||
</html>
|
13
bundled-war-example/src/main/webapp/index.html
Executable file
13
bundled-war-example/src/main/webapp/index.html
Executable file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body bgcolor="#E3F6CE">
|
||||
<h1>Customer Portal</h1>
|
||||
|
||||
<p><a href="customers/view.jsp">Customer Listing</a></p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,26 @@
|
|||
package org.keycloak.adapters;
|
||||
|
||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class AdapterDeploymentContext {
|
||||
protected KeycloakDeployment deployment;
|
||||
|
||||
public AdapterDeploymentContext() {
|
||||
}
|
||||
|
||||
public AdapterDeploymentContext(KeycloakDeployment deployment) {
|
||||
this.deployment = deployment;
|
||||
}
|
||||
|
||||
public KeycloakDeployment getDeployment() {
|
||||
return deployment;
|
||||
}
|
||||
|
||||
public void updateDeployment(AdapterConfig config) {
|
||||
deployment = KeycloakDeploymentBuilder.build(config);
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import java.util.Map;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class KeycloakDeployment {
|
||||
protected boolean configured;
|
||||
protected String realm;
|
||||
protected PublicKey realmKey;
|
||||
protected KeycloakUriBuilder authUrl;
|
||||
|
@ -37,6 +38,14 @@ public class KeycloakDeployment {
|
|||
protected boolean exposeToken;
|
||||
protected volatile int notBefore;
|
||||
|
||||
public boolean isConfigured() {
|
||||
return configured;
|
||||
}
|
||||
|
||||
public void setConfigured(boolean configured) {
|
||||
this.configured = configured;
|
||||
}
|
||||
|
||||
public String getResourceName() {
|
||||
return resourceName;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public class KeycloakDeploymentBuilder {
|
|||
|
||||
|
||||
protected KeycloakDeployment internalBuild(AdapterConfig adapterConfig) {
|
||||
|
||||
deployment.setConfigured(true);
|
||||
if (adapterConfig.getRealm() == null) throw new RuntimeException("Must set 'realm' in config");
|
||||
deployment.setRealm(adapterConfig.getRealm());
|
||||
String resource = adapterConfig.getResource();
|
||||
|
|
|
@ -35,6 +35,7 @@ public class PreAuthActionsHandler {
|
|||
}
|
||||
|
||||
public boolean handleRequest() {
|
||||
if (!deployment.isConfigured()) return false;
|
||||
String requestUri = facade.getRequest().getURI();
|
||||
log.debugv("adminRequest {0}", requestUri);
|
||||
if (preflightCors()) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.apache.catalina.valves.ValveBase;
|
|||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.keycloak.adapters.AdapterConstants;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.AuthenticatedActionsHandler;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
|
@ -33,10 +34,10 @@ import java.util.Set;
|
|||
*/
|
||||
public class AuthenticatedActionsValve extends ValveBase {
|
||||
private static final Logger log = Logger.getLogger(AuthenticatedActionsValve.class);
|
||||
protected KeycloakDeployment deployment;
|
||||
protected AdapterDeploymentContext deploymentContext;
|
||||
|
||||
public AuthenticatedActionsValve(KeycloakDeployment deployment, Valve next, Container container, ObjectName controller) {
|
||||
this.deployment = deployment;
|
||||
public AuthenticatedActionsValve(AdapterDeploymentContext deploymentContext, Valve next, Container container, ObjectName controller) {
|
||||
this.deploymentContext = deploymentContext;
|
||||
if (next == null) throw new RuntimeException("WTF is next null?!");
|
||||
setNext(next);
|
||||
setContainer(container);
|
||||
|
@ -47,7 +48,7 @@ public class AuthenticatedActionsValve extends ValveBase {
|
|||
@Override
|
||||
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||
log.debugv("AuthenticatedActionsValve.invoke {0}", request.getRequestURI());
|
||||
AuthenticatedActionsHandler handler = new AuthenticatedActionsHandler(deployment, new CatalinaHttpFacade(request, response));
|
||||
AuthenticatedActionsHandler handler = new AuthenticatedActionsHandler(deploymentContext.getDeployment(), new CatalinaHttpFacade(request, response));
|
||||
if (handler.handledRequest()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.apache.catalina.deploy.LoginConfig;
|
|||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.KeycloakSecurityContext;
|
||||
import org.keycloak.adapters.AdapterConstants;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.AuthChallenge;
|
||||
import org.keycloak.adapters.AuthOutcome;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
|
@ -55,7 +56,7 @@ import java.util.Map;
|
|||
public class KeycloakAuthenticatorValve extends FormAuthenticator implements LifecycleListener {
|
||||
private static final Logger log = Logger.getLogger(KeycloakAuthenticatorValve.class);
|
||||
protected CatalinaUserSessionManagement userSessionManagement = new CatalinaUserSessionManagement();
|
||||
protected KeycloakDeployment deployment;
|
||||
protected AdapterDeploymentContext deploymentContext;
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -100,15 +101,26 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
|
||||
|
||||
protected void init() {
|
||||
this.deployment = KeycloakDeploymentBuilder.build(getConfigInputStream(context));
|
||||
AuthenticatedActionsValve actions = new AuthenticatedActionsValve(deployment, getNext(), getContainer(), getController());
|
||||
InputStream configInputStream = getConfigInputStream(context);
|
||||
KeycloakDeployment kd = null;
|
||||
if (configInputStream == null) {
|
||||
log.warn("No adapter configuration. Keycloak is unconfigured and will deny all requests.");
|
||||
kd = new KeycloakDeployment();
|
||||
kd.setConfigured(false);
|
||||
|
||||
} else {
|
||||
kd = KeycloakDeploymentBuilder.build(configInputStream);
|
||||
}
|
||||
deploymentContext = new AdapterDeploymentContext(kd);
|
||||
context.getServletContext().setAttribute(AdapterDeploymentContext.class.getName(), deploymentContext);
|
||||
AuthenticatedActionsValve actions = new AuthenticatedActionsValve(deploymentContext, getNext(), getContainer(), getController());
|
||||
setNext(actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(Request request, Response response) throws IOException, ServletException {
|
||||
try {
|
||||
PreAuthActionsHandler handler = new PreAuthActionsHandler(userSessionManagement, deployment, new CatalinaHttpFacade(request, response));
|
||||
PreAuthActionsHandler handler = new PreAuthActionsHandler(userSessionManagement, deploymentContext.getDeployment(), new CatalinaHttpFacade(request, response));
|
||||
if (handler.handleRequest()) {
|
||||
return;
|
||||
}
|
||||
|
@ -120,8 +132,9 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
|
||||
@Override
|
||||
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
|
||||
if (!deploymentContext.getDeployment().isConfigured()) return false;
|
||||
CatalinaHttpFacade facade = new CatalinaHttpFacade(request, response);
|
||||
CatalinaRequestAuthenticator authenticator = new CatalinaRequestAuthenticator(deployment, this, userSessionManagement, facade, request);
|
||||
CatalinaRequestAuthenticator authenticator = new CatalinaRequestAuthenticator(deploymentContext.getDeployment(), this, userSessionManagement, facade, request);
|
||||
AuthOutcome outcome = authenticator.authenticate();
|
||||
if (outcome == AuthOutcome.AUTHENTICATED) {
|
||||
if (facade.isEnded()) {
|
||||
|
@ -146,7 +159,7 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext)request.getSessionInternal().getNote(KeycloakSecurityContext.class.getName());
|
||||
if (session == null) return;
|
||||
// just in case session got serialized
|
||||
session.setDeployment(deployment);
|
||||
session.setDeployment(deploymentContext.getDeployment());
|
||||
if (session.isActive()) return;
|
||||
|
||||
// FYI: A refresh requires same scope, so same roles will be set. Otherwise, refresh will fail and token will
|
||||
|
|
1
pom.xml
1
pom.xml
|
@ -102,6 +102,7 @@
|
|||
<module>testsuite</module>
|
||||
<module>server</module>
|
||||
<module>timer</module>
|
||||
<module>bundled-war-example</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
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;
|
||||
|
@ -21,8 +22,8 @@ public class KeycloakServerApplication extends KeycloakApplication {
|
|||
|
||||
private static final Logger log = Logger.getLogger(KeycloakServerApplication.class);
|
||||
|
||||
public KeycloakServerApplication(@Context ServletContext servletContext) throws FileNotFoundException {
|
||||
super(servletContext);
|
||||
public KeycloakServerApplication(@Context ServletContext servletContext, @Context Dispatcher dispatcher) throws FileNotFoundException {
|
||||
super(servletContext, dispatcher);
|
||||
|
||||
String importRealm = System.getProperty("keycloak.import");
|
||||
if (importRealm != null) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.keycloak.services.resources;
|
||||
|
||||
import org.jboss.resteasy.core.Dispatcher;
|
||||
import org.jboss.resteasy.logging.Logger;
|
||||
import org.keycloak.SkeletonKeyContextResolver;
|
||||
import org.keycloak.audit.AuditListener;
|
||||
|
@ -52,9 +53,10 @@ public class KeycloakApplication extends Application {
|
|||
protected ProviderSessionFactory providerSessionFactory;
|
||||
protected String contextPath;
|
||||
|
||||
public KeycloakApplication(@Context ServletContext context) {
|
||||
this.factory = createSessionFactory();
|
||||
public KeycloakApplication(@Context ServletContext context, @Context Dispatcher dispatcher) {
|
||||
dispatcher.getDefaultContextObjects().put(KeycloakApplication.class, this);
|
||||
this.contextPath = context.getContextPath();
|
||||
this.factory = createSessionFactory();
|
||||
this.providerSessionFactory = createProviderSessionFactory();
|
||||
context.setAttribute(KeycloakSessionFactory.class.getName(), factory);
|
||||
//classes.add(KeycloakSessionCleanupFilter.class);
|
||||
|
|
|
@ -52,7 +52,7 @@ public class ApplicationResource {
|
|||
protected UriInfo uriInfo;
|
||||
|
||||
@Context
|
||||
protected Application keycloak;
|
||||
protected KeycloakApplication keycloak;
|
||||
|
||||
protected KeycloakApplication getKeycloakApplication() {
|
||||
return (KeycloakApplication)keycloak;
|
||||
|
|
|
@ -41,7 +41,7 @@ public class OAuthClientResource {
|
|||
protected UriInfo uriInfo;
|
||||
|
||||
@Context
|
||||
protected Application application;
|
||||
protected KeycloakApplication application;
|
||||
|
||||
protected KeycloakApplication getApplication() {
|
||||
return (KeycloakApplication)application;
|
||||
|
|
Loading…
Reference in a new issue