commit
bbb2e738fc
39 changed files with 769 additions and 66 deletions
|
@ -16,6 +16,8 @@ public class RealmRepresentation {
|
||||||
protected boolean enabled;
|
protected boolean enabled;
|
||||||
protected boolean sslNotRequired;
|
protected boolean sslNotRequired;
|
||||||
protected boolean cookieLoginAllowed;
|
protected boolean cookieLoginAllowed;
|
||||||
|
protected String privateKey;
|
||||||
|
protected String publicKey;
|
||||||
protected Set<String> roles;
|
protected Set<String> roles;
|
||||||
protected List<RequiredCredentialRepresentation> requiredCredentials;
|
protected List<RequiredCredentialRepresentation> requiredCredentials;
|
||||||
protected List<UserRepresentation> users;
|
protected List<UserRepresentation> users;
|
||||||
|
@ -151,4 +153,20 @@ public class RealmRepresentation {
|
||||||
public void setRoles(Set<String> roles) {
|
public void setRoles(Set<String> roles) {
|
||||||
this.roles = roles;
|
this.roles = roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivateKey(String privateKey) {
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPublicKey() {
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublicKey(String publicKey) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
79
examples/as7-eap-demo/customer-app/pom.xml
Executable file
79
examples/as7-eap-demo/customer-app/pom.xml
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
<?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</version>
|
||||||
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.keycloak.example.as7.demo</groupId>
|
||||||
|
<artifactId>customer-portal-example</artifactId>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>Customer Portal - Secured via Valve</name>
|
||||||
|
<description/>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jboss</id>
|
||||||
|
<name>jboss repo</name>
|
||||||
|
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>servlet-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
<artifactId>resteasy-client</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-as7-adapter</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>customer-portal</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,36 @@
|
||||||
|
package org.jboss.resteasy.example.oauth;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
|
||||||
|
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
|
||||||
|
import org.keycloak.SkeletonKeySession;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.ws.rs.core.GenericType;
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class CustomerDatabaseClient
|
||||||
|
{
|
||||||
|
public static List<String> getCustomers(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
SkeletonKeySession session = (SkeletonKeySession)request.getAttribute(SkeletonKeySession.class.getName());
|
||||||
|
ResteasyClient client = new ResteasyClientBuilder()
|
||||||
|
.trustStore(session.getMetadata().getTruststore())
|
||||||
|
.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY).build();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Response response = client.target("http://localhost:8080/database/customers").request()
|
||||||
|
.header(HttpHeaders.AUTHORIZATION, "Bearer " + session.getToken()).get();
|
||||||
|
return response.readEntity(new GenericType<List<String>>(){});
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
<jboss-deployment-structure>
|
||||||
|
<deployment>
|
||||||
|
<!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->
|
||||||
|
<dependencies>
|
||||||
|
<module name="org.bouncycastle"/>
|
||||||
|
<module name="org.jboss.resteasy.resteasy-jaxrs" services="import"/>
|
||||||
|
<module name="org.jboss.resteasy.resteasy-jackson-provider" services="import"/>
|
||||||
|
<module name="org.jboss.resteasy.jose-jwt" />
|
||||||
|
</dependencies>
|
||||||
|
</deployment>
|
||||||
|
</jboss-deployment-structure>
|
5
examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/jboss-web.xml
Executable file
5
examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/jboss-web.xml
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
<jboss-web>
|
||||||
|
<valve>
|
||||||
|
<class-name>org.keycloak.adapters.as7.OAuthManagedResourceValve</class-name>
|
||||||
|
</valve>
|
||||||
|
</jboss-web>
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"realm" : "demo",
|
||||||
|
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||||
|
"auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/auth/request",
|
||||||
|
"code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes",
|
||||||
|
"ssl-not-required" : true,
|
||||||
|
"client-id" : "customer-portal",
|
||||||
|
"client-credentials" : {
|
||||||
|
"password" : "password"
|
||||||
|
}
|
||||||
|
}
|
46
examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/web.xml
Executable file
46
examples/as7-eap-demo/customer-app/src/main/webapp/WEB-INF/web.xml
Executable file
|
@ -0,0 +1,46 @@
|
||||||
|
<?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">
|
||||||
|
<security-constraint>
|
||||||
|
<web-resource-collection>
|
||||||
|
<web-resource-name>Admins</web-resource-name>
|
||||||
|
<url-pattern>/admin/*</url-pattern>
|
||||||
|
</web-resource-collection>
|
||||||
|
<auth-constraint>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</auth-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>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</web-resource-collection>
|
||||||
|
<user-data-constraint>
|
||||||
|
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||||
|
</user-data-constraint>
|
||||||
|
</security-constraint> -->
|
||||||
|
|
||||||
|
<login-config>
|
||||||
|
<auth-method>BASIC</auth-method>
|
||||||
|
<realm-name>commerce</realm-name>
|
||||||
|
</login-config>
|
||||||
|
|
||||||
|
<security-role>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</security-role>
|
||||||
|
<security-role>
|
||||||
|
<role-name>user</role-name>
|
||||||
|
</security-role>
|
||||||
|
</web-app>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||||
|
pageEncoding="ISO-8859-1"%>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Customer Admin Iterface</title>
|
||||||
|
</head>
|
||||||
|
<body bgcolor="#E3F6CE">
|
||||||
|
<h1>Customer Admin Interface</h1>
|
||||||
|
User <b><%=request.getUserPrincipal().getName()%></b> made this request.
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||||
|
pageEncoding="ISO-8859-1"%>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Customer View Page</title>
|
||||||
|
</head>
|
||||||
|
<body bgcolor="#E3F6CE">
|
||||||
|
<p>Goto: <a href="https://localhost:8443/product-portal">products</a> | <a href="https://localhost:8443/auth-server/j_oauth_logout">logout</a></p>
|
||||||
|
User <b><%=request.getUserPrincipal().getName()%></b> made this request.
|
||||||
|
<h2>Customer Listing</h2>
|
||||||
|
<%
|
||||||
|
java.util.List<String> list = org.jboss.resteasy.example.oauth.CustomerDatabaseClient.getCustomers(request);
|
||||||
|
for (String cust : list)
|
||||||
|
{
|
||||||
|
out.print("<p>");
|
||||||
|
out.print(cust);
|
||||||
|
out.println("</p>");
|
||||||
|
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
<br><br>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<!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>
|
||||||
|
<p><a href="admin/admin.html">Customer Admin Interface</a></p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
73
examples/as7-eap-demo/database-service/pom.xml
Executable file
73
examples/as7-eap-demo/database-service/pom.xml
Executable file
|
@ -0,0 +1,73 @@
|
||||||
|
<?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</version>
|
||||||
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.keycloak.example.as7.demo</groupId>
|
||||||
|
<artifactId>database-service</artifactId>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>JAX-RS Database Service Using OAuth Bearer Tokens</name>
|
||||||
|
<description/>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jboss</id>
|
||||||
|
<name>jboss repo</name>
|
||||||
|
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
<artifactId>resteasy-client</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
<artifactId>resteasy-client</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-as7-adapter</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>database</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-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.6</source>
|
||||||
|
<target>1.6</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.jboss.resteasy.example.oauth;
|
||||||
|
|
||||||
|
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")
|
||||||
|
public List<String> getCustomers()
|
||||||
|
{
|
||||||
|
ArrayList<String> rtn = new ArrayList<String>();
|
||||||
|
rtn.add("Bill Burke");
|
||||||
|
rtn.add("Ron Sigal");
|
||||||
|
rtn.add("Weinan Li");
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.jboss.resteasy.example.oauth;
|
||||||
|
|
||||||
|
import javax.ws.rs.ApplicationPath;
|
||||||
|
import javax.ws.rs.core.Application;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
@ApplicationPath("/")
|
||||||
|
public class DataApplication extends Application
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.jboss.resteasy.example.oauth;
|
||||||
|
|
||||||
|
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")
|
||||||
|
public List<String> getProducts()
|
||||||
|
{
|
||||||
|
ArrayList<String> rtn = new ArrayList<String>();
|
||||||
|
rtn.add("iphone");
|
||||||
|
rtn.add("ipad");
|
||||||
|
rtn.add("ipod");
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<jboss-deployment-structure>
|
||||||
|
<deployment>
|
||||||
|
<!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->
|
||||||
|
<dependencies>
|
||||||
|
<module name="org.bouncycastle"/>
|
||||||
|
<module name="org.jboss.resteasy.jose-jwt" />
|
||||||
|
</dependencies>
|
||||||
|
</deployment>
|
||||||
|
</jboss-deployment-structure>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<jboss-web>
|
||||||
|
<valve>
|
||||||
|
<class-name>org.keycloak.adapters.as7.BearerTokenAuthenticatorValve</class-name>
|
||||||
|
</valve>
|
||||||
|
</jboss-web>
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"realm" : "demo",
|
||||||
|
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB"
|
||||||
|
}
|
26
examples/as7-eap-demo/database-service/src/main/webapp/WEB-INF/web.xml
Executable file
26
examples/as7-eap-demo/database-service/src/main/webapp/WEB-INF/web.xml
Executable file
|
@ -0,0 +1,26 @@
|
||||||
|
<?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">
|
||||||
|
<security-constraint>
|
||||||
|
<web-resource-collection>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</web-resource-collection>
|
||||||
|
<!-- <user-data-constraint>
|
||||||
|
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
|
||||||
|
</user-data-constraint> -->
|
||||||
|
<auth-constraint>
|
||||||
|
<role-name>user</role-name>
|
||||||
|
</auth-constraint>
|
||||||
|
</security-constraint>
|
||||||
|
|
||||||
|
<login-config>
|
||||||
|
<auth-method>BASIC</auth-method>
|
||||||
|
<realm-name>commerce</realm-name>
|
||||||
|
</login-config>
|
||||||
|
|
||||||
|
<security-role>
|
||||||
|
<role-name>user</role-name>
|
||||||
|
</security-role>
|
||||||
|
</web-app>
|
79
examples/as7-eap-demo/product-app/pom.xml
Executable file
79
examples/as7-eap-demo/product-app/pom.xml
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
<?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</version>
|
||||||
|
<relativePath>../../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.keycloak.example.as7.demo</groupId>
|
||||||
|
<artifactId>product-portal-example</artifactId>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>Product Portal - Secured via Valve</name>
|
||||||
|
<description/>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jboss</id>
|
||||||
|
<name>jboss repo</name>
|
||||||
|
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>servlet-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
<artifactId>resteasy-client</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-as7-adapter</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>product-portal</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,11 @@
|
||||||
|
<jboss-deployment-structure>
|
||||||
|
<deployment>
|
||||||
|
<!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->
|
||||||
|
<dependencies>
|
||||||
|
<module name="org.bouncycastle"/>
|
||||||
|
<module name="org.jboss.resteasy.resteasy-jaxrs" services="import"/>
|
||||||
|
<module name="org.jboss.resteasy.resteasy-jackson-provider" services="import"/>
|
||||||
|
<module name="org.jboss.resteasy.jose-jwt" />
|
||||||
|
</dependencies>
|
||||||
|
</deployment>
|
||||||
|
</jboss-deployment-structure>
|
5
examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/jboss-web.xml
Executable file
5
examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/jboss-web.xml
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
<jboss-web>
|
||||||
|
<valve>
|
||||||
|
<class-name>org.keycloak.adapters.as7.OAuthManagedResourceValve</class-name>
|
||||||
|
</valve>
|
||||||
|
</jboss-web>
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"realm" : "demo",
|
||||||
|
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||||
|
"auth-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/auth/request",
|
||||||
|
"code-url" : "http://localhost:8080/auth-server/rest/realms/demo/tokens/access/codes",
|
||||||
|
"ssl-not-required" : true,
|
||||||
|
"client-id" : "product-portal",
|
||||||
|
"client-credentials" : {
|
||||||
|
"password" : "password"
|
||||||
|
}
|
||||||
|
}
|
46
examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/web.xml
Executable file
46
examples/as7-eap-demo/product-app/src/main/webapp/WEB-INF/web.xml
Executable file
|
@ -0,0 +1,46 @@
|
||||||
|
<?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">
|
||||||
|
<security-constraint>
|
||||||
|
<web-resource-collection>
|
||||||
|
<web-resource-name>Admins</web-resource-name>
|
||||||
|
<url-pattern>/admin/*</url-pattern>
|
||||||
|
</web-resource-collection>
|
||||||
|
<auth-constraint>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</auth-constraint>
|
||||||
|
</security-constraint>
|
||||||
|
<security-constraint>
|
||||||
|
<web-resource-collection>
|
||||||
|
<web-resource-name>Products</web-resource-name>
|
||||||
|
<url-pattern>/products/*</url-pattern>
|
||||||
|
</web-resource-collection>
|
||||||
|
<auth-constraint>
|
||||||
|
<role-name>user</role-name>
|
||||||
|
</auth-constraint>
|
||||||
|
</security-constraint>
|
||||||
|
<!--
|
||||||
|
<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>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<login-config>
|
||||||
|
<auth-method>BASIC</auth-method>
|
||||||
|
<realm-name>commerce</realm-name>
|
||||||
|
</login-config>
|
||||||
|
|
||||||
|
<security-role>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</security-role>
|
||||||
|
<security-role>
|
||||||
|
<role-name>user</role-name>
|
||||||
|
</security-role>
|
||||||
|
</web-app>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||||
|
pageEncoding="ISO-8859-1"%>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Product Admin Interface</title>
|
||||||
|
</head>
|
||||||
|
<body bgcolor="#F5F6CE">
|
||||||
|
<h1>Product Admin Interface</h1>
|
||||||
|
User <b><%=request.getUserPrincipal().getName()%></b> made this request.
|
||||||
|
</body>
|
||||||
|
</html>
|
14
examples/as7-eap-demo/product-app/src/main/webapp/index.html
Normal file
14
examples/as7-eap-demo/product-app/src/main/webapp/index.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!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="#F5F6CE">
|
||||||
|
<h1>Product Portal</h1>
|
||||||
|
|
||||||
|
<p><a href="products/view.jsp">Product Listing</a></p>
|
||||||
|
<p><a href="admin/admin.html">Admin Interface</a></p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||||
|
pageEncoding="ISO-8859-1"%>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Product View Page</title>
|
||||||
|
</head>
|
||||||
|
<body bgcolor="#F5F6CE">
|
||||||
|
<p>Goto: <a href="https://localhost:8443/customer-portal">customers</a> | <a href="https://localhost:8443/auth-server/j_oauth_logout">logout</a></p>
|
||||||
|
User <b><%=request.getUserPrincipal().getName()%></b> made this request.
|
||||||
|
<h2>Product Listing</h2>
|
||||||
|
<%
|
||||||
|
java.util.List<String> list = org.jboss.resteasy.example.oauth.ProductDatabaseClient.getProducts(request);
|
||||||
|
for (String cust : list)
|
||||||
|
{
|
||||||
|
out.print("<p>");
|
||||||
|
out.print(cust);
|
||||||
|
out.println("</p>");
|
||||||
|
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
<br><br>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -3,6 +3,8 @@
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"tokenLifespan" : 6000,
|
"tokenLifespan" : 6000,
|
||||||
"accessCodeLifespan" : 30,
|
"accessCodeLifespan" : 30,
|
||||||
|
"privateKey" : "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
|
||||||
|
"publicKey" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||||
"requiredCredentials" : [
|
"requiredCredentials" : [
|
||||||
{
|
{
|
||||||
"type" : "Password",
|
"type" : "Password",
|
||||||
|
@ -12,90 +14,47 @@
|
||||||
],
|
],
|
||||||
"users" : [
|
"users" : [
|
||||||
{
|
{
|
||||||
"username" : "wburke",
|
"username" : "bburke@redhat.com",
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"attributes" : {
|
"attributes" : {
|
||||||
"email" : "bburke@redhat.com"
|
"email" : "bburke@redhat.com"
|
||||||
},
|
},
|
||||||
"credentials" : [
|
"credentials" : [
|
||||||
{ "type" : "Password",
|
{ "type" : "Password",
|
||||||
"value" : "userpassword" }
|
"value" : "password" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"username" : "loginclient",
|
"username" : "customer-portal",
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"credentials" : [
|
"credentials" : [
|
||||||
{ "type" : "Password",
|
{ "type" : "Password",
|
||||||
"value" : "clientpassword" }
|
"value" : "password" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"username" : "admin",
|
"username" : "product-portal",
|
||||||
"enabled" : true,
|
"enabled" : true,
|
||||||
"credentials" : [
|
"credentials" : [
|
||||||
{ "type" : "Password",
|
{ "type" : "Password",
|
||||||
"value" : "adminpassword" }
|
"value" : "password" }
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"username" : "oauthclient",
|
|
||||||
"enabled" : true,
|
|
||||||
"credentials" : [
|
|
||||||
{ "type" : "Password",
|
|
||||||
"value" : "clientpassword" }
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"roleMappings" : [
|
"roleMappings" : [
|
||||||
{
|
{
|
||||||
"username" : "admin",
|
"username" : "bburke@redhat.com",
|
||||||
"roles" : ["admin"]
|
"roles" : ["user"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"scopeMappings" : [
|
"scopeMappings" : [
|
||||||
{
|
{
|
||||||
"username" : "loginclient",
|
"username" : "customer-portal",
|
||||||
|
"roles" : ["*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"username" : "product-portal",
|
||||||
"roles" : ["*"]
|
"roles" : ["*"]
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"resources" : [
|
|
||||||
{
|
|
||||||
"name" : "Application",
|
|
||||||
"roles" : ["admin", "user"],
|
|
||||||
"roleMappings" : [
|
|
||||||
{
|
|
||||||
"username" : "wburke",
|
|
||||||
"roles" : ["user"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"username" : "admin",
|
|
||||||
"roles" : ["admin"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"scopeMappings" : [
|
|
||||||
{
|
|
||||||
"username" : "oauthclient",
|
|
||||||
"roles" : ["user"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "OtherApp",
|
|
||||||
"roles" : ["admin", "user"],
|
|
||||||
"roleMappings" : [
|
|
||||||
{
|
|
||||||
"username" : "wburke",
|
|
||||||
"roles" : ["user"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"username" : "admin",
|
|
||||||
"roles" : ["admin"]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -14,7 +14,29 @@
|
||||||
<artifactId>examples-pom</artifactId>
|
<artifactId>examples-pom</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jboss.as.plugins</groupId>
|
||||||
|
<artifactId>jboss-as-maven-plugin</artifactId>
|
||||||
|
<version>7.1.1.Final</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
<modules>
|
<modules>
|
||||||
<module>as7-eap-demo/server</module>
|
<module>as7-eap-demo/server</module>
|
||||||
|
<module>as7-eap-demo/customer-app</module>
|
||||||
|
<module>as7-eap-demo/product-app</module>
|
||||||
|
<module>as7-eap-demo/database-service</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -28,12 +28,13 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jboss.resteasy</groupId>
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
<artifactId>jose-jwt</artifactId>
|
<artifactId>jose-jwt</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||||
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
|
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
|
||||||
<scope>provided</scope>
|
|
||||||
<version>1.0.0.Final</version>
|
<version>1.0.0.Final</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jboss.resteasy</groupId>
|
<groupId>org.jboss.resteasy</groupId>
|
||||||
|
@ -56,12 +57,13 @@
|
||||||
<groupId>org.jboss.as</groupId>
|
<groupId>org.jboss.as</groupId>
|
||||||
<artifactId>jboss-as-web</artifactId>
|
<artifactId>jboss-as-web</artifactId>
|
||||||
<version>7.1.2.Final</version>
|
<version>7.1.2.Final</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.picketbox</groupId>
|
<groupId>org.picketbox</groupId>
|
||||||
<artifactId>picketbox</artifactId>
|
<artifactId>picketbox</artifactId>
|
||||||
<scope>provided</scope>
|
|
||||||
<version>4.0.7.Final</version>
|
<version>4.0.7.Final</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
|
|
|
@ -46,9 +46,9 @@ public class BearerTokenAuthenticatorValve extends AuthenticatorBase implements
|
||||||
|
|
||||||
protected void init() {
|
protected void init() {
|
||||||
ManagedResourceConfigLoader managedResourceConfigLoader = new ManagedResourceConfigLoader(context);
|
ManagedResourceConfigLoader managedResourceConfigLoader = new ManagedResourceConfigLoader(context);
|
||||||
resourceMetadata = managedResourceConfigLoader.getResourceMetadata();
|
|
||||||
remoteSkeletonKeyConfig = managedResourceConfigLoader.getRemoteSkeletonKeyConfig();
|
remoteSkeletonKeyConfig = managedResourceConfigLoader.getRemoteSkeletonKeyConfig();
|
||||||
managedResourceConfigLoader.init(false);
|
managedResourceConfigLoader.init(false);
|
||||||
|
resourceMetadata = managedResourceConfigLoader.getResourceMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -82,6 +82,7 @@ public class OAuthManagedResourceValve extends FormAuthenticator implements Life
|
||||||
}
|
}
|
||||||
realmConfiguration.setMetadata(resourceMetadata);
|
realmConfiguration.setMetadata(resourceMetadata);
|
||||||
realmConfiguration.setClientId(client_id);
|
realmConfiguration.setClientId(client_id);
|
||||||
|
realmConfiguration.setSslRequired(!remoteSkeletonKeyConfig.isSslNotRequired());
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getClientCredentials().entrySet()) {
|
for (Map.Entry<String, String> entry : managedResourceConfigLoader.getRemoteSkeletonKeyConfig().getClientCredentials().entrySet()) {
|
||||||
realmConfiguration.getCredentials().param(entry.getKey(), entry.getValue());
|
realmConfiguration.getCredentials().param(entry.getKey(), entry.getValue());
|
||||||
|
|
|
@ -7,6 +7,7 @@ import org.keycloak.RealmConfiguration;
|
||||||
import org.keycloak.VerificationException;
|
import org.keycloak.VerificationException;
|
||||||
import org.keycloak.representations.AccessTokenResponse;
|
import org.keycloak.representations.AccessTokenResponse;
|
||||||
import org.keycloak.representations.SkeletonKeyToken;
|
import org.keycloak.representations.SkeletonKeyToken;
|
||||||
|
import org.keycloak.representations.idm.RequiredCredentialRepresentation;
|
||||||
|
|
||||||
import javax.servlet.http.Cookie;
|
import javax.servlet.http.Cookie;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -77,6 +78,7 @@ public class ServletOAuthLogin {
|
||||||
|
|
||||||
protected void sendRedirect(String url) {
|
protected void sendRedirect(String url) {
|
||||||
try {
|
try {
|
||||||
|
log.info("Sending redirect to: " + url);
|
||||||
response.sendRedirect(url);
|
response.sendRedirect(url);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
@ -223,18 +225,26 @@ public class ServletOAuthLogin {
|
||||||
|
|
||||||
String client_id = realmInfo.getClientId();
|
String client_id = realmInfo.getClientId();
|
||||||
String password = realmInfo.getCredentials().asMap().getFirst("password");
|
String password = realmInfo.getCredentials().asMap().getFirst("password");
|
||||||
String authHeader = BasicAuthHelper.createHeader(client_id, password);
|
//String authHeader = BasicAuthHelper.createHeader(client_id, password);
|
||||||
String redirectUri = stripOauthParametersFromRedirect();
|
String redirectUri = stripOauthParametersFromRedirect();
|
||||||
Form form = new Form();
|
Form form = new Form();
|
||||||
form.param("grant_type", "authorization_code")
|
form.param("grant_type", "authorization_code")
|
||||||
.param("code", code)
|
.param("code", code)
|
||||||
|
.param("client_id", client_id)
|
||||||
|
.param(RequiredCredentialRepresentation.PASSWORD, password)
|
||||||
.param("redirect_uri", redirectUri);
|
.param("redirect_uri", redirectUri);
|
||||||
|
|
||||||
Response res = realmInfo.getCodeUrl().request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(form));
|
Response res = realmInfo.getCodeUrl().request()
|
||||||
|
//.header(HttpHeaders.AUTHORIZATION, authHeader)
|
||||||
|
.post(Entity.form(form));
|
||||||
AccessTokenResponse tokenResponse;
|
AccessTokenResponse tokenResponse;
|
||||||
try {
|
try {
|
||||||
if (res.getStatus() != 200) {
|
if (res.getStatus() != 200) {
|
||||||
log.error("failed to turn code into token");
|
log.error("failed to turn code into token");
|
||||||
|
log.error("status from server: " + res.getStatus());
|
||||||
|
if (res.getStatus() == 400 && res.getMediaType() != null) {
|
||||||
|
log.error(" " + res.readEntity(String.class));
|
||||||
|
}
|
||||||
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -248,7 +258,7 @@ public class ServletOAuthLogin {
|
||||||
tokenString = tokenResponse.getToken();
|
tokenString = tokenResponse.getToken();
|
||||||
try {
|
try {
|
||||||
token = RSATokenVerifier.verifyToken(tokenString, realmInfo.getMetadata());
|
token = RSATokenVerifier.verifyToken(tokenString, realmInfo.getMetadata());
|
||||||
log.debug("Verification succeeded!");
|
log.info("Token Verification succeeded!");
|
||||||
} catch (VerificationException e) {
|
} catch (VerificationException e) {
|
||||||
log.error("failed verification of token");
|
log.error("failed verification of token");
|
||||||
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
sendError(Response.Status.FORBIDDEN.getStatusCode());
|
||||||
|
|
|
@ -27,6 +27,8 @@ public class ManagedResourceConfig {
|
||||||
@JsonProperty("code-url")
|
@JsonProperty("code-url")
|
||||||
protected String codeUrl;
|
protected String codeUrl;
|
||||||
|
|
||||||
|
@JsonProperty("ssl-not-required")
|
||||||
|
protected boolean sslNotRequired;
|
||||||
@JsonProperty("allow-any-hostname")
|
@JsonProperty("allow-any-hostname")
|
||||||
protected boolean allowAnyHostname;
|
protected boolean allowAnyHostname;
|
||||||
@JsonProperty("disable-trust-manager")
|
@JsonProperty("disable-trust-manager")
|
||||||
|
@ -50,6 +52,14 @@ public class ManagedResourceConfig {
|
||||||
@JsonProperty("cancel-propagation")
|
@JsonProperty("cancel-propagation")
|
||||||
protected boolean cancelPropagation;
|
protected boolean cancelPropagation;
|
||||||
|
|
||||||
|
public boolean isSslNotRequired() {
|
||||||
|
return sslNotRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSslNotRequired(boolean sslNotRequired) {
|
||||||
|
this.sslNotRequired = sslNotRequired;
|
||||||
|
}
|
||||||
|
|
||||||
public String getRealmUrl() {
|
public String getRealmUrl() {
|
||||||
return realmUrl;
|
return realmUrl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,6 @@ public class ManagedResourceConfigLoader {
|
||||||
|
|
||||||
initClient();
|
initClient();
|
||||||
|
|
||||||
String realm = remoteSkeletonKeyConfig.getRealm();
|
|
||||||
|
|
||||||
if (remoteSkeletonKeyConfig.getRealmUrl() != null) {
|
if (remoteSkeletonKeyConfig.getRealmUrl() != null) {
|
||||||
PublishedRealmRepresentation rep = null;
|
PublishedRealmRepresentation rep = null;
|
||||||
|
@ -99,7 +98,11 @@ public class ManagedResourceConfigLoader {
|
||||||
remoteSkeletonKeyConfig.setRealmKey(rep.getPublicKeyPem());
|
remoteSkeletonKeyConfig.setRealmKey(rep.getPublicKeyPem());
|
||||||
remoteSkeletonKeyConfig.setAdminRole(rep.getAdminRole());
|
remoteSkeletonKeyConfig.setAdminRole(rep.getAdminRole());
|
||||||
}
|
}
|
||||||
|
if (remoteSkeletonKeyConfig.getAdminRole() == null) {
|
||||||
|
remoteSkeletonKeyConfig.setAdminRole("$REALM-ADMIN$");
|
||||||
|
}
|
||||||
|
|
||||||
|
String realm = remoteSkeletonKeyConfig.getRealm();
|
||||||
String resource = remoteSkeletonKeyConfig.getResource();
|
String resource = remoteSkeletonKeyConfig.getResource();
|
||||||
if (realm == null) throw new RuntimeException("Must set 'realm' in config");
|
if (realm == null) throw new RuntimeException("Must set 'realm' in config");
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,11 @@
|
||||||
<description/>
|
<description/>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk16</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-core</artifactId>
|
<artifactId>keycloak-core</artifactId>
|
||||||
|
|
|
@ -97,13 +97,19 @@ public class RealmManager {
|
||||||
|
|
||||||
|
|
||||||
public void importRealm(RealmRepresentation rep, RealmModel newRealm) {
|
public void importRealm(RealmRepresentation rep, RealmModel newRealm) {
|
||||||
generateRealmKeys(newRealm);
|
|
||||||
newRealm.setName(rep.getRealm());
|
newRealm.setName(rep.getRealm());
|
||||||
newRealm.setEnabled(rep.isEnabled());
|
newRealm.setEnabled(rep.isEnabled());
|
||||||
newRealm.setTokenLifespan(rep.getTokenLifespan());
|
newRealm.setTokenLifespan(rep.getTokenLifespan());
|
||||||
newRealm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
|
newRealm.setAccessCodeLifespan(rep.getAccessCodeLifespan());
|
||||||
newRealm.setSslNotRequired(rep.isSslNotRequired());
|
newRealm.setSslNotRequired(rep.isSslNotRequired());
|
||||||
newRealm.setCookieLoginAllowed(rep.isCookieLoginAllowed());
|
newRealm.setCookieLoginAllowed(rep.isCookieLoginAllowed());
|
||||||
|
if (rep.getPrivateKey() == null || rep.getPublicKey() == null) {
|
||||||
|
generateRealmKeys(newRealm);
|
||||||
|
} else {
|
||||||
|
newRealm.setPrivateKeyPem(rep.getPrivateKey());
|
||||||
|
newRealm.setPublicKeyPem(rep.getPublicKey());
|
||||||
|
}
|
||||||
|
|
||||||
newRealm.updateRealm();
|
newRealm.updateRealm();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,6 @@ public class RealmsResource {
|
||||||
|
|
||||||
@Path("{realm}/tokens")
|
@Path("{realm}/tokens")
|
||||||
public TokenService getTokenService(@PathParam("realm") String id) {
|
public TokenService getTokenService(@PathParam("realm") String id) {
|
||||||
logger.info("**** HERE token service****");
|
|
||||||
RealmManager realmManager = new RealmManager(identitySession);
|
RealmManager realmManager = new RealmManager(identitySession);
|
||||||
RealmModel realm = realmManager.getRealm(id);
|
RealmModel realm = realmManager.getRealm(id);
|
||||||
if (realm == null) {
|
if (realm == null) {
|
||||||
|
@ -71,7 +70,6 @@ public class RealmsResource {
|
||||||
|
|
||||||
@Path("{realm}")
|
@Path("{realm}")
|
||||||
public RealmSubResource getRealmResource(@PathParam("realm") String id) {
|
public RealmSubResource getRealmResource(@PathParam("realm") String id) {
|
||||||
logger.info("**** HERE @Path {realm} ****");
|
|
||||||
RealmManager realmManager = new RealmManager(identitySession);
|
RealmManager realmManager = new RealmManager(identitySession);
|
||||||
RealmModel realm = realmManager.getRealm(id);
|
RealmModel realm = realmManager.getRealm(id);
|
||||||
if (realm == null) {
|
if (realm == null) {
|
||||||
|
|
|
@ -201,6 +201,7 @@ public class TokenService {
|
||||||
@POST
|
@POST
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public Response accessRequest(MultivaluedMap<String, String> formData) {
|
public Response accessRequest(MultivaluedMap<String, String> formData) {
|
||||||
|
logger.info("accessRequest <---");
|
||||||
if (!realm.isEnabled()) {
|
if (!realm.isEnabled()) {
|
||||||
throw new NotAuthorizedException("Realm not enabled");
|
throw new NotAuthorizedException("Realm not enabled");
|
||||||
}
|
}
|
||||||
|
@ -286,6 +287,7 @@ public class TokenService {
|
||||||
res.put("error_description", "Auth error");
|
res.put("error_description", "Auth error");
|
||||||
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res).build();
|
||||||
}
|
}
|
||||||
|
logger.info("accessRequest SUCCESS");
|
||||||
AccessTokenResponse res = accessTokenResponse(realm.getPrivateKey(), accessCode.getToken());
|
AccessTokenResponse res = accessTokenResponse(realm.getPrivateKey(), accessCode.getToken());
|
||||||
return Response.ok(res).build();
|
return Response.ok(res).build();
|
||||||
|
|
||||||
|
|
49
services/src/test/java/org/keycloak/test/RealmKeyGenerator.java
Executable file
49
services/src/test/java/org/keycloak/test/RealmKeyGenerator.java
Executable file
|
@ -0,0 +1,49 @@
|
||||||
|
package org.keycloak.test;
|
||||||
|
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.bouncycastle.openssl.PEMWriter;
|
||||||
|
import org.jboss.resteasy.security.PemUtils;
|
||||||
|
import org.keycloak.services.models.RealmModel;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.KeyPairGenerator;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
* @version $Revision: 1 $
|
||||||
|
*/
|
||||||
|
public class RealmKeyGenerator {
|
||||||
|
static {
|
||||||
|
if (Security.getProvider("BC") == null) Security.addProvider(new BouncyCastleProvider());
|
||||||
|
}
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
KeyPair keyPair = null;
|
||||||
|
try {
|
||||||
|
keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("privateKey : " + printKey(keyPair.getPrivate()));
|
||||||
|
System.out.println("publicKey : " + printKey(keyPair.getPublic()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String printKey(Object key){
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
PEMWriter pemWriter = new PEMWriter(writer);
|
||||||
|
try {
|
||||||
|
pemWriter.writeObject(key);
|
||||||
|
pemWriter.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
String s = writer.toString();
|
||||||
|
return PemUtils.removeBeginEnd(s);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue