Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
355d4bdf91
54 changed files with 1436 additions and 105 deletions
|
@ -17,6 +17,7 @@ public class AbstractOAuthClient {
|
||||||
protected KeyStore truststore;
|
protected KeyStore truststore;
|
||||||
protected String authUrl;
|
protected String authUrl;
|
||||||
protected String codeUrl;
|
protected String codeUrl;
|
||||||
|
protected String scope;
|
||||||
protected String stateCookieName = OAUTH_TOKEN_REQUEST_STATE;
|
protected String stateCookieName = OAUTH_TOKEN_REQUEST_STATE;
|
||||||
protected String stateCookiePath;
|
protected String stateCookiePath;
|
||||||
protected boolean isSecure;
|
protected boolean isSecure;
|
||||||
|
@ -68,6 +69,14 @@ public class AbstractOAuthClient {
|
||||||
this.codeUrl = codeUrl;
|
this.codeUrl = codeUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getScope() {
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScope(String scope) {
|
||||||
|
this.scope = scope;
|
||||||
|
}
|
||||||
|
|
||||||
public String getStateCookieName() {
|
public String getStateCookieName() {
|
||||||
return stateCookieName;
|
return stateCookieName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public class ResourceMetadata {
|
||||||
protected String clientKeyPassword;
|
protected String clientKeyPassword;
|
||||||
protected KeyStore truststore;
|
protected KeyStore truststore;
|
||||||
protected PublicKey realmKey;
|
protected PublicKey realmKey;
|
||||||
|
protected String scope;
|
||||||
|
|
||||||
public String getResourceName() {
|
public String getResourceName() {
|
||||||
return resourceName;
|
return resourceName;
|
||||||
|
@ -78,4 +79,12 @@ public class ResourceMetadata {
|
||||||
public void setRealmKey(PublicKey realmKey) {
|
public void setRealmKey(PublicKey realmKey) {
|
||||||
this.realmKey = realmKey;
|
this.realmKey = realmKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getScope() {
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScope(String scope) {
|
||||||
|
this.scope = scope;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.codehaus.jackson.annotate.JsonPropertyOrder;
|
||||||
"resource", "credentials",
|
"resource", "credentials",
|
||||||
"use-resource-role-mappings",
|
"use-resource-role-mappings",
|
||||||
"enable-cors", "cors-max-age", "cors-allowed-methods",
|
"enable-cors", "cors-max-age", "cors-allowed-methods",
|
||||||
"expose-token", "bearer-only",
|
"expose-token", "bearer-only", "scope",
|
||||||
"connection-pool-size",
|
"connection-pool-size",
|
||||||
"allow-any-hostname", "disable-trust-manager", "truststore", "truststore-password",
|
"allow-any-hostname", "disable-trust-manager", "truststore", "truststore-password",
|
||||||
"client-keystore", "client-keystore-password", "client-key-password"
|
"client-keystore", "client-keystore-password", "client-key-password"
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.keycloak.representations.adapters.config;
|
||||||
|
|
||||||
import org.codehaus.jackson.annotate.JsonProperty;
|
import org.codehaus.jackson.annotate.JsonProperty;
|
||||||
import org.codehaus.jackson.annotate.JsonPropertyOrder;
|
import org.codehaus.jackson.annotate.JsonPropertyOrder;
|
||||||
|
import org.keycloak.representations.SkeletonKeyScope;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -16,7 +17,7 @@ import java.util.Map;
|
||||||
"resource", "credentials",
|
"resource", "credentials",
|
||||||
"use-resource-role-mappings",
|
"use-resource-role-mappings",
|
||||||
"enable-cors", "cors-max-age", "cors-allowed-methods",
|
"enable-cors", "cors-max-age", "cors-allowed-methods",
|
||||||
"expose-token", "bearer-only"})
|
"expose-token", "bearer-only", "scope"})
|
||||||
public class BaseAdapterConfig extends BaseRealmConfig {
|
public class BaseAdapterConfig extends BaseRealmConfig {
|
||||||
@JsonProperty("resource")
|
@JsonProperty("resource")
|
||||||
protected String resource;
|
protected String resource;
|
||||||
|
@ -36,6 +37,9 @@ public class BaseAdapterConfig extends BaseRealmConfig {
|
||||||
protected boolean bearerOnly;
|
protected boolean bearerOnly;
|
||||||
@JsonProperty("credentials")
|
@JsonProperty("credentials")
|
||||||
protected Map<String, String> credentials = new HashMap<String, String>();
|
protected Map<String, String> credentials = new HashMap<String, String>();
|
||||||
|
@JsonProperty("scope")
|
||||||
|
protected SkeletonKeyScope scope;
|
||||||
|
|
||||||
|
|
||||||
public boolean isUseResourceRoleMappings() {
|
public boolean isUseResourceRoleMappings() {
|
||||||
return useResourceRoleMappings;
|
return useResourceRoleMappings;
|
||||||
|
@ -108,4 +112,12 @@ public class BaseAdapterConfig extends BaseRealmConfig {
|
||||||
public void setCredentials(Map<String, String> credentials) {
|
public void setCredentials(Map<String, String> credentials) {
|
||||||
this.credentials = credentials;
|
this.credentials = credentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SkeletonKeyScope getScope() {
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScope(SkeletonKeyScope scope) {
|
||||||
|
this.scope = scope;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.jboss.resteasy.example.oauth;
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
|
@ -1,4 +1,4 @@
|
||||||
package org.jboss.resteasy.example.oauth;
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
import javax.ws.rs.ApplicationPath;
|
import javax.ws.rs.ApplicationPath;
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
|
@ -1,4 +1,4 @@
|
||||||
package org.jboss.resteasy.example.oauth;
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
|
@ -38,5 +38,6 @@
|
||||||
<module>product-app</module>
|
<module>product-app</module>
|
||||||
<module>database-service</module>
|
<module>database-service</module>
|
||||||
<module>third-party</module>
|
<module>third-party</module>
|
||||||
|
<module>third-party-cdi</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
|
74
examples/as7-eap-demo/third-party-cdi/pom.xml
Executable file
74
examples/as7-eap-demo/third-party-cdi/pom.xml
Executable file
|
@ -0,0 +1,74 @@
|
||||||
|
<?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-alpha-1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.keycloak.example.as7.demo</groupId>
|
||||||
|
<artifactId>oauth-client-cdi-example</artifactId>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>Simple OAuth Client Using CDI and JSF</name>
|
||||||
|
<description/>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||||
|
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
|
||||||
|
<version>1.0.1.Final</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.enterprise</groupId>
|
||||||
|
<artifactId>cdi-api</artifactId>
|
||||||
|
<version>1.0-SP4</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.spec.javax.faces</groupId>
|
||||||
|
<artifactId>jboss-jsf-api_2.1_spec</artifactId>
|
||||||
|
<version>2.0.1.Final</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.logging</groupId>
|
||||||
|
<artifactId>jboss-logging</artifactId>
|
||||||
|
<version>3.1.2.GA</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-servlet-oauth-client</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>oauth-client-cdi</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jboss.as.plugins</groupId>
|
||||||
|
<artifactId>jboss-as-maven-plugin</artifactId>
|
||||||
|
<version>7.4.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>1.6</source>
|
||||||
|
<target>1.6</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,57 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
|
import javax.servlet.annotation.WebListener;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
|
import org.keycloak.servlet.ServletOAuthClientConfigLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@WebListener
|
||||||
|
public class AppContextListener implements ServletContextListener {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(AppContextListener.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ServletOAuthClient oauthClient;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
ServletContext context = sce.getServletContext();
|
||||||
|
|
||||||
|
InputStream is = null;
|
||||||
|
String path = context.getInitParameter("keycloak.config.file");
|
||||||
|
if (path == null) {
|
||||||
|
is = context.getResourceAsStream("/WEB-INF/keycloak.json");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
is = new FileInputStream(path);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ServletOAuthClientConfigLoader loader = new ServletOAuthClientConfigLoader(is);
|
||||||
|
loader.initOAuthClientConfiguration(true);
|
||||||
|
loader.configureServletOAuthClient(oauthClient);
|
||||||
|
|
||||||
|
oauthClient.start();
|
||||||
|
logger.info("OAuth client configured and started");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
|
oauthClient.stop();
|
||||||
|
logger.info("OAuth client stopped");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class CDIResourcesProducer {
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@RequestScoped
|
||||||
|
public FacesContext produceFacesContext() {
|
||||||
|
return FacesContext.getCurrentInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@RequestScoped
|
||||||
|
@ServletRequestQualifier
|
||||||
|
public HttpServletRequest produceServletRequest() {
|
||||||
|
return (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@RequestScoped
|
||||||
|
public HttpServletResponse produceServletResponse() {
|
||||||
|
return (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@ApplicationScoped
|
||||||
|
public ServletOAuthClient produceOAuthClient() {
|
||||||
|
return new ServletOAuthClient();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
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.jboss.logging.Logger;
|
||||||
|
import org.keycloak.adapters.TokenGrantRequest;
|
||||||
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.faces.application.FacesMessage;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
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>
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
@ApplicationScoped
|
||||||
|
@Named("databaseClient")
|
||||||
|
public class DatabaseClient {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@ServletRequestQualifier
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private HttpServletResponse response;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private FacesContext facesContext;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ServletOAuthClient oauthClient;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserData userData;
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(DatabaseClient.class);
|
||||||
|
|
||||||
|
public void retrieveAccessToken() {
|
||||||
|
try {
|
||||||
|
oauthClient.redirectRelative("client.jsf", request, response);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TypedList extends ArrayList<String> {}
|
||||||
|
|
||||||
|
public void sendCustomersRequest() {
|
||||||
|
List<String> customers = sendRequestToDBApplication("http://localhost:8080/database/customers");
|
||||||
|
userData.setCustomers(customers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendProductsRequest() {
|
||||||
|
List<String> products = sendRequestToDBApplication("http://localhost:8080/database/products");
|
||||||
|
userData.setProducts(products);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<String> sendRequestToDBApplication(String dbUri) {
|
||||||
|
HttpClient client = oauthClient.getClient();
|
||||||
|
HttpGet get = new HttpGet(dbUri);
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (userData.isHasAccessToken()) {
|
||||||
|
get.addHeader("Authorization", "Bearer " + userData.getAccessToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse response = client.execute(get);
|
||||||
|
switch (response.getStatusLine().getStatusCode()) {
|
||||||
|
case 200: HttpEntity entity = response.getEntity();
|
||||||
|
InputStream is = entity.getContent();
|
||||||
|
try {
|
||||||
|
return JsonSerialization.readValue(is, TypedList.class);
|
||||||
|
} finally {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
case 401: facesContext.addMessage(null, new FacesMessage("Status: 401. Request not authenticated! You need to retrieve access token first."));
|
||||||
|
break;
|
||||||
|
case 403: facesContext.addMessage(null, new FacesMessage("Status: 403. Access token has insufficient privileges"));
|
||||||
|
break;
|
||||||
|
default: facesContext.addMessage(null, new FacesMessage("Status: " + response.getStatusLine() + ". Not able to retrieve data. See log for details"));
|
||||||
|
logger.warn("Error occured. Status: " + response.getStatusLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
facesContext.addMessage(null, new FacesMessage("Unknown error. See log for details"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.faces.application.FacesMessage;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is needed because Faces context is not available in HTTP filters
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Named("messagesChecker")
|
||||||
|
public class MessagesChecker {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@ServletRequestQualifier
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private FacesContext facesContext;
|
||||||
|
|
||||||
|
public String getCheckMessage() {
|
||||||
|
String oauthError = (String)request.getAttribute(RefreshTokenFilter.OAUTH_ERROR_ATTR);
|
||||||
|
if (oauthError != null) {
|
||||||
|
facesContext.addMessage(null, new FacesMessage("OAuth error occured: " + oauthError));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.annotation.WebFilter;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.keycloak.adapters.TokenGrantRequest;
|
||||||
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@WebFilter(value = "/client.jsf")
|
||||||
|
public class RefreshTokenFilter implements Filter {
|
||||||
|
|
||||||
|
public static final String OAUTH_ERROR_ATTR = "oauthErrorAttr";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ServletOAuthClient oauthClient;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserData userData;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
|
||||||
|
HttpServletRequest request = (HttpServletRequest)req;
|
||||||
|
HttpServletResponse response = (HttpServletResponse)resp;
|
||||||
|
Map<String, String[]> reqParams = request.getParameterMap();
|
||||||
|
|
||||||
|
if (reqParams.containsKey("code")) {
|
||||||
|
try {
|
||||||
|
String accessToken = oauthClient.getBearerToken(request);
|
||||||
|
userData.setAccessToken(accessToken);
|
||||||
|
} catch (TokenGrantRequest.HttpFailure e) {
|
||||||
|
throw new ServletException(e);
|
||||||
|
}
|
||||||
|
} else if (reqParams.containsKey("error")) {
|
||||||
|
String oauthError = reqParams.get("error")[0];
|
||||||
|
request.setAttribute(OAUTH_ERROR_ATTR, oauthError);
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is needed to have same code working in AS7 and Wildfly. In Wildfly is HttpServletRequest injected automatically, in AS7 it's not
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@Qualifier
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
|
||||||
|
public @interface ServletRequestQualifier {
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.enterprise.context.SessionScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@SessionScoped
|
||||||
|
@Named("userData")
|
||||||
|
public class UserData implements Serializable {
|
||||||
|
|
||||||
|
private String accessToken;
|
||||||
|
private List<String> products;
|
||||||
|
private List<String> customers;
|
||||||
|
|
||||||
|
public String getAccessToken() {
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessToken(String accessToken) {
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHasAccessToken() {
|
||||||
|
return accessToken != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccessTokenAvailabilityMessage() {
|
||||||
|
StringBuilder builder = new StringBuilder("Access token ");
|
||||||
|
if (!isHasAccessToken()) {
|
||||||
|
builder.append("not ");
|
||||||
|
}
|
||||||
|
return builder.append("available!").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getProducts() {
|
||||||
|
return products;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProducts(List<String> products) {
|
||||||
|
this.products = products;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHasProducts() {
|
||||||
|
return products != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getCustomers() {
|
||||||
|
return customers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCustomers(List<String> customers) {
|
||||||
|
this.customers = customers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHasCustomers() {
|
||||||
|
return customers != null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!--
|
||||||
|
JBoss, Home of Professional Open Source
|
||||||
|
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
|
||||||
|
contributors by the @authors tag. See the copyright.txt in the
|
||||||
|
distribution for a full listing of individual contributors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<!-- Marker file indicating CDI should be enabled -->
|
||||||
|
<beans 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/beans_1_0.xsd">
|
||||||
|
</beans>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
JBoss, Home of Professional Open Source
|
||||||
|
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
|
||||||
|
contributors by the @authors tag. See the copyright.txt in the
|
||||||
|
distribution for a full listing of individual contributors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<!-- Marker file indicating JSF should be enabled -->
|
||||||
|
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
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-facesconfig_2_0.xsd">
|
||||||
|
|
||||||
|
</faces-config>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<jboss-deployment-structure>
|
||||||
|
<deployment>
|
||||||
|
<!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->
|
||||||
|
<dependencies>
|
||||||
|
</dependencies>
|
||||||
|
</deployment>
|
||||||
|
</jboss-deployment-structure>
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"resource" : "third-party",
|
||||||
|
"auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/login",
|
||||||
|
"code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes",
|
||||||
|
"ssl-not-required" : true,
|
||||||
|
"credentials" : {
|
||||||
|
"password" : "password"
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"realm": [ "user" ]
|
||||||
|
}
|
||||||
|
}
|
20
examples/as7-eap-demo/third-party-cdi/src/main/webapp/WEB-INF/web.xml
Executable file
20
examples/as7-eap-demo/third-party-cdi/src/main/webapp/WEB-INF/web.xml
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
<?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>oauth-client-cdi</module-name>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<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>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</web-app>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html
|
||||||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
|
||||||
|
xmlns:f="http://java.sun.com/jsf/core">
|
||||||
|
<body>
|
||||||
|
<h1>Third Party App That Pulls Data Using OAuth</h1>
|
||||||
|
<h:form>
|
||||||
|
#{userData.accessTokenAvailabilityMessage}
|
||||||
|
<br />
|
||||||
|
<h:commandButton id="retrieve_token" value="Retrieve/refresh access token" action="#{databaseClient.retrieveAccessToken}"/>
|
||||||
|
<h:commandButton id="products_request" value="Load products list" action="#{databaseClient.sendProductsRequest}"/>
|
||||||
|
<h:commandButton id="customers_request" value="Load customers list" action="#{databaseClient.sendCustomersRequest}"/>
|
||||||
|
</h:form>
|
||||||
|
|
||||||
|
<ui:fragment rendered="#{userData.hasProducts}">
|
||||||
|
<hr />
|
||||||
|
<h3>Products data available</h3>
|
||||||
|
<ui:repeat value="#{userData.products}" var="product">
|
||||||
|
#{product}<br/>
|
||||||
|
</ui:repeat>
|
||||||
|
</ui:fragment>
|
||||||
|
|
||||||
|
<ui:fragment rendered="#{userData.hasCustomers}">
|
||||||
|
<hr />
|
||||||
|
<h3>Customers data available</h3>
|
||||||
|
<ui:repeat value="#{userData.customers}" var="customer">
|
||||||
|
#{customer}<br/>
|
||||||
|
</ui:repeat>
|
||||||
|
</ui:fragment>
|
||||||
|
|
||||||
|
<div style="color: red">
|
||||||
|
#{messagesChecker.checkMessage}
|
||||||
|
<h:messages globalOnly="true"/>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Refresh" content="0; URL=client.jsf">
|
||||||
|
</head>
|
||||||
|
</html>
|
|
@ -1,15 +1,19 @@
|
||||||
package org.keycloak.example.oauth;
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
import org.keycloak.servlet.ServletOAuthClient;
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
|
import org.keycloak.servlet.ServletOAuthClientConfigLoader;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
import javax.servlet.ServletContextListener;
|
import javax.servlet.ServletContextListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stupid init code to load up the truststore so we can make appropriate SSL connections
|
* Init code to load up the truststore so we can make appropriate SSL connections
|
||||||
* You really should use a better way of initializing this stuff.
|
* You really should use a better way of initializing this stuff.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -32,36 +36,34 @@ public class Bootstrap implements ServletContextListener {
|
||||||
@Override
|
@Override
|
||||||
public void contextInitialized(ServletContextEvent sce) {
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
client = new ServletOAuthClient();
|
client = new ServletOAuthClient();
|
||||||
/*
|
ServletContext context = sce.getServletContext();
|
||||||
// hardcoded, WARNING, you should really have a better way of doing this
|
|
||||||
// configuration. Either use something like Spring or CDI, or even pull
|
configureClient(context);
|
||||||
// config vales from context-params
|
|
||||||
String truststorePath = "${jboss.server.config.dir}/client-truststore.ts";
|
|
||||||
String truststorePassword = "password";
|
|
||||||
truststorePath = EnvUtil.replace(truststorePath);
|
|
||||||
KeyStore truststore = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
truststore = loadKeyStore(truststorePath, truststorePassword);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
client.setTruststore(truststore);
|
|
||||||
*/
|
|
||||||
client.setClientId("third-party");
|
|
||||||
client.setPassword("password");
|
|
||||||
client.setAuthUrl("http://localhost:8080/auth-server/rest/realms/demo/tokens/login");
|
|
||||||
client.setCodeUrl("http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes");
|
|
||||||
client.start();
|
client.start();
|
||||||
sce.getServletContext().setAttribute(ServletOAuthClient.class.getName(), client);
|
context.setAttribute(ServletOAuthClient.class.getName(), client);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextDestroyed(ServletContextEvent sce) {
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
client.stop();
|
client.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void configureClient(ServletContext context) {
|
||||||
|
InputStream is = null;
|
||||||
|
String path = context.getInitParameter("keycloak.config.file");
|
||||||
|
if (path == null) {
|
||||||
|
is = context.getResourceAsStream("/WEB-INF/keycloak.json");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
is = new FileInputStream(path);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ServletOAuthClientConfigLoader loader = new ServletOAuthClientConfigLoader(is);
|
||||||
|
loader.initOAuthClientConfiguration(true);
|
||||||
|
loader.configureServletOAuthClient(client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,11 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class ProductDatabaseClient {
|
public class ProductDatabaseClient {
|
||||||
public static void redirect(HttpServletRequest request, HttpServletResponse response) {
|
public static void redirect(HttpServletRequest request, HttpServletResponse response) {
|
||||||
// This is really the worst code ever. The ServletOAuthClient is obtained by getting a context attribute
|
// The ServletOAuthClient is obtained by getting a context attribute
|
||||||
// that is set in the Bootstrap context listenr in this project.
|
// that is set in the Bootstrap context listener in this project.
|
||||||
// You really should come up with a better way to initialize
|
// You really should come up with a better way to initialize
|
||||||
// and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
|
// and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
|
||||||
// and take a look how it works.
|
// and take a look how it works. You can also take a look at third-party-cdi example
|
||||||
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
||||||
try {
|
try {
|
||||||
oAuthClient.redirectRelative("pull_data.jsp", request, response);
|
oAuthClient.redirectRelative("pull_data.jsp", request, response);
|
||||||
|
@ -37,11 +37,11 @@ public class ProductDatabaseClient {
|
||||||
static class TypedList extends ArrayList<String> {}
|
static class TypedList extends ArrayList<String> {}
|
||||||
|
|
||||||
public static List<String> getProducts(HttpServletRequest request) {
|
public static List<String> getProducts(HttpServletRequest request) {
|
||||||
// This is really the worst code ever. The ServletOAuthClient is obtained by getting a context attribute
|
// The ServletOAuthClient is obtained by getting a context attribute
|
||||||
// that is set in the Bootstrap context listenr in this project.
|
// that is set in the Bootstrap context listener in this project.
|
||||||
// You really should come up with a better way to initialize
|
// You really should come up with a better way to initialize
|
||||||
// and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
|
// and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
|
||||||
// and take a look how it works.
|
// and take a look how it works. You can also take a look at third-party-cdi example
|
||||||
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
||||||
String token = null;
|
String token = null;
|
||||||
try {
|
try {
|
||||||
|
|
12
examples/as7-eap-demo/third-party/src/main/webapp/WEB-INF/keycloak.json
vendored
Normal file
12
examples/as7-eap-demo/third-party/src/main/webapp/WEB-INF/keycloak.json
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"resource" : "third-party",
|
||||||
|
"auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/login",
|
||||||
|
"code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes",
|
||||||
|
"ssl-not-required" : true,
|
||||||
|
"credentials" : {
|
||||||
|
"password" : "password"
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"realm": [ "user" ]
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package org.jboss.resteasy.example.oauth;
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
|
@ -1,4 +1,4 @@
|
||||||
package org.jboss.resteasy.example.oauth;
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
import javax.ws.rs.ApplicationPath;
|
import javax.ws.rs.ApplicationPath;
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
|
@ -1,4 +1,4 @@
|
||||||
package org.jboss.resteasy.example.oauth;
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
|
@ -39,5 +39,6 @@
|
||||||
<module>product-app</module>
|
<module>product-app</module>
|
||||||
<module>database-service</module>
|
<module>database-service</module>
|
||||||
<module>third-party</module>
|
<module>third-party</module>
|
||||||
|
<module>third-party-cdi</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
|
74
examples/wildfly-demo/third-party-cdi/pom.xml
Executable file
74
examples/wildfly-demo/third-party-cdi/pom.xml
Executable file
|
@ -0,0 +1,74 @@
|
||||||
|
<?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-alpha-1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.keycloak.example.wildfly.demo</groupId>
|
||||||
|
<artifactId>oauth-client-cdi-example</artifactId>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>Simple OAuth Client Using CDI and JSF</name>
|
||||||
|
<description/>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||||
|
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
|
||||||
|
<version>1.0.1.Final</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.enterprise</groupId>
|
||||||
|
<artifactId>cdi-api</artifactId>
|
||||||
|
<version>1.0-SP4</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.spec.javax.faces</groupId>
|
||||||
|
<artifactId>jboss-jsf-api_2.1_spec</artifactId>
|
||||||
|
<version>2.0.1.Final</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.logging</groupId>
|
||||||
|
<artifactId>jboss-logging</artifactId>
|
||||||
|
<version>3.1.2.GA</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-servlet-oauth-client</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>oauth-client-cdi</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jboss.as.plugins</groupId>
|
||||||
|
<artifactId>jboss-as-maven-plugin</artifactId>
|
||||||
|
<version>7.4.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>1.6</source>
|
||||||
|
<target>1.6</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,57 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
|
import javax.servlet.annotation.WebListener;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
|
import org.keycloak.servlet.ServletOAuthClientConfigLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@WebListener
|
||||||
|
public class AppContextListener implements ServletContextListener {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(AppContextListener.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ServletOAuthClient oauthClient;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
ServletContext context = sce.getServletContext();
|
||||||
|
|
||||||
|
InputStream is = null;
|
||||||
|
String path = context.getInitParameter("keycloak.config.file");
|
||||||
|
if (path == null) {
|
||||||
|
is = context.getResourceAsStream("/WEB-INF/keycloak.json");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
is = new FileInputStream(path);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ServletOAuthClientConfigLoader loader = new ServletOAuthClientConfigLoader(is);
|
||||||
|
loader.initOAuthClientConfiguration(true);
|
||||||
|
loader.configureServletOAuthClient(oauthClient);
|
||||||
|
|
||||||
|
oauthClient.start();
|
||||||
|
logger.info("OAuth client configured and started");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
|
oauthClient.stop();
|
||||||
|
logger.info("OAuth client stopped");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class CDIResourcesProducer {
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@RequestScoped
|
||||||
|
public FacesContext produceFacesContext() {
|
||||||
|
return FacesContext.getCurrentInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@RequestScoped
|
||||||
|
@ServletRequestQualifier
|
||||||
|
public HttpServletRequest produceServletRequest() {
|
||||||
|
return (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@RequestScoped
|
||||||
|
public HttpServletResponse produceServletResponse() {
|
||||||
|
return (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@ApplicationScoped
|
||||||
|
public ServletOAuthClient produceOAuthClient() {
|
||||||
|
return new ServletOAuthClient();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
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.jboss.logging.Logger;
|
||||||
|
import org.keycloak.adapters.TokenGrantRequest;
|
||||||
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
import javax.faces.application.FacesMessage;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
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>
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
@ApplicationScoped
|
||||||
|
@Named("databaseClient")
|
||||||
|
public class DatabaseClient {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@ServletRequestQualifier
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private HttpServletResponse response;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private FacesContext facesContext;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ServletOAuthClient oauthClient;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserData userData;
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(DatabaseClient.class);
|
||||||
|
|
||||||
|
public void retrieveAccessToken() {
|
||||||
|
try {
|
||||||
|
oauthClient.redirectRelative("client.jsf", request, response);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TypedList extends ArrayList<String> {}
|
||||||
|
|
||||||
|
public void sendCustomersRequest() {
|
||||||
|
List<String> customers = sendRequestToDBApplication("http://localhost:8080/database/customers");
|
||||||
|
userData.setCustomers(customers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendProductsRequest() {
|
||||||
|
List<String> products = sendRequestToDBApplication("http://localhost:8080/database/products");
|
||||||
|
userData.setProducts(products);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<String> sendRequestToDBApplication(String dbUri) {
|
||||||
|
HttpClient client = oauthClient.getClient();
|
||||||
|
HttpGet get = new HttpGet(dbUri);
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (userData.isHasAccessToken()) {
|
||||||
|
get.addHeader("Authorization", "Bearer " + userData.getAccessToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse response = client.execute(get);
|
||||||
|
switch (response.getStatusLine().getStatusCode()) {
|
||||||
|
case 200: HttpEntity entity = response.getEntity();
|
||||||
|
InputStream is = entity.getContent();
|
||||||
|
try {
|
||||||
|
return JsonSerialization.readValue(is, TypedList.class);
|
||||||
|
} finally {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
case 401: facesContext.addMessage(null, new FacesMessage("Status: 401. Request not authenticated! You need to retrieve access token first."));
|
||||||
|
break;
|
||||||
|
case 403: facesContext.addMessage(null, new FacesMessage("Status: 403. Access token has insufficient privileges"));
|
||||||
|
break;
|
||||||
|
default: facesContext.addMessage(null, new FacesMessage("Status: " + response.getStatusLine() + ". Not able to retrieve data. See log for details"));
|
||||||
|
logger.warn("Error occured. Status: " + response.getStatusLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
facesContext.addMessage(null, new FacesMessage("Unknown error. See log for details"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.faces.application.FacesMessage;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is needed because Faces context is not available in HTTP filters
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Named("messagesChecker")
|
||||||
|
public class MessagesChecker {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@ServletRequestQualifier
|
||||||
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private FacesContext facesContext;
|
||||||
|
|
||||||
|
public String getCheckMessage() {
|
||||||
|
String oauthError = (String)request.getAttribute(RefreshTokenFilter.OAUTH_ERROR_ATTR);
|
||||||
|
if (oauthError != null) {
|
||||||
|
facesContext.addMessage(null, new FacesMessage("OAuth error occured: " + oauthError));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.annotation.WebFilter;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.keycloak.adapters.TokenGrantRequest;
|
||||||
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@WebFilter(value = "/client.jsf")
|
||||||
|
public class RefreshTokenFilter implements Filter {
|
||||||
|
|
||||||
|
public static final String OAUTH_ERROR_ATTR = "oauthErrorAttr";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ServletOAuthClient oauthClient;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private UserData userData;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
|
||||||
|
HttpServletRequest request = (HttpServletRequest)req;
|
||||||
|
HttpServletResponse response = (HttpServletResponse)resp;
|
||||||
|
Map<String, String[]> reqParams = request.getParameterMap();
|
||||||
|
|
||||||
|
if (reqParams.containsKey("code")) {
|
||||||
|
try {
|
||||||
|
String accessToken = oauthClient.getBearerToken(request);
|
||||||
|
userData.setAccessToken(accessToken);
|
||||||
|
} catch (TokenGrantRequest.HttpFailure e) {
|
||||||
|
throw new ServletException(e);
|
||||||
|
}
|
||||||
|
} else if (reqParams.containsKey("error")) {
|
||||||
|
String oauthError = reqParams.get("error")[0];
|
||||||
|
request.setAttribute(OAUTH_ERROR_ATTR, oauthError);
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is needed to have same code working in AS7 and Wildfly. In Wildfly is HttpServletRequest injected automatically, in AS7 it's not
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@Qualifier
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
|
||||||
|
public @interface ServletRequestQualifier {
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.enterprise.context.SessionScoped;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@SessionScoped
|
||||||
|
@Named("userData")
|
||||||
|
public class UserData implements Serializable {
|
||||||
|
|
||||||
|
private String accessToken;
|
||||||
|
private List<String> products;
|
||||||
|
private List<String> customers;
|
||||||
|
|
||||||
|
public String getAccessToken() {
|
||||||
|
return accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessToken(String accessToken) {
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHasAccessToken() {
|
||||||
|
return accessToken != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccessTokenAvailabilityMessage() {
|
||||||
|
StringBuilder builder = new StringBuilder("Access token ");
|
||||||
|
if (!isHasAccessToken()) {
|
||||||
|
builder.append("not ");
|
||||||
|
}
|
||||||
|
return builder.append("available!").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getProducts() {
|
||||||
|
return products;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProducts(List<String> products) {
|
||||||
|
this.products = products;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHasProducts() {
|
||||||
|
return products != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getCustomers() {
|
||||||
|
return customers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCustomers(List<String> customers) {
|
||||||
|
this.customers = customers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHasCustomers() {
|
||||||
|
return customers != null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!--
|
||||||
|
JBoss, Home of Professional Open Source
|
||||||
|
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
|
||||||
|
contributors by the @authors tag. See the copyright.txt in the
|
||||||
|
distribution for a full listing of individual contributors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<!-- Marker file indicating CDI should be enabled -->
|
||||||
|
<beans 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/beans_1_0.xsd">
|
||||||
|
</beans>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
JBoss, Home of Professional Open Source
|
||||||
|
Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
|
||||||
|
contributors by the @authors tag. See the copyright.txt in the
|
||||||
|
distribution for a full listing of individual contributors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<!-- Marker file indicating JSF should be enabled -->
|
||||||
|
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||||
|
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-facesconfig_2_0.xsd">
|
||||||
|
|
||||||
|
</faces-config>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<jboss-deployment-structure>
|
||||||
|
<deployment>
|
||||||
|
<!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->
|
||||||
|
<dependencies>
|
||||||
|
</dependencies>
|
||||||
|
</deployment>
|
||||||
|
</jboss-deployment-structure>
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"resource" : "third-party",
|
||||||
|
"auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/login",
|
||||||
|
"code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes",
|
||||||
|
"ssl-not-required" : true,
|
||||||
|
"credentials" : {
|
||||||
|
"password" : "password"
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"realm": [ "user" ]
|
||||||
|
}
|
||||||
|
}
|
20
examples/wildfly-demo/third-party-cdi/src/main/webapp/WEB-INF/web.xml
Executable file
20
examples/wildfly-demo/third-party-cdi/src/main/webapp/WEB-INF/web.xml
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
<?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>oauth-client-cdi</module-name>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<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>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</web-app>
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html
|
||||||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
|
||||||
|
xmlns:f="http://java.sun.com/jsf/core">
|
||||||
|
<body>
|
||||||
|
<h1>Third Party App That Pulls Data Using OAuth</h1>
|
||||||
|
<h:form>
|
||||||
|
#{userData.accessTokenAvailabilityMessage}
|
||||||
|
<br />
|
||||||
|
<h:commandButton id="retrieve_token" value="Retrieve/refresh access token" action="#{databaseClient.retrieveAccessToken}"/>
|
||||||
|
<h:commandButton id="products_request" value="Load products list" action="#{databaseClient.sendProductsRequest}"/>
|
||||||
|
<h:commandButton id="customers_request" value="Load customers list" action="#{databaseClient.sendCustomersRequest}"/>
|
||||||
|
</h:form>
|
||||||
|
|
||||||
|
<ui:fragment rendered="#{userData.hasProducts}">
|
||||||
|
<hr />
|
||||||
|
<h3>Products data available</h3>
|
||||||
|
<ui:repeat value="#{userData.products}" var="product">
|
||||||
|
#{product}<br/>
|
||||||
|
</ui:repeat>
|
||||||
|
</ui:fragment>
|
||||||
|
|
||||||
|
<ui:fragment rendered="#{userData.hasCustomers}">
|
||||||
|
<hr />
|
||||||
|
<h3>Customers data available</h3>
|
||||||
|
<ui:repeat value="#{userData.customers}" var="customer">
|
||||||
|
#{customer}<br/>
|
||||||
|
</ui:repeat>
|
||||||
|
</ui:fragment>
|
||||||
|
|
||||||
|
<div style="color: red">
|
||||||
|
#{messagesChecker.checkMessage}
|
||||||
|
<h:messages globalOnly="true"/>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Refresh" content="0; URL=client.jsf">
|
||||||
|
</head>
|
||||||
|
</html>
|
|
@ -1,15 +1,19 @@
|
||||||
package org.keycloak.example.oauth;
|
package org.keycloak.example.oauth;
|
||||||
|
|
||||||
import org.keycloak.servlet.ServletOAuthClient;
|
import org.keycloak.servlet.ServletOAuthClient;
|
||||||
|
import org.keycloak.servlet.ServletOAuthClientConfigLoader;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
import javax.servlet.ServletContextListener;
|
import javax.servlet.ServletContextListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stupid init code to load up the truststore so we can make appropriate SSL connections
|
* Init code to load up the truststore so we can make appropriate SSL connections
|
||||||
* You really should use a better way of initializing this stuff.
|
* You really should use a better way of initializing this stuff.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -32,36 +36,34 @@ public class Bootstrap implements ServletContextListener {
|
||||||
@Override
|
@Override
|
||||||
public void contextInitialized(ServletContextEvent sce) {
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
client = new ServletOAuthClient();
|
client = new ServletOAuthClient();
|
||||||
/*
|
ServletContext context = sce.getServletContext();
|
||||||
// hardcoded, WARNING, you should really have a better way of doing this
|
|
||||||
// configuration. Either use something like Spring or CDI, or even pull
|
configureClient(context);
|
||||||
// config vales from context-params
|
|
||||||
String truststorePath = "${jboss.server.config.dir}/client-truststore.ts";
|
|
||||||
String truststorePassword = "password";
|
|
||||||
truststorePath = EnvUtil.replace(truststorePath);
|
|
||||||
KeyStore truststore = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
truststore = loadKeyStore(truststorePath, truststorePassword);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
client.setTruststore(truststore);
|
|
||||||
*/
|
|
||||||
client.setClientId("third-party");
|
|
||||||
client.setPassword("password");
|
|
||||||
client.setAuthUrl("http://localhost:8080/auth-server/rest/realms/demo/tokens/login");
|
|
||||||
client.setCodeUrl("http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes");
|
|
||||||
client.start();
|
client.start();
|
||||||
sce.getServletContext().setAttribute(ServletOAuthClient.class.getName(), client);
|
context.setAttribute(ServletOAuthClient.class.getName(), client);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextDestroyed(ServletContextEvent sce) {
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
client.stop();
|
client.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void configureClient(ServletContext context) {
|
||||||
|
InputStream is = null;
|
||||||
|
String path = context.getInitParameter("keycloak.config.file");
|
||||||
|
if (path == null) {
|
||||||
|
is = context.getResourceAsStream("/WEB-INF/keycloak.json");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
is = new FileInputStream(path);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ServletOAuthClientConfigLoader loader = new ServletOAuthClientConfigLoader(is);
|
||||||
|
loader.initOAuthClientConfiguration(true);
|
||||||
|
loader.configureServletOAuthClient(client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,11 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class ProductDatabaseClient {
|
public class ProductDatabaseClient {
|
||||||
public static void redirect(HttpServletRequest request, HttpServletResponse response) {
|
public static void redirect(HttpServletRequest request, HttpServletResponse response) {
|
||||||
// This is really the worst code ever. The ServletOAuthClient is obtained by getting a context attribute
|
// The ServletOAuthClient is obtained by getting a context attribute
|
||||||
// that is set in the Bootstrap context listenr in this project.
|
// that is set in the Bootstrap context listener in this project.
|
||||||
// You really should come up with a better way to initialize
|
// You really should come up with a better way to initialize
|
||||||
// and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
|
// and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
|
||||||
// and take a look how it works.
|
// and take a look how it works. You can also take a look at third-party-cdi example
|
||||||
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
||||||
try {
|
try {
|
||||||
oAuthClient.redirectRelative("pull_data.jsp", request, response);
|
oAuthClient.redirectRelative("pull_data.jsp", request, response);
|
||||||
|
@ -37,11 +37,11 @@ public class ProductDatabaseClient {
|
||||||
static class TypedList extends ArrayList<String> {}
|
static class TypedList extends ArrayList<String> {}
|
||||||
|
|
||||||
public static List<String> getProducts(HttpServletRequest request) {
|
public static List<String> getProducts(HttpServletRequest request) {
|
||||||
// This is really the worst code ever. The ServletOAuthClient is obtained by getting a context attribute
|
// The ServletOAuthClient is obtained by getting a context attribute
|
||||||
// that is set in the Bootstrap context listenr in this project.
|
// that is set in the Bootstrap context listener in this project.
|
||||||
// You really should come up with a better way to initialize
|
// You really should come up with a better way to initialize
|
||||||
// and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
|
// and obtain the ServletOAuthClient. I actually suggest downloading the ServletOAuthClient code
|
||||||
// and take a look how it works.
|
// and take a look how it works. You can also take a look at third-party-cdi example
|
||||||
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
ServletOAuthClient oAuthClient = (ServletOAuthClient) request.getServletContext().getAttribute(ServletOAuthClient.class.getName());
|
||||||
String token = null;
|
String token = null;
|
||||||
try {
|
try {
|
||||||
|
|
12
examples/wildfly-demo/third-party/src/main/webapp/WEB-INF/keycloak.json
vendored
Normal file
12
examples/wildfly-demo/third-party/src/main/webapp/WEB-INF/keycloak.json
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"resource" : "third-party",
|
||||||
|
"auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/login",
|
||||||
|
"code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes",
|
||||||
|
"ssl-not-required" : true,
|
||||||
|
"credentials" : {
|
||||||
|
"password" : "password"
|
||||||
|
},
|
||||||
|
"scope": {
|
||||||
|
"realm": [ "user" ]
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,10 @@ package org.keycloak.adapters.config;
|
||||||
|
|
||||||
import org.codehaus.jackson.map.ObjectMapper;
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
||||||
|
import org.keycloak.representations.SkeletonKeyScope;
|
||||||
|
import org.keycloak.util.Base64Url;
|
||||||
import org.keycloak.util.EnvUtil;
|
import org.keycloak.util.EnvUtil;
|
||||||
|
import org.keycloak.util.JsonSerialization;
|
||||||
import org.keycloak.util.PemUtils;
|
import org.keycloak.util.PemUtils;
|
||||||
import org.keycloak.adapters.ResourceMetadata;
|
import org.keycloak.adapters.ResourceMetadata;
|
||||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||||
|
@ -35,29 +38,8 @@ public class AdapterConfigLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
String truststorePath = adapterConfig.getTruststore();
|
initTruststore();
|
||||||
if (truststorePath != null) {
|
initClientKeystore();
|
||||||
truststorePath = EnvUtil.replace(truststorePath);
|
|
||||||
String truststorePassword = adapterConfig.getTruststorePassword();
|
|
||||||
truststorePath = null;
|
|
||||||
try {
|
|
||||||
this.truststore = loadKeyStore(truststorePath, truststorePassword);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Failed to load truststore", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String clientKeystore = adapterConfig.getClientKeystore();
|
|
||||||
String clientKeyPassword = null;
|
|
||||||
if (clientKeystore != null) {
|
|
||||||
clientKeystore = EnvUtil.replace(clientKeystore);
|
|
||||||
String clientKeystorePassword = adapterConfig.getClientKeystorePassword();
|
|
||||||
clientCertKeystore = null;
|
|
||||||
try {
|
|
||||||
clientCertKeystore = loadKeyStore(clientKeystore, clientKeystorePassword);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Failed to load keystore", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String realm = adapterConfig.getRealm();
|
String realm = adapterConfig.getRealm();
|
||||||
if (realm == null) throw new RuntimeException("Must set 'realm' in config");
|
if (realm == null) throw new RuntimeException("Must set 'realm' in config");
|
||||||
|
@ -81,10 +63,15 @@ public class AdapterConfigLoader {
|
||||||
resourceMetadata.setResourceName(resource);
|
resourceMetadata.setResourceName(resource);
|
||||||
resourceMetadata.setRealmKey(realmKey);
|
resourceMetadata.setRealmKey(realmKey);
|
||||||
resourceMetadata.setClientKeystore(clientCertKeystore);
|
resourceMetadata.setClientKeystore(clientCertKeystore);
|
||||||
clientKeyPassword = adapterConfig.getClientKeyPassword();
|
String clientKeyPassword = adapterConfig.getClientKeyPassword();
|
||||||
resourceMetadata.setClientKeyPassword(clientKeyPassword);
|
resourceMetadata.setClientKeyPassword(clientKeyPassword);
|
||||||
resourceMetadata.setTruststore(this.truststore);
|
resourceMetadata.setTruststore(this.truststore);
|
||||||
|
|
||||||
|
if (adapterConfig.getScope() != null) {
|
||||||
|
String scope = encodeScope(adapterConfig.getScope());
|
||||||
|
resourceMetadata.setScope(scope);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AdapterConfig getAdapterConfig() {
|
public AdapterConfig getAdapterConfig() {
|
||||||
|
@ -113,4 +100,40 @@ public class AdapterConfigLoader {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void initTruststore() {
|
||||||
|
String truststorePath = adapterConfig.getTruststore();
|
||||||
|
if (truststorePath != null) {
|
||||||
|
truststorePath = EnvUtil.replace(truststorePath);
|
||||||
|
String truststorePassword = adapterConfig.getTruststorePassword();
|
||||||
|
try {
|
||||||
|
this.truststore = loadKeyStore(truststorePath, truststorePassword);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to load truststore", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initClientKeystore() {
|
||||||
|
String clientKeystore = adapterConfig.getClientKeystore();
|
||||||
|
if (clientKeystore != null) {
|
||||||
|
clientKeystore = EnvUtil.replace(clientKeystore);
|
||||||
|
String clientKeystorePassword = adapterConfig.getClientKeystorePassword();
|
||||||
|
clientCertKeystore = null;
|
||||||
|
try {
|
||||||
|
clientCertKeystore = loadKeyStore(clientKeystore, clientKeystorePassword);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to load keystore", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String encodeScope(SkeletonKeyScope scope) {
|
||||||
|
try {
|
||||||
|
byte[] scopeBytes = JsonSerialization.writeValueAsBytes(scope);
|
||||||
|
return Base64Url.encode(scopeBytes);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.keycloak.adapters.config;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.keycloak.AbstractOAuthClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public abstract class OAuthClientConfigLoader extends RealmConfigurationLoader {
|
||||||
|
|
||||||
|
public OAuthClientConfigLoader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public OAuthClientConfigLoader(InputStream is) {
|
||||||
|
super(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For now, configure just things supported by AbstractOAuthClient
|
||||||
|
*/
|
||||||
|
public void initOAuthClientConfiguration() {
|
||||||
|
initTruststore();
|
||||||
|
initClientKeystore();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configureOAuthClient(AbstractOAuthClient oauthClient) {
|
||||||
|
oauthClient.setClientId(adapterConfig.getResource());
|
||||||
|
oauthClient.setPassword(adapterConfig.getCredentials().get("password"));
|
||||||
|
oauthClient.setAuthUrl(adapterConfig.getAuthUrl());
|
||||||
|
oauthClient.setCodeUrl(adapterConfig.getCodeUrl());
|
||||||
|
oauthClient.setTruststore(truststore);
|
||||||
|
if (adapterConfig.getScope() != null) {
|
||||||
|
String scope = encodeScope(adapterConfig.getScope());
|
||||||
|
oauthClient.setScope(scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -138,12 +138,15 @@ public class ServletOAuthLogin {
|
||||||
if (port != 443) secureUrl.port(port);
|
if (port != 443) secureUrl.port(port);
|
||||||
url = secureUrl.build().toString();
|
url = secureUrl.build().toString();
|
||||||
}
|
}
|
||||||
return realmInfo.getAuthUrl().clone()
|
KeycloakUriBuilder uriBuilder = realmInfo.getAuthUrl().clone()
|
||||||
.queryParam("client_id", realmInfo.getMetadata().getResourceName())
|
.queryParam("client_id", realmInfo.getMetadata().getResourceName())
|
||||||
.queryParam("redirect_uri", url)
|
.queryParam("redirect_uri", url)
|
||||||
.queryParam("state", state)
|
.queryParam("state", state)
|
||||||
.queryParam("login", "true")
|
.queryParam("login", "true");
|
||||||
.build().toString();
|
if (realmInfo.getMetadata().getScope() != null) {
|
||||||
|
uriBuilder.queryParam("scope", realmInfo.getMetadata().getScope());
|
||||||
|
}
|
||||||
|
return uriBuilder.build().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static final AtomicLong counter = new AtomicLong();
|
protected static final AtomicLong counter = new AtomicLong();
|
||||||
|
|
|
@ -18,6 +18,7 @@ import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper code to obtain oauth access tokens via browser redirects
|
* Helper code to obtain oauth access tokens via browser redirects
|
||||||
|
@ -87,11 +88,15 @@ public class JaxrsOAuthClient extends AbstractOAuthClient {
|
||||||
state += "#" + path;
|
state += "#" + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
URI url = UriBuilder.fromUri(authUrl)
|
UriBuilder uriBuilder = UriBuilder.fromUri(authUrl)
|
||||||
.queryParam("client_id", clientId)
|
.queryParam("client_id", clientId)
|
||||||
.queryParam("redirect_uri", redirectUri)
|
.queryParam("redirect_uri", redirectUri)
|
||||||
.queryParam("state", state)
|
.queryParam("state", state);
|
||||||
.build();
|
if (scope != null) {
|
||||||
|
uriBuilder.queryParam("scope", scope);
|
||||||
|
}
|
||||||
|
URI url = uriBuilder.build();
|
||||||
|
|
||||||
NewCookie cookie = new NewCookie(getStateCookieName(), state, getStateCookiePath(uriInfo), null, null, -1, isSecure, true);
|
NewCookie cookie = new NewCookie(getStateCookieName(), state, getStateCookiePath(uriInfo), null, null, -1, isSecure, true);
|
||||||
logger.debug("NewCookie: " + cookie.toString());
|
logger.debug("NewCookie: " + cookie.toString());
|
||||||
logger.debug("Oauth Redirect to: " + url);
|
logger.debug("Oauth Redirect to: " + url);
|
||||||
|
|
|
@ -84,11 +84,15 @@ public class ServletOAuthClient extends AbstractOAuthClient {
|
||||||
public void redirect(String redirectUri, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
public void redirect(String redirectUri, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
String state = getStateCode();
|
String state = getStateCode();
|
||||||
|
|
||||||
URI url = KeycloakUriBuilder.fromUri(authUrl)
|
KeycloakUriBuilder uriBuilder = KeycloakUriBuilder.fromUri(authUrl)
|
||||||
.queryParam("client_id", clientId)
|
.queryParam("client_id", clientId)
|
||||||
.queryParam("redirect_uri", redirectUri)
|
.queryParam("redirect_uri", redirectUri)
|
||||||
.queryParam("state", state)
|
.queryParam("state", state);
|
||||||
.build();
|
if (scope != null) {
|
||||||
|
uriBuilder.queryParam("scope", scope);
|
||||||
|
}
|
||||||
|
URI url = uriBuilder.build();
|
||||||
|
|
||||||
String stateCookiePath = this.stateCookiePath;
|
String stateCookiePath = this.stateCookiePath;
|
||||||
if (stateCookiePath == null) stateCookiePath = request.getContextPath();
|
if (stateCookiePath == null) stateCookiePath = request.getContextPath();
|
||||||
if (stateCookiePath.equals("")) stateCookiePath = "/";
|
if (stateCookiePath.equals("")) stateCookiePath = "/";
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.keycloak.servlet;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.keycloak.adapters.config.OAuthClientConfigLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class ServletOAuthClientConfigLoader extends OAuthClientConfigLoader {
|
||||||
|
|
||||||
|
public ServletOAuthClientConfigLoader() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServletOAuthClientConfigLoader(InputStream is) {
|
||||||
|
super(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For now, configure just things supported by ServletOAuthClient
|
||||||
|
* @param setupClient
|
||||||
|
*/
|
||||||
|
public void initOAuthClientConfiguration(boolean setupClient) {
|
||||||
|
initOAuthClientConfiguration();
|
||||||
|
if (setupClient) {
|
||||||
|
initClient();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configureServletOAuthClient(ServletOAuthClient oauthClient) {
|
||||||
|
configureOAuthClient(oauthClient);
|
||||||
|
if (client != null) {
|
||||||
|
oauthClient.setClient(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue