more subsystem work
This commit is contained in:
parent
4c71eeb627
commit
9390e90b85
38 changed files with 475 additions and 362 deletions
|
@ -23,6 +23,26 @@
|
|||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
<!-- for some reason, Wildfly 8 final decided to turn off management-native which means jboss-as-maven-plugin no
|
||||
longer works -->
|
||||
<xsl:template match="node()[name(.)='management-interfaces']">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="node()|@*"/>
|
||||
<native-interface security-realm="ManagementRealm">
|
||||
<socket-binding native="management-native"/>
|
||||
</native-interface>
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
<!-- for some reason, Wildfly 8 final decided to turn off management-native which means jboss-as-maven-plugin no
|
||||
longer works -->
|
||||
<xsl:template match="node()[name(.)='socket-binding-group']">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="node()|@*"/>
|
||||
<socket-binding name="management-native" interface="management" port="9999"/>
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="@*|node()">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="@*|node()" />
|
||||
|
|
|
@ -20,10 +20,11 @@ import java.util.List;
|
|||
*/
|
||||
public class CustomerDatabaseClient {
|
||||
|
||||
static class TypedList extends ArrayList<String> {}
|
||||
static class TypedList extends ArrayList<String> {
|
||||
}
|
||||
|
||||
public static List<String> getCustomers(HttpServletRequest req) {
|
||||
SkeletonKeySession session = (SkeletonKeySession)req.getAttribute(SkeletonKeySession.class.getName());
|
||||
SkeletonKeySession session = (SkeletonKeySession) req.getAttribute(SkeletonKeySession.class.getName());
|
||||
|
||||
HttpClient client = new HttpClientBuilder()
|
||||
.trustStore(session.getMetadata().getTruststore())
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<dependencies>
|
||||
<!-- the Demo code uses classes in these modules. These are optional to import if you are not using
|
||||
Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
|
||||
<module name="org.apache.httpcomponents" />
|
||||
<module name="org.apache.httpcomponents"/>
|
||||
</dependencies>
|
||||
</deployment>
|
||||
</jboss-deployment-structure>
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"realm" : "demo",
|
||||
"resource" : "customer-portal",
|
||||
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
"auth-server-url" : "http://localhost:8080/auth",
|
||||
"ssl-not-required" : true,
|
||||
"expose-token" : true,
|
||||
"credentials" : {
|
||||
"password" : "password"
|
||||
}
|
||||
"realm": "demo",
|
||||
"resource": "customer-portal",
|
||||
"realm-public-key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
|
||||
"auth-server-url": "http://localhost:8080/auth",
|
||||
"ssl-not-required": true,
|
||||
"expose-token": true,
|
||||
"credentials": {
|
||||
"password": "password"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?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">
|
||||
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>customer-portal</module-name>
|
||||
<module-name>customer-portal</module-name>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
pageEncoding="ISO-8859-1" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Customer Admin Interface</title>
|
||||
</head>
|
||||
<body bgcolor="#E3F6CE">
|
||||
<h1>Customer Admin Interface</h1>
|
||||
User <b><%=request.getUserPrincipal().getName()%></b> made this request.
|
||||
User <b><%=request.getUserPrincipal().getName()%>
|
||||
</b> made this request.
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1"%>
|
||||
pageEncoding="ISO-8859-1" %>
|
||||
<%@ page import="org.keycloak.example.CustomerDatabaseClient" %>
|
||||
<%@ page import="org.keycloak.util.KeycloakUriBuilder" %>
|
||||
<html>
|
||||
|
@ -10,20 +10,21 @@
|
|||
<%
|
||||
String logoutUri = KeycloakUriBuilder.fromUri("http://localhost:8080/auth/rest/realms/demo/tokens/logout")
|
||||
.queryParam("redirect_uri", "http://localhost:8080/customer-portal").build().toString();
|
||||
String acctUri = "http://localhost:8080/auth/rest/realms/demo/account";
|
||||
String acctUri = "http://localhost:8080/auth/rest/realms/demo/account";
|
||||
%>
|
||||
<p>Goto: <a href="http://localhost:8080/product-portal">products</a> | <a href="<%=logoutUri%>">logout</a> | <a href="<%=acctUri%>">manage acct</a></p>
|
||||
User <b><%=request.getUserPrincipal().getName()%></b> made this request.
|
||||
<p>Goto: <a href="http://localhost:8080/product-portal">products</a> | <a href="<%=logoutUri%>">logout</a> | <a
|
||||
href="<%=acctUri%>">manage acct</a></p>
|
||||
User <b><%=request.getUserPrincipal().getName()%>
|
||||
</b> made this request.
|
||||
<h2>Customer Listing</h2>
|
||||
<%
|
||||
java.util.List<String> list = CustomerDatabaseClient.getCustomers(request);
|
||||
for (String cust : list)
|
||||
{
|
||||
out.print("<p>");
|
||||
out.print(cust);
|
||||
out.println("</p>");
|
||||
java.util.List<String> list = CustomerDatabaseClient.getCustomers(request);
|
||||
for (String cust : list) {
|
||||
out.print("<p>");
|
||||
out.print(cust);
|
||||
out.println("</p>");
|
||||
|
||||
}
|
||||
}
|
||||
%>
|
||||
<br><br>
|
||||
</body>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<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>
|
||||
|
|
|
@ -11,16 +11,18 @@ import java.util.List;
|
|||
* @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;
|
||||
}
|
||||
public class CustomerService {
|
||||
@GET
|
||||
@Produces("application/json")
|
||||
public List<String> getCustomers() {
|
||||
ArrayList<String> rtn = new ArrayList<String>();
|
||||
rtn.add("Bill Burke");
|
||||
rtn.add("Stian Thorgersen");
|
||||
rtn.add("Stan Silvert");
|
||||
rtn.add("Gabriel Cordoso");
|
||||
rtn.add("Viliam Rockai");
|
||||
rtn.add("Marek Posolda");
|
||||
rtn.add("Boleslaw Dawidowicz");
|
||||
return rtn;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,16 +11,14 @@ import java.util.List;
|
|||
* @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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,17 +4,20 @@
|
|||
<realm-public-key>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB</realm-public-key>
|
||||
<auth-server-url>http://localhost:8080/auth</auth-server-url>
|
||||
<ssl-not-required>true</ssl-not-required>
|
||||
<secure-deployment name="customer-portal.war">
|
||||
<resource>customer-portal</resource>
|
||||
<credential name="password">password</credential>
|
||||
</secure-deployment>
|
||||
<secure-deployment name="product-portal.war">
|
||||
<resource>product-portal</resource>
|
||||
<credential name="password">password</credential>
|
||||
</secure-deployment>
|
||||
<secure-deployment name="database.war">
|
||||
<resource>database</resource>
|
||||
<credential name="password">password</credential>
|
||||
</secure-deployment>
|
||||
</realm>
|
||||
<secure-deployment name="customer-portal.war">
|
||||
<realm>demo</realm>
|
||||
<resource>customer-portal</resource>
|
||||
<credential name="password">password</credential>
|
||||
</secure-deployment>
|
||||
<secure-deployment name="product-portal.war">
|
||||
<realm>demo</realm>
|
||||
<resource>product-portal</resource>
|
||||
<credential name="password">password</credential>
|
||||
</secure-deployment>
|
||||
<secure-deployment name="database.war">
|
||||
<realm>demo</realm>
|
||||
<resource>database-service</resource>
|
||||
<bearer-only>true</bearer-only>
|
||||
</secure-deployment>
|
||||
</subsystem>
|
||||
|
|
|
@ -39,11 +39,29 @@
|
|||
<version>3.1.2.GA</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-servlet-oauth-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<jboss-deployment-structure>
|
||||
<deployment>
|
||||
<dependencies>
|
||||
<!-- the Demo code uses classes in these modules. These are optional to import if you are not using
|
||||
Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
|
||||
<module name="org.apache.httpcomponents" />
|
||||
</dependencies>
|
||||
</deployment>
|
||||
</jboss-deployment-structure>
|
18
examples/demo-template/third-party/pom.xml
vendored
18
examples/demo-template/third-party/pom.xml
vendored
|
@ -21,11 +21,29 @@
|
|||
<version>1.0.1.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-servlet-oauth-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
9
examples/demo-template/third-party/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
vendored
Executable file
9
examples/demo-template/third-party/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
vendored
Executable file
|
@ -0,0 +1,9 @@
|
|||
<jboss-deployment-structure>
|
||||
<deployment>
|
||||
<dependencies>
|
||||
<!-- the Demo code uses classes in these modules. These are optional to import if you are not using
|
||||
Apache Http Client or the HttpClientBuilder that comes with the adapter core -->
|
||||
<module name="org.apache.httpcomponents" />
|
||||
</dependencies>
|
||||
</deployment>
|
||||
</jboss-deployment-structure>
|
|
@ -17,8 +17,6 @@
|
|||
|
||||
package org.keycloak.subsystem.extension;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.jboss.dmr.Property;
|
||||
|
@ -31,6 +29,9 @@ import org.jboss.msc.service.StartContext;
|
|||
import org.jboss.msc.service.StartException;
|
||||
import org.jboss.msc.service.StopContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADDRESS;
|
||||
|
||||
/**
|
||||
|
@ -86,7 +87,6 @@ public final class KeycloakAdapterConfigService implements Service<KeycloakAdapt
|
|||
|
||||
public void addSecureDeployment(ModelNode operation, ModelNode model) {
|
||||
ModelNode deployment = model.clone();
|
||||
deployment.get(RealmDefinition.TAG_NAME).set(realmNameFromOp(operation));
|
||||
this.deployments.put(deploymentNameFromOp(operation), deployment);
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ public final class KeycloakAdapterConfigService implements Service<KeycloakAdapt
|
|||
json.get(RealmDefinition.TAG_NAME).set(realmName);
|
||||
|
||||
// Realm values set first. Some can be overridden by deployment values.
|
||||
setJSONValues(json, realm);
|
||||
if (realm != null) setJSONValues(json, realm);
|
||||
setJSONValues(json, deployment);
|
||||
return json.toJSONString(true);
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@ package org.keycloak.subsystem.extension;
|
|||
import org.jboss.as.controller.Extension;
|
||||
import org.jboss.as.controller.ExtensionContext;
|
||||
import org.jboss.as.controller.PathElement;
|
||||
import org.jboss.as.controller.ResourceDefinition;
|
||||
import org.jboss.as.controller.SubsystemRegistration;
|
||||
import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
|
||||
import org.jboss.as.controller.parsing.ExtensionParsingContext;
|
||||
import org.jboss.as.controller.registry.ManagementResourceRegistration;
|
||||
import org.jboss.as.controller.ResourceDefinition;
|
||||
import org.keycloak.subsystem.logging.KeycloakLogger;
|
||||
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
|
||||
|
@ -77,7 +77,7 @@ public class KeycloakExtension implements Extension {
|
|||
|
||||
ManagementResourceRegistration registration = subsystem.registerSubsystemModel(KEYCLOAK_SUBSYSTEM_RESOURCE);
|
||||
ManagementResourceRegistration realmRegistration = registration.registerSubModel(REALM_DEFINITION);
|
||||
ManagementResourceRegistration secureDeploymentRegistration = realmRegistration.registerSubModel(SECURE_DEPLOYMENT_DEFINITION);
|
||||
ManagementResourceRegistration secureDeploymentRegistration = registration.registerSubModel(SECURE_DEPLOYMENT_DEFINITION);
|
||||
secureDeploymentRegistration.registerSubModel(CREDENTIAL_DEFINITION);
|
||||
|
||||
subsystem.registerXMLElementWriter(PARSER);
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
import org.jboss.as.controller.PathAddress;
|
||||
import org.jboss.as.controller.PathElement;
|
||||
|
@ -35,6 +30,12 @@ import org.jboss.staxmapper.XMLElementWriter;
|
|||
import org.jboss.staxmapper.XMLExtendedStreamReader;
|
||||
import org.jboss.staxmapper.XMLExtendedStreamWriter;
|
||||
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The subsystem parser, which uses stax to read and write to and from xml
|
||||
*/
|
||||
|
@ -51,10 +52,12 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
|||
list.add(addKeycloakSub);
|
||||
|
||||
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
|
||||
if (!reader.getLocalName().equals("realm")) {
|
||||
throw ParseUtils.unexpectedElement(reader);
|
||||
if (reader.getLocalName().equals(RealmDefinition.TAG_NAME)) {
|
||||
readRealm(reader, list);
|
||||
}
|
||||
else if (reader.getLocalName().equals(SecureDeploymentDefinition.TAG_NAME)) {
|
||||
readDeployment(reader, list);
|
||||
}
|
||||
readRealm(reader, list);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,48 +68,33 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
|||
|
||||
private void readRealm(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException {
|
||||
String realmName = readNameAttribute(reader);
|
||||
ModelNode composite = new ModelNode();
|
||||
composite.get(ModelDescriptionConstants.OP_ADDR).setEmptyList();
|
||||
composite.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.COMPOSITE);
|
||||
ModelNode addRealm = new ModelNode();
|
||||
addRealm.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
|
||||
PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
|
||||
PathElement.pathElement(RealmDefinition.TAG_NAME, realmName));
|
||||
addRealm.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
|
||||
|
||||
List<ModelNode> resourcesToAdd = new ArrayList<ModelNode>();
|
||||
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
|
||||
String tagName = reader.getLocalName();
|
||||
if (tagName.equals(SecureDeploymentDefinition.TAG_NAME)) {
|
||||
readDeployment(reader, addr, resourcesToAdd);
|
||||
continue;
|
||||
}
|
||||
|
||||
SimpleAttributeDefinition def = RealmDefinition.lookup(tagName);
|
||||
if (def == null) throw new XMLStreamException("Unknown realm tag " + tagName);
|
||||
def.parseAndSetParameter(reader.getElementText(), addRealm, reader);
|
||||
}
|
||||
|
||||
if (!RealmDefinition.validateTruststoreSetIfRequired(addRealm)) {
|
||||
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addRealm)) {
|
||||
//TODO: externalize the message
|
||||
throw new XMLStreamException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
|
||||
}
|
||||
|
||||
ModelNode steps = new ModelNode();
|
||||
steps.add(addRealm);
|
||||
for (ModelNode resource : resourcesToAdd) {
|
||||
steps.add(resource);
|
||||
}
|
||||
composite.get(ModelDescriptionConstants.STEPS).set(steps);
|
||||
|
||||
list.add(composite);
|
||||
list.add(addRealm);
|
||||
}
|
||||
|
||||
private void readDeployment(XMLExtendedStreamReader reader, PathAddress parent, List<ModelNode> resourcesToAdd) throws XMLStreamException {
|
||||
private void readDeployment(XMLExtendedStreamReader reader, List<ModelNode> resourcesToAdd) throws XMLStreamException {
|
||||
String name = readNameAttribute(reader);
|
||||
ModelNode addSecureDeployment = new ModelNode();
|
||||
addSecureDeployment.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
|
||||
PathAddress addr = PathAddress.pathAddress(parent, PathElement.pathElement(SecureDeploymentDefinition.TAG_NAME, name));
|
||||
PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
|
||||
PathElement.pathElement(SecureDeploymentDefinition.TAG_NAME, name));
|
||||
addSecureDeployment.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
|
||||
List<ModelNode> credentialsToAdd = new ArrayList<ModelNode>();
|
||||
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
|
||||
|
@ -120,6 +108,16 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
|||
if (def == null) throw new XMLStreamException("Unknown secure-deployment tag " + tagName);
|
||||
def.parseAndSetParameter(reader.getElementText(), addSecureDeployment, reader);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO need to check realm-ref first.
|
||||
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addSecureDeployment)) {
|
||||
//TODO: externalize the message
|
||||
throw new XMLStreamException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
|
||||
}
|
||||
*/
|
||||
|
||||
// Must add credentials after the deployment is added.
|
||||
resourcesToAdd.add(addSecureDeployment);
|
||||
resourcesToAdd.addAll(credentialsToAdd);
|
||||
|
@ -159,6 +157,7 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
|||
public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context) throws XMLStreamException {
|
||||
context.startSubsystemElement(KeycloakExtension.NAMESPACE, false);
|
||||
writeRealms(writer, context);
|
||||
writeSecureDeployments(writer, context);
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
|
@ -174,17 +173,15 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
|||
element.marshallAsElement(realmElements, writer);
|
||||
}
|
||||
|
||||
ModelNode deployments = realmElements.get(SecureDeploymentDefinition.TAG_NAME);
|
||||
if (deployments.isDefined()) {
|
||||
writeSecureDeployments(writer, deployments);
|
||||
}
|
||||
|
||||
writer.writeEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSecureDeployments(XMLExtendedStreamWriter writer, ModelNode deployments) throws XMLStreamException {
|
||||
for (Property deployment : deployments.asPropertyList()) {
|
||||
private void writeSecureDeployments(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
|
||||
if (!context.getModelNode().get(SecureDeploymentDefinition.TAG_NAME).isDefined()) {
|
||||
return;
|
||||
}
|
||||
for (Property deployment : context.getModelNode().get(SecureDeploymentDefinition.TAG_NAME).asPropertyList()) {
|
||||
writer.writeStartElement(SecureDeploymentDefinition.TAG_NAME);
|
||||
writer.writeAttribute("name", deployment.getName());
|
||||
ModelNode deploymentElements = deployment.getValue();
|
||||
|
|
|
@ -17,17 +17,18 @@
|
|||
|
||||
package org.keycloak.subsystem.extension;
|
||||
|
||||
import java.util.List;
|
||||
import org.jboss.as.controller.AbstractAddStepHandler;
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
import org.jboss.as.controller.OperationFailedException;
|
||||
import org.jboss.as.controller.ServiceVerificationHandler;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.jboss.msc.service.ServiceController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
|
||||
import org.jboss.msc.service.ServiceController;
|
||||
|
||||
/**
|
||||
* Add a new realm.
|
||||
|
@ -51,7 +52,7 @@ public final class RealmAddHandler extends AbstractAddStepHandler {
|
|||
attrib.validateAndSet(operation, model);
|
||||
}
|
||||
|
||||
if (!RealmDefinition.validateTruststoreSetIfRequired(model.clone())) {
|
||||
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(model.clone())) {
|
||||
//TODO: externalize message
|
||||
throw new OperationFailedException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
|
||||
}
|
||||
|
|
|
@ -44,65 +44,9 @@ public class RealmDefinition extends SimpleResourceDefinition {
|
|||
|
||||
public static final String TAG_NAME = "realm";
|
||||
|
||||
protected static final SimpleAttributeDefinition REALM_PUBLIC_KEY =
|
||||
new SimpleAttributeDefinitionBuilder("realm-public-key", ModelType.STRING, false)
|
||||
.setXmlName("realm-public-key")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, false, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition AUTH_SERVER_URL =
|
||||
new SimpleAttributeDefinitionBuilder("auth-server-url", ModelType.STRING, false)
|
||||
.setXmlName("auth-server-url")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, false, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition SSL_NOT_REQUIRED =
|
||||
new SimpleAttributeDefinitionBuilder("ssl-not-required", ModelType.BOOLEAN, true)
|
||||
.setXmlName("ssl-not-required")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition ALLOW_ANY_HOSTNAME =
|
||||
new SimpleAttributeDefinitionBuilder("allow-any-hostname", ModelType.BOOLEAN, true)
|
||||
.setXmlName("allow-any-hostname")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition DISABLE_TRUST_MANAGER =
|
||||
new SimpleAttributeDefinitionBuilder("disable-trust-manager", ModelType.BOOLEAN, true)
|
||||
.setXmlName("disable-trust-manager")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition TRUSTSTORE =
|
||||
new SimpleAttributeDefinitionBuilder("truststore", ModelType.STRING, true)
|
||||
.setXmlName("truststore")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition TRUSTSTORE_PASSWORD =
|
||||
new SimpleAttributeDefinitionBuilder("truststore-password", ModelType.STRING, true)
|
||||
.setXmlName("truststore-password")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition CONNECTION_POOL_SIZE =
|
||||
new SimpleAttributeDefinitionBuilder("connection-pool-size", ModelType.INT, true)
|
||||
.setXmlName("connection-pool-size")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new IntRangeValidator(0, true))
|
||||
.build();
|
||||
|
||||
protected static final List<SimpleAttributeDefinition> REALM_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
|
||||
static {
|
||||
REALM_ONLY_ATTRIBUTES.add(REALM_PUBLIC_KEY);
|
||||
REALM_ONLY_ATTRIBUTES.add(AUTH_SERVER_URL);
|
||||
REALM_ONLY_ATTRIBUTES.add(TRUSTSTORE);
|
||||
REALM_ONLY_ATTRIBUTES.add(TRUSTSTORE_PASSWORD);
|
||||
REALM_ONLY_ATTRIBUTES.add(SSL_NOT_REQUIRED);
|
||||
REALM_ONLY_ATTRIBUTES.add(ALLOW_ANY_HOSTNAME);
|
||||
REALM_ONLY_ATTRIBUTES.add(DISABLE_TRUST_MANAGER);
|
||||
REALM_ONLY_ATTRIBUTES.add(CONNECTION_POOL_SIZE);
|
||||
}
|
||||
|
||||
protected static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
|
||||
|
@ -144,32 +88,6 @@ public class RealmDefinition extends SimpleResourceDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* truststore and truststore-password must be set if ssl-not-required and disable-trust-manager are both false.
|
||||
*
|
||||
* @param attributes The full set of attributes.
|
||||
*
|
||||
* @return <code>true</code> if the attributes are valid, <code>false</code> otherwise.
|
||||
*/
|
||||
public static boolean validateTruststoreSetIfRequired(ModelNode attributes) {
|
||||
if (!isSet(attributes, SSL_NOT_REQUIRED) && !isSet(attributes, DISABLE_TRUST_MANAGER)) {
|
||||
if (!(isSet(attributes, TRUSTSTORE) && isSet(attributes, TRUSTSTORE_PASSWORD))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isSet(ModelNode attributes, SimpleAttributeDefinition def) {
|
||||
ModelNode attribute = attributes.get(def.getName());
|
||||
|
||||
if (def.getType() == ModelType.BOOLEAN) {
|
||||
return attribute.isDefined() && attribute.asBoolean();
|
||||
}
|
||||
|
||||
return attribute.isDefined() && !attribute.asString().isEmpty();
|
||||
}
|
||||
|
||||
public static SimpleAttributeDefinition lookup(String name) {
|
||||
return DEFINITION_LOOKUP.get(name);
|
||||
|
|
|
@ -43,12 +43,18 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
|
|||
|
||||
public static final String TAG_NAME = "secure-deployment";
|
||||
|
||||
protected static final SimpleAttributeDefinition REALM =
|
||||
new SimpleAttributeDefinitionBuilder("realm", ModelType.STRING, true)
|
||||
.setXmlName("realm")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition RESOURCE =
|
||||
new SimpleAttributeDefinitionBuilder("resource", ModelType.STRING, true)
|
||||
.setXmlName("resource")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
.setXmlName("resource")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition USE_RESOURCE_ROLE_MAPPINGS =
|
||||
new SimpleAttributeDefinitionBuilder("use-resource-role-mappings", ModelType.BOOLEAN, true)
|
||||
.setXmlName("use-resource-role-mappings")
|
||||
|
@ -64,6 +70,7 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
|
|||
|
||||
protected static final List<SimpleAttributeDefinition> DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
|
||||
static {
|
||||
DEPLOYMENT_ONLY_ATTRIBUTES.add(REALM);
|
||||
DEPLOYMENT_ONLY_ATTRIBUTES.add(RESOURCE);
|
||||
DEPLOYMENT_ONLY_ATTRIBUTES.add(USE_RESOURCE_ROLE_MAPPINGS);
|
||||
DEPLOYMENT_ONLY_ATTRIBUTES.add(BEARER_ONLY);
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.jboss.as.controller.SimpleAttributeDefinition;
|
||||
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
|
||||
import org.jboss.as.controller.operations.validation.IntRangeValidator;
|
||||
|
@ -25,6 +23,9 @@ import org.jboss.as.controller.operations.validation.StringLengthValidator;
|
|||
import org.jboss.dmr.ModelNode;
|
||||
import org.jboss.dmr.ModelType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Defines attributes that can be present in both a realm and an application (secure-deployment).
|
||||
*
|
||||
|
@ -32,6 +33,55 @@ import org.jboss.dmr.ModelType;
|
|||
*/
|
||||
public class SharedAttributeDefinitons {
|
||||
|
||||
protected static final SimpleAttributeDefinition REALM_PUBLIC_KEY =
|
||||
new SimpleAttributeDefinitionBuilder("realm-public-key", ModelType.STRING, true)
|
||||
.setXmlName("realm-public-key")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition AUTH_SERVER_URL =
|
||||
new SimpleAttributeDefinitionBuilder("auth-server-url", ModelType.STRING, true)
|
||||
.setXmlName("auth-server-url")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition SSL_NOT_REQUIRED =
|
||||
new SimpleAttributeDefinitionBuilder("ssl-not-required", ModelType.BOOLEAN, true)
|
||||
.setXmlName("ssl-not-required")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition ALLOW_ANY_HOSTNAME =
|
||||
new SimpleAttributeDefinitionBuilder("allow-any-hostname", ModelType.BOOLEAN, true)
|
||||
.setXmlName("allow-any-hostname")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition DISABLE_TRUST_MANAGER =
|
||||
new SimpleAttributeDefinitionBuilder("disable-trust-manager", ModelType.BOOLEAN, true)
|
||||
.setXmlName("disable-trust-manager")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition TRUSTSTORE =
|
||||
new SimpleAttributeDefinitionBuilder("truststore", ModelType.STRING, true)
|
||||
.setXmlName("truststore")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition TRUSTSTORE_PASSWORD =
|
||||
new SimpleAttributeDefinitionBuilder("truststore-password", ModelType.STRING, true)
|
||||
.setXmlName("truststore-password")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition CONNECTION_POOL_SIZE =
|
||||
new SimpleAttributeDefinitionBuilder("connection-pool-size", ModelType.INT, true)
|
||||
.setXmlName("connection-pool-size")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new IntRangeValidator(0, true))
|
||||
.build();
|
||||
|
||||
protected static final SimpleAttributeDefinition ENABLE_CORS =
|
||||
new SimpleAttributeDefinitionBuilder("enable-cors", ModelType.BOOLEAN, true)
|
||||
.setXmlName("enable-cors")
|
||||
|
@ -84,6 +134,14 @@ public class SharedAttributeDefinitons {
|
|||
|
||||
protected static final List<SimpleAttributeDefinition> ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
|
||||
static {
|
||||
ATTRIBUTES.add(REALM_PUBLIC_KEY);
|
||||
ATTRIBUTES.add(AUTH_SERVER_URL);
|
||||
ATTRIBUTES.add(TRUSTSTORE);
|
||||
ATTRIBUTES.add(TRUSTSTORE_PASSWORD);
|
||||
ATTRIBUTES.add(SSL_NOT_REQUIRED);
|
||||
ATTRIBUTES.add(ALLOW_ANY_HOSTNAME);
|
||||
ATTRIBUTES.add(DISABLE_TRUST_MANAGER);
|
||||
ATTRIBUTES.add(CONNECTION_POOL_SIZE);
|
||||
ATTRIBUTES.add(ENABLE_CORS);
|
||||
ATTRIBUTES.add(CLIENT_KEYSTORE);
|
||||
ATTRIBUTES.add(CLIENT_KEYSTORE_PASSWORD);
|
||||
|
@ -94,4 +152,32 @@ public class SharedAttributeDefinitons {
|
|||
ATTRIBUTES.add(EXPOSE_TOKEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* truststore and truststore-password must be set if ssl-not-required and disable-trust-manager are both false.
|
||||
*
|
||||
* @param attributes The full set of attributes.
|
||||
*
|
||||
* @return <code>true</code> if the attributes are valid, <code>false</code> otherwise.
|
||||
*/
|
||||
public static boolean validateTruststoreSetIfRequired(ModelNode attributes) {
|
||||
if (!isSet(attributes, SSL_NOT_REQUIRED) && !isSet(attributes, DISABLE_TRUST_MANAGER)) {
|
||||
if (!(isSet(attributes, TRUSTSTORE) && isSet(attributes, TRUSTSTORE_PASSWORD))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isSet(ModelNode attributes, SimpleAttributeDefinition def) {
|
||||
ModelNode attribute = attributes.get(def.getName());
|
||||
|
||||
if (def.getType() == ModelType.BOOLEAN) {
|
||||
return attribute.isDefined() && attribute.asBoolean();
|
||||
}
|
||||
|
||||
return attribute.isDefined() && !attribute.asString().isEmpty();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ keycloak.subsystem=Keycloak subsystem
|
|||
keycloak.subsystem.add=Operation Adds Keycloak subsystem
|
||||
keycloak.subsystem.remove=Operation removes Keycloak subsystem
|
||||
keycloak.subsystem.realm=A Keycloak realm.
|
||||
keycloak.subsystem.secure-deployment=A deployment secured by Keycloak.
|
||||
|
||||
keycloak.realm=A Keycloak realm.
|
||||
keycloak.realm.add=Add a realm definition to the subsystem.
|
||||
|
@ -23,11 +24,18 @@ keycloak.realm.cors-allowed-headers=TODO: fill in help text
|
|||
keycloak.realm.cors-allowed-methods=TODO: fill in help text
|
||||
keycloak.realm.expose-token=TODO: fill in help text
|
||||
|
||||
keycloak.realm.secure-deployment=A deployment secured by Keycloak
|
||||
|
||||
keycloak.secure-deployment=A deployment secured by Keycloak
|
||||
keycloak.secure-deployment.add=Add a deployment to be secured by Keycloak
|
||||
keycloak.secure-deployment.realm=Keycloak realm
|
||||
keycloak.secure-deployment.remove=Remove a deployment to be secured by Keycloak
|
||||
keycloak.secure-deployment.realm-public-key=TODO: fill in help text
|
||||
keycloak.secure-deployment.auth-server-url=TODO: fill in help text
|
||||
keycloak.secure-deployment.disable-trust-manager=TODO: fill in help text
|
||||
keycloak.secure-deployment.ssl-not-required=TODO: fill in help text
|
||||
keycloak.secure-deployment.allow-any-hostname=TODO: fill in help text
|
||||
keycloak.secure-deployment.truststore=TODO: fill in help text
|
||||
keycloak.secure-deployment.truststore-password=TODO: fill in help text
|
||||
keycloak.secure-deployment.connection-pool-size=TODO: fill in help text
|
||||
keycloak.secure-deployment.resource=TODO: fill in help text
|
||||
keycloak.secure-deployment.use-resource-role-mappings=TODO: fill in help text
|
||||
keycloak.secure-deployment.credentials=TODO: fill in help text
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:element name="realm" maxOccurs="unbounded" minOccurs="0" type="realm-type"/>
|
||||
<xs:element name="realm" maxOccurs="unbounded" minOccurs="0" type="secure-deployment-type"/>
|
||||
|
||||
</xs:complexType>
|
||||
|
||||
|
@ -28,18 +29,6 @@
|
|||
</xs:attribute>
|
||||
<xs:complexContent>
|
||||
<xs:extension base="override-element-type">
|
||||
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="auth-url" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="code-url" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="ssl-not-required" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="allow-any-hostname" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="disable-trust-manager" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="truststore" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="truststore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="connection-pool-size" type="xs:integer" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:choice maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:element name="secure-deployment" maxOccurs="unbounded" minOccurs="0" type="secure-deployment-type"/>
|
||||
</xs:choice>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
@ -52,6 +41,7 @@
|
|||
</xs:attribute>
|
||||
<xs:complexContent>
|
||||
<xs:extension base="override-element-type">
|
||||
<xs:element name="realm" type="xs:string" minOccurs="0" maxOccurs="1" use="required"/>
|
||||
<xs:element name="resource" type="xs:string" minOccurs="0" maxOccurs="1" use="required"/>
|
||||
<xs:element name="use-resource-role-mappings" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="bearer-only" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
|
@ -76,6 +66,15 @@
|
|||
]]>
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="auth-url" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="code-url" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="ssl-not-required" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="allow-any-hostname" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="disable-trust-manager" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="truststore" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="truststore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="connection-pool-size" type="xs:integer" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="enable-cors" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="client-keystore" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="client-keystore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
|
||||
|
@ -50,30 +49,30 @@ public class RealmDefinitionTestCase {
|
|||
public void testIsTruststoreSetIfRequired() throws Exception {
|
||||
model.get("ssl-not-required").set(true);
|
||||
model.get("disable-trust-manager").set(true);
|
||||
Assert.assertTrue(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
|
||||
model.get("ssl-not-required").set(true);
|
||||
model.get("disable-trust-manager").set(false);
|
||||
Assert.assertTrue(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
|
||||
model.get("ssl-not-required").set(false);
|
||||
model.get("disable-trust-manager").set(true);
|
||||
Assert.assertTrue(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
|
||||
model.get("ssl-not-required").set(false);
|
||||
model.get("disable-trust-manager").set(false);
|
||||
Assert.assertFalse(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
|
||||
model.get("ssl-not-required").set(false);
|
||||
model.get("disable-trust-manager").set(false);
|
||||
model.get("truststore").set("foo");
|
||||
Assert.assertFalse(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
|
||||
model.get("ssl-not-required").set(false);
|
||||
model.get("disable-trust-manager").set(false);
|
||||
model.get("truststore").set("foo");
|
||||
model.get("truststore-password").set("password");
|
||||
Assert.assertTrue(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,21 +16,25 @@
|
|||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk16</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>${keycloak.apache.httpcomponents.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
|
@ -43,6 +47,7 @@
|
|||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
<artifactId>base64</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||
|
|
|
@ -86,7 +86,6 @@ public final class KeycloakAdapterConfigService implements Service<KeycloakAdapt
|
|||
|
||||
public void addSecureDeployment(ModelNode operation, ModelNode model) {
|
||||
ModelNode deployment = model.clone();
|
||||
deployment.get(RealmDefinition.TAG_NAME).set(realmNameFromOp(operation));
|
||||
this.deployments.put(deploymentNameFromOp(operation), deployment);
|
||||
}
|
||||
|
||||
|
@ -178,7 +177,7 @@ public final class KeycloakAdapterConfigService implements Service<KeycloakAdapt
|
|||
json.get(RealmDefinition.TAG_NAME).set(realmName);
|
||||
|
||||
// Realm values set first. Some can be overridden by deployment values.
|
||||
setJSONValues(json, realm);
|
||||
if (realm != null) setJSONValues(json, realm);
|
||||
setJSONValues(json, deployment);
|
||||
return json.toJSONString(true);
|
||||
}
|
||||
|
|
2
integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakExtension.java
Normal file → Executable file
2
integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakExtension.java
Normal file → Executable file
|
@ -77,7 +77,7 @@ public class KeycloakExtension implements Extension {
|
|||
|
||||
ManagementResourceRegistration registration = subsystem.registerSubsystemModel(KEYCLOAK_SUBSYSTEM_RESOURCE);
|
||||
ManagementResourceRegistration realmRegistration = registration.registerSubModel(REALM_DEFINITION);
|
||||
ManagementResourceRegistration secureDeploymentRegistration = realmRegistration.registerSubModel(SECURE_DEPLOYMENT_DEFINITION);
|
||||
ManagementResourceRegistration secureDeploymentRegistration = registration.registerSubModel(SECURE_DEPLOYMENT_DEFINITION);
|
||||
secureDeploymentRegistration.registerSubModel(CREDENTIAL_DEFINITION);
|
||||
|
||||
subsystem.registerXMLElementWriter(PARSER);
|
||||
|
|
56
integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakSubsystemParser.java
Normal file → Executable file
56
integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakSubsystemParser.java
Normal file → Executable file
|
@ -52,10 +52,12 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
|||
list.add(addKeycloakSub);
|
||||
|
||||
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
|
||||
if (!reader.getLocalName().equals("realm")) {
|
||||
throw ParseUtils.unexpectedElement(reader);
|
||||
if (reader.getLocalName().equals(RealmDefinition.TAG_NAME)) {
|
||||
readRealm(reader, list);
|
||||
}
|
||||
else if (reader.getLocalName().equals(SecureDeploymentDefinition.TAG_NAME)) {
|
||||
readDeployment(reader, list);
|
||||
}
|
||||
readRealm(reader, list);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,48 +68,33 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
|||
|
||||
private void readRealm(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException {
|
||||
String realmName = readNameAttribute(reader);
|
||||
ModelNode composite = new ModelNode();
|
||||
composite.get(ModelDescriptionConstants.OP_ADDR).setEmptyList();
|
||||
composite.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.COMPOSITE);
|
||||
ModelNode addRealm = new ModelNode();
|
||||
addRealm.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
|
||||
PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
|
||||
PathElement.pathElement(RealmDefinition.TAG_NAME, realmName));
|
||||
addRealm.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
|
||||
|
||||
List<ModelNode> resourcesToAdd = new ArrayList<ModelNode>();
|
||||
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
|
||||
String tagName = reader.getLocalName();
|
||||
if (tagName.equals(SecureDeploymentDefinition.TAG_NAME)) {
|
||||
readDeployment(reader, addr, resourcesToAdd);
|
||||
continue;
|
||||
}
|
||||
|
||||
SimpleAttributeDefinition def = RealmDefinition.lookup(tagName);
|
||||
if (def == null) throw new XMLStreamException("Unknown realm tag " + tagName);
|
||||
def.parseAndSetParameter(reader.getElementText(), addRealm, reader);
|
||||
}
|
||||
|
||||
if (!RealmDefinition.validateTruststoreSetIfRequired(addRealm)) {
|
||||
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addRealm)) {
|
||||
//TODO: externalize the message
|
||||
throw new XMLStreamException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
|
||||
}
|
||||
|
||||
ModelNode steps = new ModelNode();
|
||||
steps.add(addRealm);
|
||||
for (ModelNode resource : resourcesToAdd) {
|
||||
steps.add(resource);
|
||||
}
|
||||
composite.get(ModelDescriptionConstants.STEPS).set(steps);
|
||||
|
||||
list.add(composite);
|
||||
list.add(addRealm);
|
||||
}
|
||||
|
||||
private void readDeployment(XMLExtendedStreamReader reader, PathAddress parent, List<ModelNode> resourcesToAdd) throws XMLStreamException {
|
||||
private void readDeployment(XMLExtendedStreamReader reader, List<ModelNode> resourcesToAdd) throws XMLStreamException {
|
||||
String name = readNameAttribute(reader);
|
||||
ModelNode addSecureDeployment = new ModelNode();
|
||||
addSecureDeployment.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
|
||||
PathAddress addr = PathAddress.pathAddress(parent, PathElement.pathElement(SecureDeploymentDefinition.TAG_NAME, name));
|
||||
PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
|
||||
PathElement.pathElement(SecureDeploymentDefinition.TAG_NAME, name));
|
||||
addSecureDeployment.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
|
||||
List<ModelNode> credentialsToAdd = new ArrayList<ModelNode>();
|
||||
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
|
||||
|
@ -121,6 +108,16 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
|||
if (def == null) throw new XMLStreamException("Unknown secure-deployment tag " + tagName);
|
||||
def.parseAndSetParameter(reader.getElementText(), addSecureDeployment, reader);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO need to check realm-ref first.
|
||||
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addSecureDeployment)) {
|
||||
//TODO: externalize the message
|
||||
throw new XMLStreamException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
|
||||
}
|
||||
*/
|
||||
|
||||
// Must add credentials after the deployment is added.
|
||||
resourcesToAdd.add(addSecureDeployment);
|
||||
resourcesToAdd.addAll(credentialsToAdd);
|
||||
|
@ -160,6 +157,7 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
|||
public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context) throws XMLStreamException {
|
||||
context.startSubsystemElement(KeycloakExtension.NAMESPACE, false);
|
||||
writeRealms(writer, context);
|
||||
writeSecureDeployments(writer, context);
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
|
@ -175,17 +173,15 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
|||
element.marshallAsElement(realmElements, writer);
|
||||
}
|
||||
|
||||
ModelNode deployments = realmElements.get(SecureDeploymentDefinition.TAG_NAME);
|
||||
if (deployments.isDefined()) {
|
||||
writeSecureDeployments(writer, deployments);
|
||||
}
|
||||
|
||||
writer.writeEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSecureDeployments(XMLExtendedStreamWriter writer, ModelNode deployments) throws XMLStreamException {
|
||||
for (Property deployment : deployments.asPropertyList()) {
|
||||
private void writeSecureDeployments(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
|
||||
if (!context.getModelNode().get(SecureDeploymentDefinition.TAG_NAME).isDefined()) {
|
||||
return;
|
||||
}
|
||||
for (Property deployment : context.getModelNode().get(SecureDeploymentDefinition.TAG_NAME).asPropertyList()) {
|
||||
writer.writeStartElement(SecureDeploymentDefinition.TAG_NAME);
|
||||
writer.writeAttribute("name", deployment.getName());
|
||||
ModelNode deploymentElements = deployment.getValue();
|
||||
|
|
2
integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmAddHandler.java
Normal file → Executable file
2
integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/RealmAddHandler.java
Normal file → Executable file
|
@ -51,7 +51,7 @@ public final class RealmAddHandler extends AbstractAddStepHandler {
|
|||
attrib.validateAndSet(operation, model);
|
||||
}
|
||||
|
||||
if (!RealmDefinition.validateTruststoreSetIfRequired(model.clone())) {
|
||||
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(model.clone())) {
|
||||
//TODO: externalize message
|
||||
throw new OperationFailedException("truststore and truststore-password must be set if both ssl-not-required and disable-trust-maanger are false.");
|
||||
}
|
||||
|
|
|
@ -41,65 +41,9 @@ public class RealmDefinition extends SimpleResourceDefinition {
|
|||
|
||||
public static final String TAG_NAME = "realm";
|
||||
|
||||
protected static final SimpleAttributeDefinition REALM_PUBLIC_KEY =
|
||||
new SimpleAttributeDefinitionBuilder("realm-public-key", ModelType.STRING, false)
|
||||
.setXmlName("realm-public-key")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, false, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition AUTH_SERVER_URL =
|
||||
new SimpleAttributeDefinitionBuilder("auth-server-url", ModelType.STRING, false)
|
||||
.setXmlName("auth-server-url")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, false, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition SSL_NOT_REQUIRED =
|
||||
new SimpleAttributeDefinitionBuilder("ssl-not-required", ModelType.BOOLEAN, true)
|
||||
.setXmlName("ssl-not-required")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition ALLOW_ANY_HOSTNAME =
|
||||
new SimpleAttributeDefinitionBuilder("allow-any-hostname", ModelType.BOOLEAN, true)
|
||||
.setXmlName("allow-any-hostname")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition DISABLE_TRUST_MANAGER =
|
||||
new SimpleAttributeDefinitionBuilder("disable-trust-manager", ModelType.BOOLEAN, true)
|
||||
.setXmlName("disable-trust-manager")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition TRUSTSTORE =
|
||||
new SimpleAttributeDefinitionBuilder("truststore", ModelType.STRING, true)
|
||||
.setXmlName("truststore")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition TRUSTSTORE_PASSWORD =
|
||||
new SimpleAttributeDefinitionBuilder("truststore-password", ModelType.STRING, true)
|
||||
.setXmlName("truststore-password")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition CONNECTION_POOL_SIZE =
|
||||
new SimpleAttributeDefinitionBuilder("connection-pool-size", ModelType.INT, true)
|
||||
.setXmlName("connection-pool-size")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new IntRangeValidator(0, true))
|
||||
.build();
|
||||
|
||||
protected static final List<SimpleAttributeDefinition> REALM_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
|
||||
static {
|
||||
REALM_ONLY_ATTRIBUTES.add(REALM_PUBLIC_KEY);
|
||||
REALM_ONLY_ATTRIBUTES.add(AUTH_SERVER_URL);
|
||||
REALM_ONLY_ATTRIBUTES.add(TRUSTSTORE);
|
||||
REALM_ONLY_ATTRIBUTES.add(TRUSTSTORE_PASSWORD);
|
||||
REALM_ONLY_ATTRIBUTES.add(SSL_NOT_REQUIRED);
|
||||
REALM_ONLY_ATTRIBUTES.add(ALLOW_ANY_HOSTNAME);
|
||||
REALM_ONLY_ATTRIBUTES.add(DISABLE_TRUST_MANAGER);
|
||||
REALM_ONLY_ATTRIBUTES.add(CONNECTION_POOL_SIZE);
|
||||
}
|
||||
|
||||
protected static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
|
||||
|
@ -140,32 +84,6 @@ public class RealmDefinition extends SimpleResourceDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* truststore and truststore-password must be set if ssl-not-required and disable-trust-manager are both false.
|
||||
*
|
||||
* @param attributes The full set of attributes.
|
||||
*
|
||||
* @return <code>true</code> if the attributes are valid, <code>false</code> otherwise.
|
||||
*/
|
||||
public static boolean validateTruststoreSetIfRequired(ModelNode attributes) {
|
||||
if (!isSet(attributes, SSL_NOT_REQUIRED) && !isSet(attributes, DISABLE_TRUST_MANAGER)) {
|
||||
if (!(isSet(attributes, TRUSTSTORE) && isSet(attributes, TRUSTSTORE_PASSWORD))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isSet(ModelNode attributes, SimpleAttributeDefinition def) {
|
||||
ModelNode attribute = attributes.get(def.getName());
|
||||
|
||||
if (def.getType() == ModelType.BOOLEAN) {
|
||||
return attribute.isDefined() && attribute.asBoolean();
|
||||
}
|
||||
|
||||
return attribute.isDefined() && !attribute.asString().isEmpty();
|
||||
}
|
||||
|
||||
public static SimpleAttributeDefinition lookup(String name) {
|
||||
return DEFINITION_LOOKUP.get(name);
|
||||
|
|
15
integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentDefinition.java
Normal file → Executable file
15
integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/SecureDeploymentDefinition.java
Normal file → Executable file
|
@ -40,12 +40,18 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
|
|||
|
||||
public static final String TAG_NAME = "secure-deployment";
|
||||
|
||||
protected static final SimpleAttributeDefinition REALM =
|
||||
new SimpleAttributeDefinitionBuilder("realm", ModelType.STRING, true)
|
||||
.setXmlName("realm")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition RESOURCE =
|
||||
new SimpleAttributeDefinitionBuilder("resource", ModelType.STRING, true)
|
||||
.setXmlName("resource")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
.setXmlName("resource")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition USE_RESOURCE_ROLE_MAPPINGS =
|
||||
new SimpleAttributeDefinitionBuilder("use-resource-role-mappings", ModelType.BOOLEAN, true)
|
||||
.setXmlName("use-resource-role-mappings")
|
||||
|
@ -61,6 +67,7 @@ public class SecureDeploymentDefinition extends SimpleResourceDefinition {
|
|||
|
||||
protected static final List<SimpleAttributeDefinition> DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
|
||||
static {
|
||||
DEPLOYMENT_ONLY_ATTRIBUTES.add(REALM);
|
||||
DEPLOYMENT_ONLY_ATTRIBUTES.add(RESOURCE);
|
||||
DEPLOYMENT_ONLY_ATTRIBUTES.add(USE_RESOURCE_ROLE_MAPPINGS);
|
||||
DEPLOYMENT_ONLY_ATTRIBUTES.add(BEARER_ONLY);
|
||||
|
|
|
@ -32,6 +32,55 @@ import org.jboss.dmr.ModelType;
|
|||
*/
|
||||
public class SharedAttributeDefinitons {
|
||||
|
||||
protected static final SimpleAttributeDefinition REALM_PUBLIC_KEY =
|
||||
new SimpleAttributeDefinitionBuilder("realm-public-key", ModelType.STRING, true)
|
||||
.setXmlName("realm-public-key")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition AUTH_SERVER_URL =
|
||||
new SimpleAttributeDefinitionBuilder("auth-server-url", ModelType.STRING, true)
|
||||
.setXmlName("auth-server-url")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition SSL_NOT_REQUIRED =
|
||||
new SimpleAttributeDefinitionBuilder("ssl-not-required", ModelType.BOOLEAN, true)
|
||||
.setXmlName("ssl-not-required")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition ALLOW_ANY_HOSTNAME =
|
||||
new SimpleAttributeDefinitionBuilder("allow-any-hostname", ModelType.BOOLEAN, true)
|
||||
.setXmlName("allow-any-hostname")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition DISABLE_TRUST_MANAGER =
|
||||
new SimpleAttributeDefinitionBuilder("disable-trust-manager", ModelType.BOOLEAN, true)
|
||||
.setXmlName("disable-trust-manager")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition TRUSTSTORE =
|
||||
new SimpleAttributeDefinitionBuilder("truststore", ModelType.STRING, true)
|
||||
.setXmlName("truststore")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition TRUSTSTORE_PASSWORD =
|
||||
new SimpleAttributeDefinitionBuilder("truststore-password", ModelType.STRING, true)
|
||||
.setXmlName("truststore-password")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
|
||||
.build();
|
||||
protected static final SimpleAttributeDefinition CONNECTION_POOL_SIZE =
|
||||
new SimpleAttributeDefinitionBuilder("connection-pool-size", ModelType.INT, true)
|
||||
.setXmlName("connection-pool-size")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new IntRangeValidator(0, true))
|
||||
.build();
|
||||
|
||||
protected static final SimpleAttributeDefinition ENABLE_CORS =
|
||||
new SimpleAttributeDefinitionBuilder("enable-cors", ModelType.BOOLEAN, true)
|
||||
.setXmlName("enable-cors")
|
||||
|
@ -84,6 +133,14 @@ public class SharedAttributeDefinitons {
|
|||
|
||||
protected static final List<SimpleAttributeDefinition> ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
|
||||
static {
|
||||
ATTRIBUTES.add(REALM_PUBLIC_KEY);
|
||||
ATTRIBUTES.add(AUTH_SERVER_URL);
|
||||
ATTRIBUTES.add(TRUSTSTORE);
|
||||
ATTRIBUTES.add(TRUSTSTORE_PASSWORD);
|
||||
ATTRIBUTES.add(SSL_NOT_REQUIRED);
|
||||
ATTRIBUTES.add(ALLOW_ANY_HOSTNAME);
|
||||
ATTRIBUTES.add(DISABLE_TRUST_MANAGER);
|
||||
ATTRIBUTES.add(CONNECTION_POOL_SIZE);
|
||||
ATTRIBUTES.add(ENABLE_CORS);
|
||||
ATTRIBUTES.add(CLIENT_KEYSTORE);
|
||||
ATTRIBUTES.add(CLIENT_KEYSTORE_PASSWORD);
|
||||
|
@ -94,4 +151,32 @@ public class SharedAttributeDefinitons {
|
|||
ATTRIBUTES.add(EXPOSE_TOKEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* truststore and truststore-password must be set if ssl-not-required and disable-trust-manager are both false.
|
||||
*
|
||||
* @param attributes The full set of attributes.
|
||||
*
|
||||
* @return <code>true</code> if the attributes are valid, <code>false</code> otherwise.
|
||||
*/
|
||||
public static boolean validateTruststoreSetIfRequired(ModelNode attributes) {
|
||||
if (!isSet(attributes, SSL_NOT_REQUIRED) && !isSet(attributes, DISABLE_TRUST_MANAGER)) {
|
||||
if (!(isSet(attributes, TRUSTSTORE) && isSet(attributes, TRUSTSTORE_PASSWORD))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isSet(ModelNode attributes, SimpleAttributeDefinition def) {
|
||||
ModelNode attribute = attributes.get(def.getName());
|
||||
|
||||
if (def.getType() == ModelType.BOOLEAN) {
|
||||
return attribute.isDefined() && attribute.asBoolean();
|
||||
}
|
||||
|
||||
return attribute.isDefined() && !attribute.asString().isEmpty();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
12
integration/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/extension/LocalDescriptions.properties
Normal file → Executable file
12
integration/wildfly-subsystem/src/main/resources/org/keycloak/subsystem/extension/LocalDescriptions.properties
Normal file → Executable file
|
@ -2,6 +2,7 @@ keycloak.subsystem=Keycloak subsystem
|
|||
keycloak.subsystem.add=Operation Adds Keycloak subsystem
|
||||
keycloak.subsystem.remove=Operation removes Keycloak subsystem
|
||||
keycloak.subsystem.realm=A Keycloak realm.
|
||||
keycloak.subsystem.secure-deployment=A deployment secured by Keycloak.
|
||||
|
||||
keycloak.realm=A Keycloak realm.
|
||||
keycloak.realm.add=Add a realm definition to the subsystem.
|
||||
|
@ -23,11 +24,18 @@ keycloak.realm.cors-allowed-headers=TODO: fill in help text
|
|||
keycloak.realm.cors-allowed-methods=TODO: fill in help text
|
||||
keycloak.realm.expose-token=TODO: fill in help text
|
||||
|
||||
keycloak.realm.secure-deployment=A deployment secured by Keycloak
|
||||
|
||||
keycloak.secure-deployment=A deployment secured by Keycloak
|
||||
keycloak.secure-deployment.add=Add a deployment to be secured by Keycloak
|
||||
keycloak.secure-deployment.realm=Keycloak realm
|
||||
keycloak.secure-deployment.remove=Remove a deployment to be secured by Keycloak
|
||||
keycloak.secure-deployment.realm-public-key=TODO: fill in help text
|
||||
keycloak.secure-deployment.auth-server-url=TODO: fill in help text
|
||||
keycloak.secure-deployment.disable-trust-manager=TODO: fill in help text
|
||||
keycloak.secure-deployment.ssl-not-required=TODO: fill in help text
|
||||
keycloak.secure-deployment.allow-any-hostname=TODO: fill in help text
|
||||
keycloak.secure-deployment.truststore=TODO: fill in help text
|
||||
keycloak.secure-deployment.truststore-password=TODO: fill in help text
|
||||
keycloak.secure-deployment.connection-pool-size=TODO: fill in help text
|
||||
keycloak.secure-deployment.resource=TODO: fill in help text
|
||||
keycloak.secure-deployment.use-resource-role-mappings=TODO: fill in help text
|
||||
keycloak.secure-deployment.credentials=TODO: fill in help text
|
||||
|
|
23
integration/wildfly-subsystem/src/main/resources/schema/keycloak_1_0.xsd
Normal file → Executable file
23
integration/wildfly-subsystem/src/main/resources/schema/keycloak_1_0.xsd
Normal file → Executable file
|
@ -17,6 +17,7 @@
|
|||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:element name="realm" maxOccurs="unbounded" minOccurs="0" type="realm-type"/>
|
||||
<xs:element name="realm" maxOccurs="unbounded" minOccurs="0" type="secure-deployment-type"/>
|
||||
|
||||
</xs:complexType>
|
||||
|
||||
|
@ -28,18 +29,6 @@
|
|||
</xs:attribute>
|
||||
<xs:complexContent>
|
||||
<xs:extension base="override-element-type">
|
||||
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="auth-url" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="code-url" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="ssl-not-required" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="allow-any-hostname" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="disable-trust-manager" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="truststore" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="truststore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="connection-pool-size" type="xs:integer" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:choice maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:element name="secure-deployment" maxOccurs="unbounded" minOccurs="0" type="secure-deployment-type"/>
|
||||
</xs:choice>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
@ -52,6 +41,7 @@
|
|||
</xs:attribute>
|
||||
<xs:complexContent>
|
||||
<xs:extension base="override-element-type">
|
||||
<xs:element name="realm" type="xs:string" minOccurs="0" maxOccurs="1" use="required"/>
|
||||
<xs:element name="resource" type="xs:string" minOccurs="0" maxOccurs="1" use="required"/>
|
||||
<xs:element name="use-resource-role-mappings" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="bearer-only" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
|
@ -76,6 +66,15 @@
|
|||
]]>
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="auth-url" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="code-url" type="xs:string" minOccurs="1" maxOccurs="1" use="required"/>
|
||||
<xs:element name="ssl-not-required" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="allow-any-hostname" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="disable-trust-manager" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="truststore" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="truststore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="connection-pool-size" type="xs:integer" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="enable-cors" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="client-keystore" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="client-keystore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
|
|
12
integration/wildfly-subsystem/src/test/java/org/keycloak/subsystem/extension/RealmDefinitionTestCase.java
Normal file → Executable file
12
integration/wildfly-subsystem/src/test/java/org/keycloak/subsystem/extension/RealmDefinitionTestCase.java
Normal file → Executable file
|
@ -50,30 +50,30 @@ public class RealmDefinitionTestCase {
|
|||
public void testIsTruststoreSetIfRequired() throws Exception {
|
||||
model.get("ssl-not-required").set(true);
|
||||
model.get("disable-trust-manager").set(true);
|
||||
Assert.assertTrue(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
|
||||
model.get("ssl-not-required").set(true);
|
||||
model.get("disable-trust-manager").set(false);
|
||||
Assert.assertTrue(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
|
||||
model.get("ssl-not-required").set(false);
|
||||
model.get("disable-trust-manager").set(true);
|
||||
Assert.assertTrue(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
|
||||
model.get("ssl-not-required").set(false);
|
||||
model.get("disable-trust-manager").set(false);
|
||||
Assert.assertFalse(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
|
||||
model.get("ssl-not-required").set(false);
|
||||
model.get("disable-trust-manager").set(false);
|
||||
model.get("truststore").set("foo");
|
||||
Assert.assertFalse(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
|
||||
model.get("ssl-not-required").set(false);
|
||||
model.get("disable-trust-manager").set(false);
|
||||
model.get("truststore").set("foo");
|
||||
model.get("truststore-password").set("password");
|
||||
Assert.assertTrue(RealmDefinition.validateTruststoreSetIfRequired(model));
|
||||
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -14,7 +14,7 @@
|
|||
<properties>
|
||||
<keycloak.apache.httpcomponents.version>4.1.2</keycloak.apache.httpcomponents.version>
|
||||
<resteasy.version>3.0.6.Final</resteasy.version>
|
||||
<undertow.version>1.0.0.Beta30</undertow.version>
|
||||
<undertow.version>1.0.0.Final</undertow.version>
|
||||
<picketlink.version>2.5.0.Beta6</picketlink.version>
|
||||
<mongo.driver.version>2.11.3</mongo.driver.version>
|
||||
<jboss.logging.version>3.1.1.GA</jboss.logging.version>
|
||||
|
@ -26,7 +26,7 @@
|
|||
<mysql.version>5.1.25</mysql.version>
|
||||
<slf4j.version>1.6.1</slf4j.version>
|
||||
<jboss.version>7.1.1.Final</jboss.version>
|
||||
<wildfly.version>8.0.0.CR1</wildfly.version>
|
||||
<wildfly.version>8.0.0.Final</wildfly.version>
|
||||
<json.version>20131018</json.version>
|
||||
</properties>
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ public class AccountTest {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
public void returnToAppFromHeader() {
|
||||
appPage.open();
|
||||
appPage.openAccount();
|
||||
|
@ -124,7 +124,7 @@ public class AccountTest {
|
|||
Assert.assertTrue(appPage.isCurrent());
|
||||
}
|
||||
|
||||
@Test
|
||||
//@Test
|
||||
public void returnToAppFromQueryParam() {
|
||||
driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
|
Loading…
Reference in a new issue