Merge pull request #1234 from mstruk/wfly-subs-split-master
Wildfly 9 - subsystem split + feature packs
This commit is contained in:
commit
833c276424
228 files changed
+6741
-1174
No files matched your search
@@ -71,25 +71,25 @@
|
||||
<dependency>
|
||||
<groupId>org.jboss.as</groupId>
|
||||
<artifactId>jboss-as-naming</artifactId>
|
||||
<version>7.1.1.Final</version>
|
||||
<version>${jboss.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.as</groupId>
|
||||
<artifactId>jboss-as-server</artifactId>
|
||||
<version>7.1.1.Final</version>
|
||||
<version>${jboss.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.as</groupId>
|
||||
<artifactId>jboss-as-ee</artifactId>
|
||||
<version>7.1.1.Final</version>
|
||||
<version>${jboss.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.as</groupId>
|
||||
<artifactId>jboss-as-web</artifactId>
|
||||
<version>7.1.1.Final</version>
|
||||
<version>${jboss.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
|
||||
import org.jboss.as.version.Version;
|
||||
import org.jboss.modules.Module;
|
||||
import org.jboss.modules.ModuleIdentifier;
|
||||
import org.jboss.modules.ModuleLoadException;
|
||||
|
||||
/**
|
||||
* Allows the Keycloak subsystem to learn about its environment.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
|
||||
*/
|
||||
public class Environment {
|
||||
private static final ModuleIdentifier KEYCLOAK_SUBSYSTEM = ModuleIdentifier.create("org.keycloak.keycloak-subsystem");
|
||||
|
||||
private static final boolean isWildFly = findIsWildFly();
|
||||
|
||||
public Environment() {
|
||||
}
|
||||
|
||||
private static boolean findIsWildFly() {
|
||||
try {
|
||||
return !Version.AS_VERSION.startsWith("7");
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Module getSubsysModule() {
|
||||
// Unfortunately, we can't cache this because unit tests will fail
|
||||
try {
|
||||
return Module.getModuleFromCallerModuleLoader(KEYCLOAK_SUBSYSTEM);
|
||||
} catch (ModuleLoadException e) {
|
||||
throw new IllegalStateException("Can't find Keycloak subsystem.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isWildFly() {
|
||||
return isWildFly;
|
||||
}
|
||||
}
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
|
||||
import org.jboss.as.server.deployment.DeploymentPhaseContext;
|
||||
import org.jboss.as.server.deployment.DeploymentUnit;
|
||||
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
|
||||
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
|
||||
import org.jboss.as.web.deployment.WarMetaData;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.metadata.javaee.spec.ParamValueMetaData;
|
||||
import org.jboss.metadata.web.jboss.JBossWebMetaData;
|
||||
import org.jboss.metadata.web.jboss.ValveMetaData;
|
||||
import org.jboss.metadata.web.spec.LoginConfigMetaData;
|
||||
import org.keycloak.adapters.jbossweb.KeycloakAuthenticatorValve;
|
||||
import org.keycloak.subsystem.logging.KeycloakLogger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Pass authentication data (keycloak.json) as a servlet context param so it can be read by the KeycloakServletExtension.
|
||||
* This is used for EAP6.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
|
||||
*/
|
||||
|
||||
// Note: Even though this class closely resembles the WildFly KeycloakAdapterConfigDeploymentProcessor
|
||||
// it can not be easily refactored because the WarMetaData classes are of different types.
|
||||
public class KeycloakAdapterConfigDeploymentProcessorEAP6 implements DeploymentUnitProcessor {
|
||||
protected Logger log = Logger.getLogger(KeycloakAdapterConfigDeploymentProcessorEAP6.class);
|
||||
|
||||
@Override
|
||||
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
|
||||
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
|
||||
String deploymentName = deploymentUnit.getName();
|
||||
|
||||
KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance();
|
||||
//log.info("********* CHECK KEYCLOAK DEPLOYMENT: " + deploymentName);
|
||||
if (service.isSecureDeployment(deploymentName)) {
|
||||
addKeycloakAuthData(phaseContext, deploymentName, service);
|
||||
return;
|
||||
}
|
||||
|
||||
// else check to see if KEYCLOAK is specified as login config
|
||||
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
|
||||
if (warMetaData == null) return;
|
||||
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
|
||||
if (webMetaData == null) return;
|
||||
|
||||
LoginConfigMetaData loginConfig = webMetaData.getLoginConfig();
|
||||
if (loginConfig != null && "KEYCLOAK".equalsIgnoreCase(loginConfig.getAuthMethod())) {
|
||||
addValve(webMetaData);
|
||||
}
|
||||
}
|
||||
|
||||
private void addKeycloakAuthData(DeploymentPhaseContext phaseContext, String deploymentName, KeycloakAdapterConfigService service) {
|
||||
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
|
||||
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
|
||||
|
||||
addJSONData(service.getJSON(deploymentName), warMetaData);
|
||||
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
|
||||
if (webMetaData == null) {
|
||||
webMetaData = new JBossWebMetaData();
|
||||
warMetaData.setMergedJBossWebMetaData(webMetaData);
|
||||
}
|
||||
addValve(webMetaData);
|
||||
|
||||
LoginConfigMetaData loginConfig = webMetaData.getLoginConfig();
|
||||
if (loginConfig == null) {
|
||||
loginConfig = new LoginConfigMetaData();
|
||||
webMetaData.setLoginConfig(loginConfig);
|
||||
}
|
||||
loginConfig.setAuthMethod("KEYCLOAK");
|
||||
loginConfig.setRealmName(service.getRealmName(deploymentName));
|
||||
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentName);
|
||||
}
|
||||
|
||||
private void addValve(JBossWebMetaData webMetaData) {
|
||||
List<ValveMetaData> valves = webMetaData.getValves();
|
||||
if (valves == null) {
|
||||
valves = new ArrayList<ValveMetaData>(1);
|
||||
webMetaData.setValves(valves);
|
||||
}
|
||||
ValveMetaData valve = new ValveMetaData();
|
||||
valve.setValveClass(KeycloakAuthenticatorValve.class.getName());
|
||||
valve.setModule("org.keycloak.keycloak-as7-adapter");
|
||||
//log.info("******* adding Keycloak valve to: " + deploymentName);
|
||||
valves.add(valve);
|
||||
}
|
||||
|
||||
private void addJSONData(String json, WarMetaData warMetaData) {
|
||||
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
|
||||
if (webMetaData == null) {
|
||||
webMetaData = new JBossWebMetaData();
|
||||
warMetaData.setMergedJBossWebMetaData(webMetaData);
|
||||
}
|
||||
|
||||
List<ParamValueMetaData> contextParams = webMetaData.getContextParams();
|
||||
if (contextParams == null) {
|
||||
contextParams = new ArrayList<ParamValueMetaData>();
|
||||
}
|
||||
|
||||
ParamValueMetaData param = new ParamValueMetaData();
|
||||
param.setParamName(KeycloakAdapterConfigDeploymentProcessor.AUTH_DATA_PARAM_NAME);
|
||||
param.setParamValue(json);
|
||||
contextParams.add(param);
|
||||
|
||||
webMetaData.setContextParams(contextParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undeploy(DeploymentUnit du) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
org.keycloak.subsystem.extension.KeycloakExtension
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Template used by WildFly build when directed to include Keycloak subsystem in a configuration. -->
|
||||
<config>
|
||||
<extension-module>org.keycloak.keycloak-subsystem</extension-module>
|
||||
<subsystem xmlns="urn:jboss:domain:keycloak:1.0">
|
||||
<?WILDFLY-WEB-CONSOLE-CONFIG?>
|
||||
</subsystem>
|
||||
|
||||
<!-- Used in the WildFly build to create standalone-keycloak.xml -->
|
||||
<supplement name="web-console-client-config">
|
||||
<replacement placeholder="WILDFLY-WEB-CONSOLE-CONFIG">
|
||||
<secure-deployment name="web-console">
|
||||
<realm>master</realm>
|
||||
<realm-public-key>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB</realm-public-key>
|
||||
<auth-server-url>http://localhost:8080/auth</auth-server-url>
|
||||
<ssl-required>EXTERNAL</ssl-required>
|
||||
<resource>web-console</resource>
|
||||
<credential name="secret">0aa31d98-e0aa-404c-b6e0-e771dba1e798</credential>
|
||||
<use-resource-role-mappings>true</use-resource-role-mappings>
|
||||
</secure-deployment>
|
||||
<secure-deployment name="http-endpoint">
|
||||
<realm>master</realm>
|
||||
<realm-public-key>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB</realm-public-key>
|
||||
<auth-server-url>http://localhost:8080/auth</auth-server-url>
|
||||
<ssl-required>EXTERNAL</ssl-required>
|
||||
<resource>http-endpoint</resource>
|
||||
<credential name="secret">2769a4a2-5be0-454f-838f-f33b7755b667</credential>
|
||||
<use-resource-role-mappings>true</use-resource-role-mappings>
|
||||
</secure-deployment>
|
||||
</replacement>
|
||||
</supplement>
|
||||
|
||||
|
||||
</config>
|
||||
-171
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.jboss.as.controller.PathAddress;
|
||||
import org.jboss.as.controller.PathElement;
|
||||
import org.jboss.as.subsystem.test.AbstractSubsystemTest;
|
||||
import org.jboss.as.subsystem.test.KernelServices;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.*;
|
||||
|
||||
|
||||
/**
|
||||
* Tests all management expects for subsystem, parsing, marshaling, model definition and other
|
||||
* Here is an example that allows you a fine grained controller over what is tested and how. So it can give you ideas what can be done and tested.
|
||||
* If you have no need for advanced testing of subsystem you look at {@link SubsystemBaseParsingTestCase} that testes same stuff but most of the code
|
||||
* is hidden inside of test harness
|
||||
*
|
||||
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
|
||||
*/
|
||||
public class SubsystemParsingTestCase extends AbstractSubsystemTest {
|
||||
|
||||
public SubsystemParsingTestCase() {
|
||||
super(KeycloakExtension.SUBSYSTEM_NAME, new KeycloakExtension());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJson() throws Exception {
|
||||
ModelNode node = new ModelNode();
|
||||
node.get("realm").set("demo");
|
||||
node.get("resource").set("customer-portal");
|
||||
node.get("realm-public-key").set("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB");
|
||||
node.get("auth-url").set("http://localhost:8080/auth-server/rest/realms/demo/protocol/openid-connect/login");
|
||||
node.get("code-url").set("http://localhost:8080/auth-server/rest/realms/demo/protocol/openid-connect/access/codes");
|
||||
node.get("ssl-required").set("external");
|
||||
node.get("expose-token").set(true);
|
||||
ModelNode credential = new ModelNode();
|
||||
credential.get("password").set("password");
|
||||
node.get("credentials").set(credential);
|
||||
|
||||
System.out.println("json=" + node.toJSONString(false));
|
||||
}
|
||||
/**
|
||||
* Tests that the xml is parsed into the correct operations
|
||||
*/
|
||||
@Test
|
||||
public void testParseSubsystem() throws Exception {
|
||||
//Parse the subsystem xml into operations
|
||||
String subsystemXml =
|
||||
"<subsystem xmlns=\"" + KeycloakExtension.NAMESPACE + "\">" +
|
||||
"</subsystem>";
|
||||
List<ModelNode> operations = super.parse(subsystemXml);
|
||||
|
||||
///Check that we have the expected number of operations
|
||||
Assert.assertEquals(1, operations.size());
|
||||
|
||||
//Check that each operation has the correct content
|
||||
ModelNode addSubsystem = operations.get(0);
|
||||
Assert.assertEquals(ADD, addSubsystem.get(OP).asString());
|
||||
PathAddress addr = PathAddress.pathAddress(addSubsystem.get(OP_ADDR));
|
||||
Assert.assertEquals(1, addr.size());
|
||||
PathElement element = addr.getElement(0);
|
||||
Assert.assertEquals(SUBSYSTEM, element.getKey());
|
||||
Assert.assertEquals(KeycloakExtension.SUBSYSTEM_NAME, element.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the model created from the xml looks as expected
|
||||
*/
|
||||
@Test
|
||||
public void testInstallIntoController() throws Exception {
|
||||
//Parse the subsystem xml and install into the controller
|
||||
String subsystemXml =
|
||||
"<subsystem xmlns=\"" + KeycloakExtension.NAMESPACE + "\">" +
|
||||
"</subsystem>";
|
||||
KernelServices services = super.installInController(subsystemXml);
|
||||
|
||||
//Read the whole model and make sure it looks as expected
|
||||
ModelNode model = services.readWholeModel();
|
||||
Assert.assertTrue(model.get(SUBSYSTEM).hasDefined(KeycloakExtension.SUBSYSTEM_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a controller with a given subsystem xml and then checks that a second
|
||||
* controller started with the xml marshalled from the first one results in the same model
|
||||
*/
|
||||
@Test
|
||||
public void testParseAndMarshalModel() throws Exception {
|
||||
//Parse the subsystem xml and install into the first controller
|
||||
//TODO: Figure out why this fails
|
||||
String subsystemXml =
|
||||
"<subsystem xmlns=\"" + KeycloakExtension.NAMESPACE + "\">" +
|
||||
"</subsystem>";
|
||||
KernelServices servicesA = super.installInController(subsystemXml);
|
||||
//Get the model and the persisted xml from the first controller
|
||||
ModelNode modelA = servicesA.readWholeModel();
|
||||
String marshalled = servicesA.getPersistedSubsystemXml();
|
||||
|
||||
//Install the persisted xml from the first controller into a second controller
|
||||
KernelServices servicesB = super.installInController(marshalled);
|
||||
ModelNode modelB = servicesB.readWholeModel();
|
||||
|
||||
//Make sure the models from the two controllers are identical
|
||||
super.compare(modelA, modelB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a controller with the given subsystem xml and then checks that a second
|
||||
* controller started with the operations from its describe action results in the same model
|
||||
*/
|
||||
@Test
|
||||
public void testDescribeHandler() throws Exception {
|
||||
//Parse the subsystem xml and install into the first controller
|
||||
String subsystemXml =
|
||||
"<subsystem xmlns=\"" + KeycloakExtension.NAMESPACE + "\">" +
|
||||
"</subsystem>";
|
||||
KernelServices servicesA = super.installInController(subsystemXml);
|
||||
//Get the model and the describe operations from the first controller
|
||||
ModelNode modelA = servicesA.readWholeModel();
|
||||
ModelNode describeOp = new ModelNode();
|
||||
describeOp.get(OP).set(DESCRIBE);
|
||||
describeOp.get(OP_ADDR).set(
|
||||
PathAddress.pathAddress(
|
||||
PathElement.pathElement(SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME)).toModelNode());
|
||||
List<ModelNode> operations = super.checkResultAndGetContents(servicesA.executeOperation(describeOp)).asList();
|
||||
|
||||
|
||||
//Install the describe options from the first controller into a second controller
|
||||
KernelServices servicesB = super.installInController(operations);
|
||||
ModelNode modelB = servicesB.readWholeModel();
|
||||
|
||||
//Make sure the models from the two controllers are identical
|
||||
super.compare(modelA, modelB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the subsystem can be removed
|
||||
*/
|
||||
@Test
|
||||
public void testSubsystemRemoval() throws Exception {
|
||||
//Parse the subsystem xml and install into the first controller
|
||||
String subsystemXml =
|
||||
"<subsystem xmlns=\"" + KeycloakExtension.NAMESPACE + "\">" +
|
||||
"</subsystem>";
|
||||
KernelServices services = super.installInController(subsystemXml);
|
||||
//Checks that the subsystem was removed from the model
|
||||
super.assertRemoveSubsystemResources(services);
|
||||
|
||||
//TODO Chek that any services that were installed were removed here
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -22,9 +22,7 @@
|
||||
<module>as7-eap6/adapter</module>
|
||||
<module>jetty</module>
|
||||
<module>undertow</module>
|
||||
<module>wildfly-adapter</module>
|
||||
<module>wildfly-extensions</module>
|
||||
<module>keycloak-subsystem</module>
|
||||
<module>wildfly</module>
|
||||
<module>keycloak-as7-subsystem</module>
|
||||
<module>js</module>
|
||||
<module>installed</module>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<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.3.0.Beta1-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<name>Keycloak WildFly Integration</name>
|
||||
<description/>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-wildfly-integration-pom</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>wildfly-adapter</module>
|
||||
<module>wildfly-extensions</module>
|
||||
<module>wildfly-server-subsystem</module>
|
||||
<module>wildfly-adapter-subsystem</module>
|
||||
</modules>
|
||||
</project>
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013 JBoss Inc
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>1.3.0.Beta1-SNAPSHOT</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>keycloak-wildfly-adapter-subsystem</artifactId>
|
||||
<name>Keycloak Adapter Subsystem</name>
|
||||
<description/>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<redirectTestOutputToFile>false</redirectTestOutputToFile>
|
||||
<enableAssertions>true</enableAssertions>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>jboss.home</name>
|
||||
<value>${jboss.home}</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
<includes>
|
||||
<include>**/*TestCase.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.wildfly.core</groupId>
|
||||
<artifactId>wildfly-controller</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wildfly.core</groupId>
|
||||
<artifactId>wildfly-server</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wildfly</groupId>
|
||||
<artifactId>wildfly-web-common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging-annotations</artifactId>
|
||||
<version>${jboss-logging-tools.version}</version>
|
||||
<!-- This is a compile-time dependency of this project, but is not needed at compile or runtime by other
|
||||
projects that depend on this project.-->
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging-processor</artifactId>
|
||||
<!-- This is a compile-time dependency of this project, but is not needed at compile or runtime by other
|
||||
projects that depend on this project.-->
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.wildfly.core</groupId>
|
||||
<artifactId>wildfly-subsystem-test-framework</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-wildfly-adapter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+2
-6
@@ -15,17 +15,13 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Add a credential to a deployment.
|
||||
@@ -39,7 +35,7 @@ public class CredentialAddHandler extends AbstractAddStepHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
|
||||
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
|
||||
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
|
||||
ckService.addCredential(operation, context.resolveExpressions(model));
|
||||
}
|
||||
+1
-2
@@ -14,7 +14,7 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
import org.jboss.as.controller.PathElement;
|
||||
@@ -36,7 +36,6 @@ public class CredentialDefinition extends SimpleResourceDefinition {
|
||||
|
||||
protected static final AttributeDefinition VALUE =
|
||||
new SimpleAttributeDefinitionBuilder("value", ModelType.STRING, false)
|
||||
.setXmlName("value")
|
||||
.setAllowExpression(true)
|
||||
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, false, true))
|
||||
.build();
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.AbstractWriteAttributeHandler;
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.AbstractRemoveStepHandler;
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
+2
-2
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.server.deployment.DeploymentPhaseContext;
|
||||
import org.jboss.as.server.deployment.DeploymentUnit;
|
||||
@@ -26,7 +26,7 @@ import org.jboss.logging.Logger;
|
||||
import org.jboss.metadata.javaee.spec.ParamValueMetaData;
|
||||
import org.jboss.metadata.web.jboss.JBossWebMetaData;
|
||||
import org.jboss.metadata.web.spec.LoginConfigMetaData;
|
||||
import org.keycloak.subsystem.logging.KeycloakLogger;
|
||||
import org.keycloak.subsystem.adapter.logging.KeycloakLogger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
+2
-27
@@ -15,11 +15,10 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.jboss.dmr.Property;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -33,7 +32,7 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
|
||||
*/
|
||||
public final class KeycloakAdapterConfigService {
|
||||
protected Logger log = Logger.getLogger(KeycloakAdapterConfigService.class);
|
||||
|
||||
private static final String CREDENTIALS_JSON_NAME = "credentials";
|
||||
|
||||
private static final KeycloakAdapterConfigService INSTANCE = new KeycloakAdapterConfigService();
|
||||
@@ -47,30 +46,10 @@ public final class KeycloakAdapterConfigService {
|
||||
// keycloak-secured deployments
|
||||
private final Map<String, ModelNode> secureDeployments = new HashMap<String, ModelNode>();
|
||||
|
||||
// key=auth-server deployment name; value=web-context
|
||||
private final Map<String, String> webContexts = new HashMap<String, String>();
|
||||
|
||||
|
||||
|
||||
private KeycloakAdapterConfigService() {
|
||||
}
|
||||
|
||||
public void addServerDeployment(String deploymentName, String webContext) {
|
||||
this.webContexts.put(deploymentName, webContext);
|
||||
}
|
||||
|
||||
public String getWebContext(String deploymentName) {
|
||||
return webContexts.get(deploymentName);
|
||||
}
|
||||
|
||||
public void removeServerDeployment(String deploymentName) {
|
||||
this.webContexts.remove(deploymentName);
|
||||
}
|
||||
|
||||
public boolean isWebContextUsed(String webContext) {
|
||||
return webContexts.containsValue(webContext);
|
||||
}
|
||||
|
||||
public void addRealm(ModelNode operation, ModelNode model) {
|
||||
this.realms.put(realmNameFromOp(operation), model.clone());
|
||||
}
|
||||
@@ -197,8 +176,4 @@ public final class KeycloakAdapterConfigService {
|
||||
|
||||
return this.secureDeployments.containsKey(deploymentName);
|
||||
}
|
||||
|
||||
public boolean isKeycloakServerDeployment(String deploymentName) {
|
||||
return this.webContexts.containsKey(deploymentName);
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.server.deployment.Attachments;
|
||||
import org.jboss.as.server.deployment.DeploymentPhaseContext;
|
||||
import org.jboss.as.server.deployment.DeploymentUnit;
|
||||
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
|
||||
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
|
||||
import org.jboss.as.server.deployment.module.ModuleDependency;
|
||||
import org.jboss.as.server.deployment.module.ModuleSpecification;
|
||||
import org.jboss.modules.Module;
|
||||
import org.jboss.modules.ModuleIdentifier;
|
||||
import org.jboss.modules.ModuleLoader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
|
||||
*/
|
||||
public abstract class KeycloakDependencyProcessor implements DeploymentUnitProcessor {
|
||||
|
||||
private static final ModuleIdentifier KEYCLOAK_JBOSS_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-jboss-adapter-core");
|
||||
private static final ModuleIdentifier KEYCLOAK_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-adapter-core");
|
||||
private static final ModuleIdentifier KEYCLOAK_CORE = ModuleIdentifier.create("org.keycloak.keycloak-core");
|
||||
|
||||
@Override
|
||||
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
|
||||
final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
|
||||
|
||||
// Next phase, need to detect if this is a Keycloak deployment. If not, don't add the modules.
|
||||
|
||||
final ModuleSpecification moduleSpecification = deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION);
|
||||
final ModuleLoader moduleLoader = Module.getBootModuleLoader();
|
||||
addCommonModules(moduleSpecification, moduleLoader);
|
||||
addPlatformSpecificModules(moduleSpecification, moduleLoader);
|
||||
}
|
||||
|
||||
private void addCommonModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader) {
|
||||
// ModuleDependency(ModuleLoader moduleLoader, ModuleIdentifier identifier, boolean optional, boolean export, boolean importServices, boolean userSpecified)
|
||||
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_JBOSS_CORE_ADAPTER, false, false, false, false));
|
||||
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE_ADAPTER, false, false, false, false));
|
||||
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE, false, false, false, false));
|
||||
}
|
||||
|
||||
abstract protected void addPlatformSpecificModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader);
|
||||
|
||||
@Override
|
||||
public void undeploy(DeploymentUnit du) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+7
-5
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.server.deployment.module.ModuleDependency;
|
||||
import org.jboss.as.server.deployment.module.ModuleSpecification;
|
||||
@@ -23,17 +23,19 @@ import org.jboss.modules.ModuleIdentifier;
|
||||
import org.jboss.modules.ModuleLoader;
|
||||
|
||||
/**
|
||||
* Adds platform-specific modules for EAP6
|
||||
* Add platform-specific modules for WildFly.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
|
||||
*/
|
||||
public class KeycloakDependencyProcessorEAP6 extends KeycloakDependencyProcessor {
|
||||
public class KeycloakDependencyProcessorWildFly extends KeycloakDependencyProcessor {
|
||||
|
||||
private static final ModuleIdentifier KEYCLOAK_AS7_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-as7-adapter");
|
||||
private static final ModuleIdentifier KEYCLOAK_WILDFLY_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-wildfly-adapter");
|
||||
private static final ModuleIdentifier KEYCLOAK_UNDERTOW_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-undertow-adapter");
|
||||
|
||||
@Override
|
||||
protected void addPlatformSpecificModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader) {
|
||||
// ModuleDependency(ModuleLoader moduleLoader, ModuleIdentifier identifier, boolean optional, boolean export, boolean importServices, boolean userSpecified)
|
||||
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_AS7_ADAPTER, false, false, true, false));
|
||||
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_WILDFLY_ADAPTER, false, false, true, false));
|
||||
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_UNDERTOW_ADAPTER, false, false, false, false));
|
||||
}
|
||||
}
|
||||
+7
-12
@@ -14,18 +14,18 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.keycloak.subsystem.extension.authserver.AuthServerDefinition;
|
||||
import org.jboss.as.controller.Extension;
|
||||
import org.jboss.as.controller.ExtensionContext;
|
||||
import org.jboss.as.controller.ModelVersion;
|
||||
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.keycloak.subsystem.logging.KeycloakLogger;
|
||||
import org.keycloak.subsystem.adapter.logging.KeycloakLogger;
|
||||
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
|
||||
|
||||
@@ -38,16 +38,13 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUB
|
||||
public class KeycloakExtension implements Extension {
|
||||
|
||||
public static final String SUBSYSTEM_NAME = "keycloak";
|
||||
public static final String NAMESPACE = "urn:jboss:domain:keycloak:1.0";
|
||||
public static final String NAMESPACE = "urn:jboss:domain:keycloak:1.1";
|
||||
private static final KeycloakSubsystemParser PARSER = new KeycloakSubsystemParser();
|
||||
static final PathElement PATH_SUBSYSTEM = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
|
||||
private static final String RESOURCE_NAME = KeycloakExtension.class.getPackage().getName() + ".LocalDescriptions";
|
||||
private static final int MANAGEMENT_API_MAJOR_VERSION = 1;
|
||||
private static final int MANAGEMENT_API_MINOR_VERSION = 0;
|
||||
private static final int MANAGEMENT_API_MICRO_VERSION = 0;
|
||||
protected static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
|
||||
private static final ModelVersion MGMT_API_VERSION = ModelVersion.create(1,1,0);
|
||||
static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
|
||||
private static final ResourceDefinition KEYCLOAK_SUBSYSTEM_RESOURCE = new KeycloakSubsystemDefinition();
|
||||
static final AuthServerDefinition AUTH_SERVER_DEFINITION = new AuthServerDefinition();
|
||||
static final RealmDefinition REALM_DEFINITION = new RealmDefinition();
|
||||
static final SecureDeploymentDefinition SECURE_DEPLOYMENT_DEFINITION = new SecureDeploymentDefinition();
|
||||
static final CredentialDefinition CREDENTIAL_DEFINITION = new CredentialDefinition();
|
||||
@@ -74,11 +71,9 @@ public class KeycloakExtension implements Extension {
|
||||
@Override
|
||||
public void initialize(final ExtensionContext context) {
|
||||
KeycloakLogger.ROOT_LOGGER.debug("Activating Keycloak Extension");
|
||||
final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, MANAGEMENT_API_MAJOR_VERSION,
|
||||
MANAGEMENT_API_MINOR_VERSION, MANAGEMENT_API_MICRO_VERSION);
|
||||
final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, MGMT_API_VERSION);
|
||||
|
||||
ManagementResourceRegistration registration = subsystem.registerSubsystemModel(KEYCLOAK_SUBSYSTEM_RESOURCE);
|
||||
registration.registerSubModel(AUTH_SERVER_DEFINITION);
|
||||
registration.registerSubModel(REALM_DEFINITION);
|
||||
ManagementResourceRegistration secureDeploymentRegistration = registration.registerSubModel(SECURE_DEPLOYMENT_DEFINITION);
|
||||
secureDeploymentRegistration.registerSubModel(CREDENTIAL_DEFINITION);
|
||||
+4
-34
@@ -14,23 +14,17 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
|
||||
import org.jboss.as.controller.AbstractBoottimeAddStepHandler;
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
import org.jboss.as.controller.OperationFailedException;
|
||||
import org.jboss.as.controller.ServiceVerificationHandler;
|
||||
import org.jboss.as.server.AbstractDeploymentChainStep;
|
||||
import org.jboss.as.server.DeploymentProcessorTarget;
|
||||
import org.jboss.as.server.deployment.Phase;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.jboss.msc.service.ServiceController;
|
||||
|
||||
import java.util.List;
|
||||
import org.jboss.as.controller.registry.Resource;
|
||||
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
|
||||
import org.keycloak.subsystem.extension.authserver.KeycloakServerDeploymentProcessor;
|
||||
|
||||
/**
|
||||
* The Keycloak subsystem add update handler.
|
||||
@@ -42,14 +36,7 @@ class KeycloakSubsystemAdd extends AbstractBoottimeAddStepHandler {
|
||||
static final KeycloakSubsystemAdd INSTANCE = new KeycloakSubsystemAdd();
|
||||
|
||||
@Override
|
||||
protected void populateModel(OperationContext context, ModelNode operation, Resource resource) throws OperationFailedException {
|
||||
resource.getModel().setEmptyObject();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performBoottime(final OperationContext context, ModelNode operation, final ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) {
|
||||
protected void performBoottime(final OperationContext context, ModelNode operation, final ModelNode model) {
|
||||
context.addStep(new AbstractDeploymentChainStep() {
|
||||
@Override
|
||||
protected void execute(DeploymentProcessorTarget processorTarget) {
|
||||
@@ -58,32 +45,15 @@ class KeycloakSubsystemAdd extends AbstractBoottimeAddStepHandler {
|
||||
Phase.POST_MODULE, // PHASE
|
||||
Phase.POST_MODULE_VALIDATOR_FACTORY - 1, // PRIORITY
|
||||
chooseConfigDeploymentProcessor());
|
||||
processorTarget.addDeploymentProcessor(KeycloakExtension.SUBSYSTEM_NAME,
|
||||
Phase.POST_MODULE, // PHASE
|
||||
Phase.POST_MODULE_VALIDATOR_FACTORY - 1, // PRIORITY
|
||||
new KeycloakServerDeploymentProcessor());
|
||||
}
|
||||
}, OperationContext.Stage.RUNTIME);
|
||||
}
|
||||
|
||||
private DeploymentUnitProcessor chooseDependencyProcessor() {
|
||||
if (Environment.isWildFly()) {
|
||||
return new KeycloakDependencyProcessorWildFly();
|
||||
} else {
|
||||
return new KeycloakDependencyProcessorEAP6();
|
||||
}
|
||||
return new KeycloakDependencyProcessorWildFly();
|
||||
}
|
||||
|
||||
private DeploymentUnitProcessor chooseConfigDeploymentProcessor() {
|
||||
if (Environment.isWildFly()) {
|
||||
return new KeycloakAdapterConfigDeploymentProcessor();
|
||||
} else {
|
||||
return new KeycloakAdapterConfigDeploymentProcessorEAP6();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean requiresRuntimeVerification() {
|
||||
return false;
|
||||
return new KeycloakAdapterConfigDeploymentProcessor();
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -15,12 +15,10 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.PathElement;
|
||||
import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
|
||||
import org.jboss.as.controller.SimpleResourceDefinition;
|
||||
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
|
||||
import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
|
||||
import org.jboss.as.controller.registry.ManagementResourceRegistration;
|
||||
|
||||
@@ -31,7 +29,7 @@ import org.jboss.as.controller.registry.ManagementResourceRegistration;
|
||||
*/
|
||||
public class KeycloakSubsystemDefinition extends SimpleResourceDefinition {
|
||||
protected KeycloakSubsystemDefinition() {
|
||||
super(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
|
||||
super(KeycloakExtension.SUBSYSTEM_PATH,
|
||||
KeycloakExtension.getResourceDescriptionResolver("subsystem"),
|
||||
KeycloakSubsystemAdd.INSTANCE,
|
||||
ReloadRequiredRemoveStepHandler.INSTANCE
|
||||
+1
-39
@@ -14,9 +14,8 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.keycloak.subsystem.extension.authserver.AuthServerDefinition;
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
import org.jboss.as.controller.PathAddress;
|
||||
import org.jboss.as.controller.PathElement;
|
||||
@@ -59,8 +58,6 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
||||
}
|
||||
else if (reader.getLocalName().equals(SecureDeploymentDefinition.TAG_NAME)) {
|
||||
readDeployment(reader, list);
|
||||
} else if (reader.getLocalName().equals(AuthServerDefinition.TAG_NAME)) {
|
||||
readAuthServer(reader, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,24 +67,6 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
||||
return reader.nextTag();
|
||||
}
|
||||
|
||||
private void readAuthServer(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException {
|
||||
String authServerName = readNameAttribute(reader);
|
||||
ModelNode addAuthServer = new ModelNode();
|
||||
addAuthServer.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
|
||||
PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
|
||||
PathElement.pathElement(AuthServerDefinition.TAG_NAME, authServerName));
|
||||
addAuthServer.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
|
||||
|
||||
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
|
||||
String tagName = reader.getLocalName();
|
||||
SimpleAttributeDefinition def = AuthServerDefinition.lookup(tagName);
|
||||
if (def == null) throw new XMLStreamException("Unknown auth-server tag " + tagName);
|
||||
def.parseAndSetParameter(reader.getElementText(), addAuthServer, reader);
|
||||
}
|
||||
|
||||
list.add(addAuthServer);
|
||||
}
|
||||
|
||||
private void readRealm(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException {
|
||||
String realmName = readNameAttribute(reader);
|
||||
ModelNode addRealm = new ModelNode();
|
||||
@@ -178,28 +157,11 @@ class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<Li
|
||||
@Override
|
||||
public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context) throws XMLStreamException {
|
||||
context.startSubsystemElement(KeycloakExtension.NAMESPACE, false);
|
||||
writeAuthServers(writer, context);
|
||||
writeRealms(writer, context);
|
||||
writeSecureDeployments(writer, context);
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
private void writeAuthServers(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
|
||||
if (!context.getModelNode().get(AuthServerDefinition.TAG_NAME).isDefined()) {
|
||||
return;
|
||||
}
|
||||
for (Property authServer : context.getModelNode().get(AuthServerDefinition.TAG_NAME).asPropertyList()) {
|
||||
writer.writeStartElement(AuthServerDefinition.TAG_NAME);
|
||||
writer.writeAttribute("name", authServer.getName());
|
||||
ModelNode authServerElements = authServer.getValue();
|
||||
for (AttributeDefinition element : AuthServerDefinition.ALL_ATTRIBUTES) {
|
||||
element.marshallAsElement(authServerElements, writer);
|
||||
}
|
||||
|
||||
writer.writeEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeRealms(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
|
||||
if (!context.getModelNode().get(RealmDefinition.TAG_NAME).isDefined()) {
|
||||
return;
|
||||
+2
-6
@@ -15,17 +15,13 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
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;
|
||||
@@ -59,7 +55,7 @@ public final class RealmAddHandler extends AbstractAddStepHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
|
||||
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
|
||||
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
|
||||
ckService.addRealm(operation, context.resolveExpressions(model));
|
||||
}
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
import org.jboss.as.controller.PathElement;
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.AbstractRemoveStepHandler;
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
+1
-7
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.AbstractWriteAttributeHandler;
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
@@ -23,8 +23,6 @@ import org.jboss.as.controller.OperationContext;
|
||||
import org.jboss.as.controller.OperationFailedException;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Update an attribute on a realm.
|
||||
*
|
||||
@@ -32,10 +30,6 @@ import java.util.List;
|
||||
*/
|
||||
public class RealmWriteAttributeHandler extends AbstractWriteAttributeHandler<KeycloakAdapterConfigService> {
|
||||
|
||||
public RealmWriteAttributeHandler(List<AttributeDefinition> definitions) {
|
||||
this(definitions.toArray(new AttributeDefinition[definitions.size()]));
|
||||
}
|
||||
|
||||
public RealmWriteAttributeHandler(AttributeDefinition... definitions) {
|
||||
super(definitions);
|
||||
}
|
||||
+2
-6
@@ -15,17 +15,13 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
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;
|
||||
@@ -54,7 +50,7 @@ public final class SecureDeploymentAddHandler extends AbstractAddStepHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
|
||||
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
|
||||
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
|
||||
ckService.addSecureDeployment(operation, context.resolveExpressions(model));
|
||||
}
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
import org.jboss.as.controller.PathElement;
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.AbstractRemoveStepHandler;
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.AbstractWriteAttributeHandler;
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.controller.SimpleAttributeDefinition;
|
||||
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.logging;
|
||||
package org.keycloak.subsystem.adapter.logging;
|
||||
|
||||
import org.jboss.logging.BasicLogger;
|
||||
import org.jboss.logging.Logger;
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.adapter.logging;
|
||||
|
||||
import org.jboss.logging.Messages;
|
||||
import org.jboss.logging.annotations.MessageBundle;
|
||||
|
||||
/**
|
||||
* This interface to be fleshed out later when error messages are fully externalized.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2012 Red Hat Inc.
|
||||
*/
|
||||
@MessageBundle(projectCode = "KEYCLOAK")
|
||||
public interface KeycloakMessages {
|
||||
|
||||
/**
|
||||
* The messages
|
||||
*/
|
||||
KeycloakMessages MESSAGES = Messages.getBundle(KeycloakMessages.class);
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.keycloak.subsystem.adapter.extension.KeycloakExtension
|
||||
+3
-24
@@ -1,30 +1,9 @@
|
||||
keycloak.subsystem=Keycloak subsystem
|
||||
keycloak.subsystem.add=Operation Adds Keycloak subsystem
|
||||
keycloak.subsystem.remove=Operation removes Keycloak subsystem
|
||||
keycloak.subsystem.auth-server=Keycloak Auth Server
|
||||
keycloak.subsystem=Keycloak adapter subsystem
|
||||
keycloak.subsystem.add=Operation Adds Keycloak adapter subsystem
|
||||
keycloak.subsystem.remove=Operation removes Keycloak adapter subsystem
|
||||
keycloak.subsystem.realm=A Keycloak realm.
|
||||
keycloak.subsystem.secure-deployment=A deployment secured by Keycloak.
|
||||
|
||||
|
||||
keycloak.auth-server=A Keycloak Auth Server
|
||||
keycloak.auth-server.add=Add an Auth Server to the subsystem.
|
||||
keycloak.auth-server.remove=Remove an Auth Server from the subsystem.
|
||||
keycloak.auth-server.add-provider=Add a provider service jar to the Keycloak auth server.
|
||||
keycloak.auth-server.add-provider.uploaded-file-name=The file name of the provider service jar to be added or updated.
|
||||
keycloak.auth-server.add-provider.bytes-to-upload=The bytes of the provider service jar to be added or updated.
|
||||
keycloak.auth-server.add-provider.redeploy=Redeploy the auth server after adding the provider. Ignored if auth server is disabled.
|
||||
keycloak.auth-server.add-provider.overwrite=Overwrite even if the uploaded-file-name already exists as an overlay.
|
||||
keycloak.auth-server.list-overlays=List the overlays uploaded for this auth server.
|
||||
keycloak.auth-server.remove-overlay=Remove a provider jar, theme jar, or keycloak-server.json that has been uploaded to the auth server.
|
||||
keycloak.auth-server.remove-overlay.overlay-file-path=The uploaded path and file name of the overlay to be removed.
|
||||
keycloak.auth-server.remove-overlay.redeploy=Redeploy the auth server after removing the overlay.
|
||||
keycloak.auth-server.update-server-config=Upload a new keycloak-server.json configuration file for the Keycloak auth server.
|
||||
keycloak.auth-server.update-server-config.bytes-to-upload=The bytes of the keycloak-server.json file to be added or updated.
|
||||
keycloak.auth-server.update-server-config.redeploy=Redeploy the auth server after updating the server config.
|
||||
keycloak.auth-server.update-server-config.overwrite=Overwrite even if keycloak-server.json already exitss as an overlay.
|
||||
keycloak.auth-server.enabled=Enable or disable the Auth Server.
|
||||
keycloak.auth-server.web-context=Web context the auth-server will use. Also, the module name of the auth-server deployment.
|
||||
|
||||
keycloak.realm=A Keycloak realm.
|
||||
keycloak.realm.add=Add a realm definition to the subsystem.
|
||||
keycloak.realm.remove=Remove a realm from the subsystem.
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="urn:jboss:domain:keycloak:1.0"
|
||||
xmlns="urn:jboss:domain:keycloak:1.0"
|
||||
targetNamespace="urn:jboss:domain:keycloak:1.1"
|
||||
xmlns="urn:jboss:domain:keycloak:1.1"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified"
|
||||
version="1.0">
|
||||
@@ -14,7 +14,7 @@
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
<![CDATA[
|
||||
The Keycloak subsystem, used to register deployments managed by Keycloak
|
||||
The Keycloak adapter subsystem, used to register deployments managed by Keycloak
|
||||
]]>
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
@@ -40,7 +40,7 @@
|
||||
<xs:element name="expose-token" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="disable-trust-manager" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="ssl-required" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="cors-allowed-methods" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="cors-allowed-methods" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="auth-server-url-for-backend-requests" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="always-refresh-token" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
|
||||
@@ -67,7 +67,7 @@
|
||||
<xs:element name="auth-server-url" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="realm" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="disable-trust-manager" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="cors-allowed-methods" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="cors-allowed-methods" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="bearer-only" type="xs:boolean" minOccurs="0" maxOccurs="1" />
|
||||
<xs:element name="cors-allowed-headers" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="resource" type="xs:string" minOccurs="0" maxOccurs="1" />
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Template used by WildFly build when directed to include Keycloak subsystem in a configuration. -->
|
||||
<config>
|
||||
<extension-module>org.keycloak.keycloak-adapter-subsystem</extension-module>
|
||||
<subsystem xmlns="urn:jboss:domain:keycloak:1.1">
|
||||
</subsystem>
|
||||
</config>
|
||||
+1
-4
@@ -14,16 +14,13 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension;
|
||||
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.adapter.extension;
|
||||
|
||||
import org.jboss.as.subsystem.test.AbstractSubsystemBaseTest;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Tests all management expects for subsystem, parsing, marshaling, model definition and other
|
||||
* Here is an example that allows you a fine grained controller over what is tested and how. So it can give you ideas what can be done and tested.
|
||||
* If you have no need for advanced testing of subsystem you look at {@link SubsystemBaseParsingTestCase} that testes same stuff but most of the code
|
||||
* is hidden inside of test harness
|
||||
*
|
||||
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
|
||||
* @author Tomaz Cerar
|
||||
* @author <a href="marko.strukelj@gmail.com">Marko Strukelj</a>
|
||||
*/
|
||||
public class SubsystemParsingTestCase extends AbstractSubsystemBaseTest {
|
||||
|
||||
public SubsystemParsingTestCase() {
|
||||
super(KeycloakExtension.SUBSYSTEM_NAME, new KeycloakExtension());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJson() throws Exception {
|
||||
ModelNode node = new ModelNode();
|
||||
node.get("realm").set("demo");
|
||||
node.get("resource").set("customer-portal");
|
||||
node.get("realm-public-key").set("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB");
|
||||
node.get("auth-url").set("http://localhost:8080/auth-server/rest/realms/demo/protocol/openid-connect/login");
|
||||
node.get("code-url").set("http://localhost:8080/auth-server/rest/realms/demo/protocol/openid-connect/access/codes");
|
||||
node.get("ssl-required").set("external");
|
||||
node.get("expose-token").set(true);
|
||||
ModelNode credential = new ModelNode();
|
||||
credential.get("password").set("password");
|
||||
node.get("credentials").set(credential);
|
||||
|
||||
System.out.println("json=" + node.toJSONString(false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSubsystemXml() throws IOException {
|
||||
return readResource("keycloak-1.1.xml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSubsystemXsdPath() throws Exception {
|
||||
return "schema/wildfly-keycloak_1_1.xsd";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getSubsystemTemplatePaths() throws IOException {
|
||||
return new String[]{
|
||||
"/subsystem-templates/keycloak-adapter.xml"
|
||||
};
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<subsystem xmlns="urn:jboss:domain:keycloak:1.1">
|
||||
<secure-deployment name="web-console">
|
||||
<realm>master</realm>
|
||||
<resource>web-console</resource>
|
||||
<use-resource-role-mappings>true</use-resource-role-mappings>
|
||||
<realm-public-key>
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB
|
||||
</realm-public-key>
|
||||
<auth-server-url>http://localhost:8080/auth</auth-server-url>
|
||||
<ssl-required>EXTERNAL</ssl-required>
|
||||
<credential name="secret">0aa31d98-e0aa-404c-b6e0-e771dba1e798</credential>
|
||||
</secure-deployment>
|
||||
<secure-deployment name="http-endpoint">
|
||||
<realm>master</realm>
|
||||
<resource>http-endpoint</resource>
|
||||
<use-resource-role-mappings>true</use-resource-role-mappings>
|
||||
<realm-public-key>
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4siLKUew0WYxdtq6/rwk4Uj/4amGFFnE/yzIxQVU0PUqz3QBRVkUWpDj0K6ZnS5nzJV/y6DHLEy7hjZTdRDphyF1sq09aDOYnVpzu8o2sIlMM8q5RnUyEfIyUZqwo8pSZDJ90fS0s+IDUJNCSIrAKO3w1lqZDHL6E/YFHXyzkvQIDAQAB
|
||||
</realm-public-key>
|
||||
<auth-server-url>http://localhost:8080/auth</auth-server-url>
|
||||
<ssl-required>EXTERNAL</ssl-required>
|
||||
<credential name="secret">2769a4a2-5be0-454f-838f-f33b7755b667</credential>
|
||||
</secure-deployment>
|
||||
</subsystem>
|
||||
+104
-104
@@ -1,104 +1,104 @@
|
||||
<?xml version="1.0"?>
|
||||
<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.3.0.Beta1-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-wildfly-adapter</artifactId>
|
||||
<name>Keycloak Wildfly Integration</name>
|
||||
<description/>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
<version>${jboss.logging.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-undertow-adapter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-jboss-adapter-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
<artifactId>base64</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-asl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-xc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketbox</groupId>
|
||||
<artifactId>picketbox</artifactId>
|
||||
<version>4.0.20.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-servlet</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
<?xml version="1.0"?>
|
||||
<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.3.0.Beta1-SNAPSHOT</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>keycloak-wildfly-adapter</artifactId>
|
||||
<name>Keycloak Wildfly Integration</name>
|
||||
<description/>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
<version>${jboss.logging.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-adapter-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-undertow-adapter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-jboss-adapter-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.iharder</groupId>
|
||||
<artifactId>base64</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-asl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-xc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.picketbox</groupId>
|
||||
<artifactId>picketbox</artifactId>
|
||||
<version>4.0.20.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-servlet</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
+116
-116
@@ -1,116 +1,116 @@
|
||||
package org.keycloak.adapters.wildfly;
|
||||
|
||||
import org.jboss.security.NestableGroup;
|
||||
import org.jboss.security.SecurityConstants;
|
||||
import org.jboss.security.SecurityContextAssociation;
|
||||
import org.jboss.security.SimpleGroup;
|
||||
import org.jboss.security.SimplePrincipal;
|
||||
import org.keycloak.adapters.KeycloakAccount;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import java.security.Principal;
|
||||
import java.security.acl.Group;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class SecurityInfoHelper {
|
||||
public static void propagateSessionInfo(KeycloakAccount account) {
|
||||
Subject subject = new Subject();
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
principals.add(account.getPrincipal());
|
||||
Group[] roleSets = getRoleSets(account.getRoles());
|
||||
for (int g = 0; g < roleSets.length; g++) {
|
||||
Group group = roleSets[g];
|
||||
String name = group.getName();
|
||||
Group subjectGroup = createGroup(name, principals);
|
||||
if (subjectGroup instanceof NestableGroup) {
|
||||
/* A NestableGroup only allows Groups to be added to it so we
|
||||
need to add a SimpleGroup to subjectRoles to contain the roles
|
||||
*/
|
||||
SimpleGroup tmp = new SimpleGroup("Roles");
|
||||
subjectGroup.addMember(tmp);
|
||||
subjectGroup = tmp;
|
||||
}
|
||||
// Copy the group members to the Subject group
|
||||
Enumeration<? extends Principal> members = group.members();
|
||||
while (members.hasMoreElements()) {
|
||||
Principal role = (Principal) members.nextElement();
|
||||
subjectGroup.addMember(role);
|
||||
}
|
||||
}
|
||||
// add the CallerPrincipal group if none has been added in getRoleSets
|
||||
Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP);
|
||||
callerGroup.addMember(account.getPrincipal());
|
||||
principals.add(callerGroup);
|
||||
org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext();
|
||||
Principal userPrincipal = getPrincipal(subject);
|
||||
sc.getUtil().createSubjectInfo(userPrincipal, account, subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is
|
||||
* considered or the single subject inside the CallerPrincipal group.
|
||||
*
|
||||
* @param subject
|
||||
* @return the authenticated subject
|
||||
*/
|
||||
protected static Principal getPrincipal(Subject subject) {
|
||||
Principal principal = null;
|
||||
Principal callerPrincipal = null;
|
||||
if (subject != null) {
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
if (principals != null && !principals.isEmpty()) {
|
||||
for (Principal p : principals) {
|
||||
if (!(p instanceof Group) && principal == null) {
|
||||
principal = p;
|
||||
}
|
||||
if (p instanceof Group) {
|
||||
Group g = Group.class.cast(p);
|
||||
if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) {
|
||||
Enumeration<? extends Principal> e = g.members();
|
||||
if (e.hasMoreElements())
|
||||
callerPrincipal = e.nextElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return callerPrincipal == null ? principal : callerPrincipal;
|
||||
}
|
||||
|
||||
protected static Group createGroup(String name, Set<Principal> principals) {
|
||||
Group roles = null;
|
||||
Iterator<Principal> iter = principals.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object next = iter.next();
|
||||
if ((next instanceof Group) == false)
|
||||
continue;
|
||||
Group grp = (Group) next;
|
||||
if (grp.getName().equals(name)) {
|
||||
roles = grp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If we did not find a group create one
|
||||
if (roles == null) {
|
||||
roles = new SimpleGroup(name);
|
||||
principals.add(roles);
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
protected static Group[] getRoleSets(Collection<String> roleSet) {
|
||||
SimpleGroup roles = new SimpleGroup("Roles");
|
||||
Group[] roleSets = {roles};
|
||||
for (String role : roleSet) {
|
||||
roles.addMember(new SimplePrincipal(role));
|
||||
}
|
||||
return roleSets;
|
||||
}
|
||||
}
|
||||
package org.keycloak.adapters.wildfly;
|
||||
|
||||
import org.jboss.security.NestableGroup;
|
||||
import org.jboss.security.SecurityConstants;
|
||||
import org.jboss.security.SecurityContextAssociation;
|
||||
import org.jboss.security.SimpleGroup;
|
||||
import org.jboss.security.SimplePrincipal;
|
||||
import org.keycloak.adapters.KeycloakAccount;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import java.security.Principal;
|
||||
import java.security.acl.Group;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class SecurityInfoHelper {
|
||||
public static void propagateSessionInfo(KeycloakAccount account) {
|
||||
Subject subject = new Subject();
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
principals.add(account.getPrincipal());
|
||||
Group[] roleSets = getRoleSets(account.getRoles());
|
||||
for (int g = 0; g < roleSets.length; g++) {
|
||||
Group group = roleSets[g];
|
||||
String name = group.getName();
|
||||
Group subjectGroup = createGroup(name, principals);
|
||||
if (subjectGroup instanceof NestableGroup) {
|
||||
/* A NestableGroup only allows Groups to be added to it so we
|
||||
need to add a SimpleGroup to subjectRoles to contain the roles
|
||||
*/
|
||||
SimpleGroup tmp = new SimpleGroup("Roles");
|
||||
subjectGroup.addMember(tmp);
|
||||
subjectGroup = tmp;
|
||||
}
|
||||
// Copy the group members to the Subject group
|
||||
Enumeration<? extends Principal> members = group.members();
|
||||
while (members.hasMoreElements()) {
|
||||
Principal role = (Principal) members.nextElement();
|
||||
subjectGroup.addMember(role);
|
||||
}
|
||||
}
|
||||
// add the CallerPrincipal group if none has been added in getRoleSets
|
||||
Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP);
|
||||
callerGroup.addMember(account.getPrincipal());
|
||||
principals.add(callerGroup);
|
||||
org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext();
|
||||
Principal userPrincipal = getPrincipal(subject);
|
||||
sc.getUtil().createSubjectInfo(userPrincipal, account, subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is
|
||||
* considered or the single subject inside the CallerPrincipal group.
|
||||
*
|
||||
* @param subject
|
||||
* @return the authenticated subject
|
||||
*/
|
||||
protected static Principal getPrincipal(Subject subject) {
|
||||
Principal principal = null;
|
||||
Principal callerPrincipal = null;
|
||||
if (subject != null) {
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
if (principals != null && !principals.isEmpty()) {
|
||||
for (Principal p : principals) {
|
||||
if (!(p instanceof Group) && principal == null) {
|
||||
principal = p;
|
||||
}
|
||||
if (p instanceof Group) {
|
||||
Group g = Group.class.cast(p);
|
||||
if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) {
|
||||
Enumeration<? extends Principal> e = g.members();
|
||||
if (e.hasMoreElements())
|
||||
callerPrincipal = e.nextElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return callerPrincipal == null ? principal : callerPrincipal;
|
||||
}
|
||||
|
||||
protected static Group createGroup(String name, Set<Principal> principals) {
|
||||
Group roles = null;
|
||||
Iterator<Principal> iter = principals.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object next = iter.next();
|
||||
if ((next instanceof Group) == false)
|
||||
continue;
|
||||
Group grp = (Group) next;
|
||||
if (grp.getName().equals(name)) {
|
||||
roles = grp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If we did not find a group create one
|
||||
if (roles == null) {
|
||||
roles = new SimpleGroup(name);
|
||||
principals.add(roles);
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
protected static Group[] getRoleSets(Collection<String> roleSet) {
|
||||
SimpleGroup roles = new SimpleGroup("Roles");
|
||||
Group[] roleSets = {roles};
|
||||
for (String role : roleSet) {
|
||||
roles.addMember(new SimplePrincipal(role));
|
||||
}
|
||||
return roleSets;
|
||||
}
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
package org.keycloak.adapters.wildfly;
|
||||
|
||||
import io.undertow.security.api.SecurityContext;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import io.undertow.servlet.api.ConfidentialPortManager;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.AdapterTokenStore;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.NodesRegistrationManagement;
|
||||
import org.keycloak.adapters.undertow.ServletKeycloakAuthMech;
|
||||
import org.keycloak.adapters.undertow.ServletRequestAuthenticator;
|
||||
import org.keycloak.adapters.undertow.UndertowHttpFacade;
|
||||
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class WildflyAuthenticationMechanism extends ServletKeycloakAuthMech {
|
||||
|
||||
public WildflyAuthenticationMechanism(AdapterDeploymentContext deploymentContext,
|
||||
UndertowUserSessionManagement userSessionManagement,
|
||||
NodesRegistrationManagement nodesRegistrationManagement,
|
||||
ConfidentialPortManager portManager, String errorPage) {
|
||||
super(deploymentContext, userSessionManagement, nodesRegistrationManagement, portManager, errorPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServletRequestAuthenticator createRequestAuthenticator(KeycloakDeployment deployment, HttpServerExchange exchange, SecurityContext securityContext, UndertowHttpFacade facade) {
|
||||
int confidentialPort = getConfidentilPort(exchange);
|
||||
AdapterTokenStore tokenStore = getTokenStore(exchange, facade, deployment, securityContext);
|
||||
return new WildflyRequestAuthenticator(facade, deployment,
|
||||
confidentialPort, securityContext, exchange, tokenStore);
|
||||
}
|
||||
}
|
||||
package org.keycloak.adapters.wildfly;
|
||||
|
||||
import io.undertow.security.api.SecurityContext;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import io.undertow.servlet.api.ConfidentialPortManager;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.AdapterTokenStore;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.NodesRegistrationManagement;
|
||||
import org.keycloak.adapters.undertow.ServletKeycloakAuthMech;
|
||||
import org.keycloak.adapters.undertow.ServletRequestAuthenticator;
|
||||
import org.keycloak.adapters.undertow.UndertowHttpFacade;
|
||||
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class WildflyAuthenticationMechanism extends ServletKeycloakAuthMech {
|
||||
|
||||
public WildflyAuthenticationMechanism(AdapterDeploymentContext deploymentContext,
|
||||
UndertowUserSessionManagement userSessionManagement,
|
||||
NodesRegistrationManagement nodesRegistrationManagement,
|
||||
ConfidentialPortManager portManager, String errorPage) {
|
||||
super(deploymentContext, userSessionManagement, nodesRegistrationManagement, portManager, errorPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServletRequestAuthenticator createRequestAuthenticator(KeycloakDeployment deployment, HttpServerExchange exchange, SecurityContext securityContext, UndertowHttpFacade facade) {
|
||||
int confidentialPort = getConfidentilPort(exchange);
|
||||
AdapterTokenStore tokenStore = getTokenStore(exchange, facade, deployment, securityContext);
|
||||
return new WildflyRequestAuthenticator(facade, deployment,
|
||||
confidentialPort, securityContext, exchange, tokenStore);
|
||||
}
|
||||
}
|
||||
+25
-25
@@ -1,25 +1,25 @@
|
||||
package org.keycloak.adapters.wildfly;
|
||||
|
||||
import io.undertow.servlet.api.DeploymentInfo;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.NodesRegistrationManagement;
|
||||
import org.keycloak.adapters.undertow.KeycloakServletExtension;
|
||||
import org.keycloak.adapters.undertow.ServletKeycloakAuthMech;
|
||||
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class WildflyKeycloakServletExtension extends KeycloakServletExtension {
|
||||
protected static Logger log = Logger.getLogger(WildflyKeycloakServletExtension.class);
|
||||
|
||||
@Override
|
||||
protected ServletKeycloakAuthMech createAuthenticationMechanism(DeploymentInfo deploymentInfo, AdapterDeploymentContext deploymentContext,
|
||||
UndertowUserSessionManagement userSessionManagement, NodesRegistrationManagement nodesRegistrationManagement) {
|
||||
log.debug("creating WildflyAuthenticationMechanism");
|
||||
return new WildflyAuthenticationMechanism(deploymentContext, userSessionManagement, nodesRegistrationManagement, deploymentInfo.getConfidentialPortManager(), getErrorPage(deploymentInfo));
|
||||
|
||||
}
|
||||
}
|
||||
package org.keycloak.adapters.wildfly;
|
||||
|
||||
import io.undertow.servlet.api.DeploymentInfo;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.adapters.AdapterDeploymentContext;
|
||||
import org.keycloak.adapters.NodesRegistrationManagement;
|
||||
import org.keycloak.adapters.undertow.KeycloakServletExtension;
|
||||
import org.keycloak.adapters.undertow.ServletKeycloakAuthMech;
|
||||
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class WildflyKeycloakServletExtension extends KeycloakServletExtension {
|
||||
protected static Logger log = Logger.getLogger(WildflyKeycloakServletExtension.class);
|
||||
|
||||
@Override
|
||||
protected ServletKeycloakAuthMech createAuthenticationMechanism(DeploymentInfo deploymentInfo, AdapterDeploymentContext deploymentContext,
|
||||
UndertowUserSessionManagement userSessionManagement, NodesRegistrationManagement nodesRegistrationManagement) {
|
||||
log.debug("creating WildflyAuthenticationMechanism");
|
||||
return new WildflyAuthenticationMechanism(deploymentContext, userSessionManagement, nodesRegistrationManagement, deploymentInfo.getConfidentialPortManager(), getErrorPage(deploymentInfo));
|
||||
|
||||
}
|
||||
}
|
||||
+137
-137
@@ -1,137 +1,137 @@
|
||||
package org.keycloak.adapters.wildfly;
|
||||
|
||||
import io.undertow.security.api.SecurityContext;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.security.NestableGroup;
|
||||
import org.jboss.security.SecurityConstants;
|
||||
import org.jboss.security.SecurityContextAssociation;
|
||||
import org.jboss.security.SimpleGroup;
|
||||
import org.jboss.security.SimplePrincipal;
|
||||
import org.keycloak.adapters.AdapterTokenStore;
|
||||
import org.keycloak.adapters.HttpFacade;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.undertow.KeycloakUndertowAccount;
|
||||
import org.keycloak.adapters.undertow.ServletRequestAuthenticator;
|
||||
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import java.security.Principal;
|
||||
import java.security.acl.Group;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class WildflyRequestAuthenticator extends ServletRequestAuthenticator {
|
||||
protected static Logger log = Logger.getLogger(WildflyRequestAuthenticator.class);
|
||||
|
||||
public WildflyRequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment, int sslRedirectPort,
|
||||
SecurityContext securityContext, HttpServerExchange exchange,
|
||||
AdapterTokenStore tokenStore) {
|
||||
super(facade, deployment, sslRedirectPort, securityContext, exchange, tokenStore);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void propagateKeycloakContext(KeycloakUndertowAccount account) {
|
||||
super.propagateKeycloakContext(account);
|
||||
SecurityInfoHelper.propagateSessionInfo(account);
|
||||
log.debug("propagate security context to wildfly");
|
||||
Subject subject = new Subject();
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
principals.add(account.getPrincipal());
|
||||
Group[] roleSets = getRoleSets(account.getRoles());
|
||||
for (int g = 0; g < roleSets.length; g++) {
|
||||
Group group = roleSets[g];
|
||||
String name = group.getName();
|
||||
Group subjectGroup = createGroup(name, principals);
|
||||
if (subjectGroup instanceof NestableGroup) {
|
||||
/* A NestableGroup only allows Groups to be added to it so we
|
||||
need to add a SimpleGroup to subjectRoles to contain the roles
|
||||
*/
|
||||
SimpleGroup tmp = new SimpleGroup("Roles");
|
||||
subjectGroup.addMember(tmp);
|
||||
subjectGroup = tmp;
|
||||
}
|
||||
// Copy the group members to the Subject group
|
||||
Enumeration<? extends Principal> members = group.members();
|
||||
while (members.hasMoreElements()) {
|
||||
Principal role = (Principal) members.nextElement();
|
||||
subjectGroup.addMember(role);
|
||||
}
|
||||
}
|
||||
// add the CallerPrincipal group if none has been added in getRoleSets
|
||||
Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP);
|
||||
callerGroup.addMember(account.getPrincipal());
|
||||
principals.add(callerGroup);
|
||||
org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext();
|
||||
Principal userPrincipal = getPrincipal(subject);
|
||||
sc.getUtil().createSubjectInfo(userPrincipal, account, subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is
|
||||
* considered or the single subject inside the CallerPrincipal group.
|
||||
*
|
||||
* @param subject
|
||||
* @return the authenticated subject
|
||||
*/
|
||||
protected Principal getPrincipal(Subject subject) {
|
||||
Principal principal = null;
|
||||
Principal callerPrincipal = null;
|
||||
if (subject != null) {
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
if (principals != null && !principals.isEmpty()) {
|
||||
for (Principal p : principals) {
|
||||
if (!(p instanceof Group) && principal == null) {
|
||||
principal = p;
|
||||
}
|
||||
if (p instanceof Group) {
|
||||
Group g = Group.class.cast(p);
|
||||
if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) {
|
||||
Enumeration<? extends Principal> e = g.members();
|
||||
if (e.hasMoreElements())
|
||||
callerPrincipal = e.nextElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return callerPrincipal == null ? principal : callerPrincipal;
|
||||
}
|
||||
|
||||
protected Group createGroup(String name, Set<Principal> principals) {
|
||||
Group roles = null;
|
||||
Iterator<Principal> iter = principals.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object next = iter.next();
|
||||
if ((next instanceof Group) == false)
|
||||
continue;
|
||||
Group grp = (Group) next;
|
||||
if (grp.getName().equals(name)) {
|
||||
roles = grp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If we did not find a group create one
|
||||
if (roles == null) {
|
||||
roles = new SimpleGroup(name);
|
||||
principals.add(roles);
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
protected Group[] getRoleSets(Collection<String> roleSet) {
|
||||
SimpleGroup roles = new SimpleGroup("Roles");
|
||||
Group[] roleSets = {roles};
|
||||
for (String role : roleSet) {
|
||||
roles.addMember(new SimplePrincipal(role));
|
||||
}
|
||||
return roleSets;
|
||||
}
|
||||
|
||||
}
|
||||
package org.keycloak.adapters.wildfly;
|
||||
|
||||
import io.undertow.security.api.SecurityContext;
|
||||
import io.undertow.server.HttpServerExchange;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.security.NestableGroup;
|
||||
import org.jboss.security.SecurityConstants;
|
||||
import org.jboss.security.SecurityContextAssociation;
|
||||
import org.jboss.security.SimpleGroup;
|
||||
import org.jboss.security.SimplePrincipal;
|
||||
import org.keycloak.adapters.AdapterTokenStore;
|
||||
import org.keycloak.adapters.HttpFacade;
|
||||
import org.keycloak.adapters.KeycloakDeployment;
|
||||
import org.keycloak.adapters.undertow.KeycloakUndertowAccount;
|
||||
import org.keycloak.adapters.undertow.ServletRequestAuthenticator;
|
||||
import org.keycloak.adapters.undertow.UndertowUserSessionManagement;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import java.security.Principal;
|
||||
import java.security.acl.Group;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class WildflyRequestAuthenticator extends ServletRequestAuthenticator {
|
||||
protected static Logger log = Logger.getLogger(WildflyRequestAuthenticator.class);
|
||||
|
||||
public WildflyRequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment, int sslRedirectPort,
|
||||
SecurityContext securityContext, HttpServerExchange exchange,
|
||||
AdapterTokenStore tokenStore) {
|
||||
super(facade, deployment, sslRedirectPort, securityContext, exchange, tokenStore);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void propagateKeycloakContext(KeycloakUndertowAccount account) {
|
||||
super.propagateKeycloakContext(account);
|
||||
SecurityInfoHelper.propagateSessionInfo(account);
|
||||
log.debug("propagate security context to wildfly");
|
||||
Subject subject = new Subject();
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
principals.add(account.getPrincipal());
|
||||
Group[] roleSets = getRoleSets(account.getRoles());
|
||||
for (int g = 0; g < roleSets.length; g++) {
|
||||
Group group = roleSets[g];
|
||||
String name = group.getName();
|
||||
Group subjectGroup = createGroup(name, principals);
|
||||
if (subjectGroup instanceof NestableGroup) {
|
||||
/* A NestableGroup only allows Groups to be added to it so we
|
||||
need to add a SimpleGroup to subjectRoles to contain the roles
|
||||
*/
|
||||
SimpleGroup tmp = new SimpleGroup("Roles");
|
||||
subjectGroup.addMember(tmp);
|
||||
subjectGroup = tmp;
|
||||
}
|
||||
// Copy the group members to the Subject group
|
||||
Enumeration<? extends Principal> members = group.members();
|
||||
while (members.hasMoreElements()) {
|
||||
Principal role = (Principal) members.nextElement();
|
||||
subjectGroup.addMember(role);
|
||||
}
|
||||
}
|
||||
// add the CallerPrincipal group if none has been added in getRoleSets
|
||||
Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP);
|
||||
callerGroup.addMember(account.getPrincipal());
|
||||
principals.add(callerGroup);
|
||||
org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext();
|
||||
Principal userPrincipal = getPrincipal(subject);
|
||||
sc.getUtil().createSubjectInfo(userPrincipal, account, subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is
|
||||
* considered or the single subject inside the CallerPrincipal group.
|
||||
*
|
||||
* @param subject
|
||||
* @return the authenticated subject
|
||||
*/
|
||||
protected Principal getPrincipal(Subject subject) {
|
||||
Principal principal = null;
|
||||
Principal callerPrincipal = null;
|
||||
if (subject != null) {
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
if (principals != null && !principals.isEmpty()) {
|
||||
for (Principal p : principals) {
|
||||
if (!(p instanceof Group) && principal == null) {
|
||||
principal = p;
|
||||
}
|
||||
if (p instanceof Group) {
|
||||
Group g = Group.class.cast(p);
|
||||
if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) {
|
||||
Enumeration<? extends Principal> e = g.members();
|
||||
if (e.hasMoreElements())
|
||||
callerPrincipal = e.nextElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return callerPrincipal == null ? principal : callerPrincipal;
|
||||
}
|
||||
|
||||
protected Group createGroup(String name, Set<Principal> principals) {
|
||||
Group roles = null;
|
||||
Iterator<Principal> iter = principals.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object next = iter.next();
|
||||
if ((next instanceof Group) == false)
|
||||
continue;
|
||||
Group grp = (Group) next;
|
||||
if (grp.getName().equals(name)) {
|
||||
roles = grp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If we did not find a group create one
|
||||
if (roles == null) {
|
||||
roles = new SimpleGroup(name);
|
||||
principals.add(roles);
|
||||
}
|
||||
return roles;
|
||||
}
|
||||
|
||||
protected Group[] getRoleSets(Collection<String> roleSet) {
|
||||
SimpleGroup roles = new SimpleGroup("Roles");
|
||||
Group[] roleSets = {roles};
|
||||
for (String role : roleSet) {
|
||||
roles.addMember(new SimplePrincipal(role));
|
||||
}
|
||||
return roleSets;
|
||||
}
|
||||
|
||||
}
|
||||
File renamed without changes.
+1
-1
@@ -21,7 +21,7 @@
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>1.3.0.Beta1-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>keycloak-wildfly-extensions</artifactId>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+7
-31
@@ -21,24 +21,16 @@
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<version>1.3.0.Beta1-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>keycloak-subsystem</artifactId>
|
||||
<name>Keycloak Subsystem</name>
|
||||
<artifactId>keycloak-wildfly-server-subsystem</artifactId>
|
||||
<name>Keycloak Server Subsystem</name>
|
||||
<description/>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
@@ -70,19 +62,9 @@
|
||||
<artifactId>wildfly-server</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wildfly.core</groupId>
|
||||
<artifactId>wildfly-version</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wildfly</groupId>
|
||||
<artifactId>wildfly-ee</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wildfly</groupId>
|
||||
<artifactId>wildfly-undertow</artifactId>
|
||||
<artifactId>wildfly-web-common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -106,8 +88,7 @@
|
||||
|
||||
<dependency>
|
||||
<groupId>org.wildfly.core</groupId>
|
||||
<artifactId>wildfly-subsystem-test</artifactId>
|
||||
<type>pom</type>
|
||||
<artifactId>wildfly-subsystem-test-framework</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -116,15 +97,10 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jboss.as</groupId>
|
||||
<artifactId>jboss-as-web</artifactId>
|
||||
<version>7.1.1.Final</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-as7-adapter</artifactId>
|
||||
<artifactId>keycloak-wildfly-adapter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.server.extension;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADDRESS;
|
||||
|
||||
/**
|
||||
* This service keeps track of the entire Keycloak management model so as to provide
|
||||
* adapter configuration to each deployment at deploy time.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
|
||||
*/
|
||||
public final class KeycloakAdapterConfigService {
|
||||
|
||||
private static final KeycloakAdapterConfigService INSTANCE = new KeycloakAdapterConfigService();
|
||||
|
||||
public static KeycloakAdapterConfigService getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
// key=auth-server deployment name; value=web-context
|
||||
private final Map<String, String> webContexts = new HashMap<String, String>();
|
||||
|
||||
|
||||
|
||||
private KeycloakAdapterConfigService() {
|
||||
}
|
||||
|
||||
public void addServerDeployment(String deploymentName, String webContext) {
|
||||
this.webContexts.put(deploymentName, webContext);
|
||||
}
|
||||
|
||||
public String getWebContext(String deploymentName) {
|
||||
return webContexts.get(deploymentName);
|
||||
}
|
||||
|
||||
public void removeServerDeployment(String deploymentName) {
|
||||
this.webContexts.remove(deploymentName);
|
||||
}
|
||||
|
||||
public boolean isWebContextUsed(String webContext) {
|
||||
return webContexts.containsValue(webContext);
|
||||
}
|
||||
|
||||
public boolean isKeycloakServerDeployment(String deploymentName) {
|
||||
return this.webContexts.containsKey(deploymentName);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.server.extension;
|
||||
|
||||
import org.jboss.as.server.deployment.Attachments;
|
||||
import org.jboss.as.server.deployment.DeploymentPhaseContext;
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension;
|
||||
package org.keycloak.subsystem.server.extension;
|
||||
|
||||
import org.jboss.as.server.deployment.module.ModuleDependency;
|
||||
import org.jboss.as.server.deployment.module.ModuleSpecification;
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.server.extension;
|
||||
|
||||
import org.jboss.as.controller.Extension;
|
||||
import org.jboss.as.controller.ExtensionContext;
|
||||
import org.jboss.as.controller.ModelVersion;
|
||||
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.keycloak.subsystem.server.extension.authserver.AuthServerDefinition;
|
||||
import org.keycloak.subsystem.server.logging.KeycloakLogger;
|
||||
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
|
||||
|
||||
|
||||
/**
|
||||
* Main Extension class for the subsystem.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
|
||||
*/
|
||||
public class KeycloakExtension implements Extension {
|
||||
|
||||
public static final String SUBSYSTEM_NAME = "keycloak-server";
|
||||
public static final String NAMESPACE = "urn:jboss:domain:keycloak-server:1.1";
|
||||
private static final KeycloakSubsystemParser PARSER = new KeycloakSubsystemParser();
|
||||
static final PathElement PATH_SUBSYSTEM = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
|
||||
private static final String RESOURCE_NAME = KeycloakExtension.class.getPackage().getName() + ".LocalDescriptions";
|
||||
private static final ModelVersion MGMT_API_VERSION = ModelVersion.create(1,1,0);
|
||||
static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
|
||||
private static final ResourceDefinition KEYCLOAK_SUBSYSTEM_RESOURCE = new KeycloakSubsystemDefinition();
|
||||
static final AuthServerDefinition AUTH_SERVER_DEFINITION = new AuthServerDefinition();
|
||||
|
||||
public static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String... keyPrefix) {
|
||||
StringBuilder prefix = new StringBuilder(SUBSYSTEM_NAME);
|
||||
for (String kp : keyPrefix) {
|
||||
prefix.append('.').append(kp);
|
||||
}
|
||||
return new StandardResourceDescriptionResolver(prefix.toString(), RESOURCE_NAME, KeycloakExtension.class.getClassLoader(), true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void initializeParsers(final ExtensionParsingContext context) {
|
||||
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, KeycloakExtension.NAMESPACE, PARSER);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void initialize(final ExtensionContext context) {
|
||||
KeycloakLogger.ROOT_LOGGER.debug("Activating Keycloak Extension");
|
||||
final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, MGMT_API_VERSION);
|
||||
|
||||
ManagementResourceRegistration registration = subsystem.registerSubsystemModel(KEYCLOAK_SUBSYSTEM_RESOURCE);
|
||||
registration.registerSubModel(AUTH_SERVER_DEFINITION);
|
||||
subsystem.registerXMLElementWriter(PARSER);
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.server.extension;
|
||||
|
||||
import org.jboss.as.controller.AbstractBoottimeAddStepHandler;
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
import org.jboss.as.server.AbstractDeploymentChainStep;
|
||||
import org.jboss.as.server.DeploymentProcessorTarget;
|
||||
import org.jboss.as.server.deployment.Phase;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
|
||||
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
|
||||
import org.keycloak.subsystem.server.extension.authserver.KeycloakServerDeploymentProcessor;
|
||||
|
||||
/**
|
||||
* The Keycloak subsystem add update handler.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
|
||||
*/
|
||||
class KeycloakSubsystemAdd extends AbstractBoottimeAddStepHandler {
|
||||
|
||||
static final KeycloakSubsystemAdd INSTANCE = new KeycloakSubsystemAdd();
|
||||
|
||||
@Override
|
||||
protected void performBoottime(final OperationContext context, ModelNode operation, final ModelNode model) {
|
||||
context.addStep(new AbstractDeploymentChainStep() {
|
||||
@Override
|
||||
protected void execute(DeploymentProcessorTarget processorTarget) {
|
||||
processorTarget.addDeploymentProcessor(KeycloakExtension.SUBSYSTEM_NAME, Phase.DEPENDENCIES, 0, chooseDependencyProcessor());
|
||||
processorTarget.addDeploymentProcessor(KeycloakExtension.SUBSYSTEM_NAME,
|
||||
Phase.POST_MODULE, // PHASE
|
||||
Phase.POST_MODULE_VALIDATOR_FACTORY - 1, // PRIORITY
|
||||
new KeycloakServerDeploymentProcessor());
|
||||
}
|
||||
}, OperationContext.Stage.RUNTIME);
|
||||
}
|
||||
|
||||
private DeploymentUnitProcessor chooseDependencyProcessor() {
|
||||
return new KeycloakDependencyProcessorWildFly();
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.server.extension;
|
||||
|
||||
import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
|
||||
import org.jboss.as.controller.SimpleResourceDefinition;
|
||||
import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
|
||||
import org.jboss.as.controller.registry.ManagementResourceRegistration;
|
||||
|
||||
/**
|
||||
* Definition of subsystem=keycloak.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
|
||||
*/
|
||||
public class KeycloakSubsystemDefinition extends SimpleResourceDefinition {
|
||||
protected KeycloakSubsystemDefinition() {
|
||||
super(KeycloakExtension.SUBSYSTEM_PATH,
|
||||
KeycloakExtension.getResourceDescriptionResolver("subsystem"),
|
||||
KeycloakSubsystemAdd.INSTANCE,
|
||||
ReloadRequiredRemoveStepHandler.INSTANCE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
|
||||
super.registerOperations(resourceRegistration);
|
||||
resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
|
||||
}
|
||||
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.server.extension;
|
||||
|
||||
import org.keycloak.subsystem.server.extension.authserver.AuthServerDefinition;
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
import org.jboss.as.controller.PathAddress;
|
||||
import org.jboss.as.controller.PathElement;
|
||||
import org.jboss.as.controller.SimpleAttributeDefinition;
|
||||
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
|
||||
import org.jboss.as.controller.operations.common.Util;
|
||||
import org.jboss.as.controller.parsing.ParseUtils;
|
||||
import org.jboss.as.controller.persistence.SubsystemMarshallingContext;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.jboss.dmr.Property;
|
||||
import org.jboss.staxmapper.XMLElementReader;
|
||||
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.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The subsystem parser, which uses stax to read and write to and from xml
|
||||
*/
|
||||
class KeycloakSubsystemParser implements XMLStreamConstants, XMLElementReader<List<ModelNode>>, XMLElementWriter<SubsystemMarshallingContext> {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void readElement(final XMLExtendedStreamReader reader, final List<ModelNode> list) throws XMLStreamException {
|
||||
// Require no attributes
|
||||
ParseUtils.requireNoAttributes(reader);
|
||||
ModelNode addKeycloakSub = Util.createAddOperation(PathAddress.pathAddress(KeycloakExtension.PATH_SUBSYSTEM));
|
||||
list.add(addKeycloakSub);
|
||||
|
||||
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
|
||||
if (reader.getLocalName().equals(AuthServerDefinition.TAG_NAME)) {
|
||||
readAuthServer(reader, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// used for debugging
|
||||
private int nextTag(XMLExtendedStreamReader reader) throws XMLStreamException {
|
||||
return reader.nextTag();
|
||||
}
|
||||
|
||||
private void readAuthServer(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException {
|
||||
String authServerName = readNameAttribute(reader);
|
||||
ModelNode addAuthServer = new ModelNode();
|
||||
addAuthServer.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
|
||||
PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
|
||||
PathElement.pathElement(AuthServerDefinition.TAG_NAME, authServerName));
|
||||
addAuthServer.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
|
||||
|
||||
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
|
||||
String tagName = reader.getLocalName();
|
||||
SimpleAttributeDefinition def = AuthServerDefinition.lookup(tagName);
|
||||
if (def == null) throw new XMLStreamException("Unknown auth-server tag " + tagName);
|
||||
def.parseAndSetParameter(reader.getElementText(), addAuthServer, reader);
|
||||
}
|
||||
|
||||
list.add(addAuthServer);
|
||||
}
|
||||
|
||||
// expects that the current tag will have one single attribute called "name"
|
||||
private String readNameAttribute(XMLExtendedStreamReader reader) throws XMLStreamException {
|
||||
String name = null;
|
||||
for (int i = 0; i < reader.getAttributeCount(); i++) {
|
||||
String attr = reader.getAttributeLocalName(i);
|
||||
if (attr.equals("name")) {
|
||||
name = reader.getAttributeValue(i);
|
||||
continue;
|
||||
}
|
||||
throw ParseUtils.unexpectedAttribute(reader, i);
|
||||
}
|
||||
if (name == null) {
|
||||
throw ParseUtils.missingRequired(reader, Collections.singleton("name"));
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context) throws XMLStreamException {
|
||||
context.startSubsystemElement(KeycloakExtension.NAMESPACE, false);
|
||||
writeAuthServers(writer, context);
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
private void writeAuthServers(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
|
||||
if (!context.getModelNode().get(AuthServerDefinition.TAG_NAME).isDefined()) {
|
||||
return;
|
||||
}
|
||||
for (Property authServer : context.getModelNode().get(AuthServerDefinition.TAG_NAME).asPropertyList()) {
|
||||
writer.writeStartElement(AuthServerDefinition.TAG_NAME);
|
||||
writer.writeAttribute("name", authServer.getName());
|
||||
ModelNode authServerElements = authServer.getValue();
|
||||
for (AttributeDefinition element : AuthServerDefinition.ALL_ATTRIBUTES) {
|
||||
element.marshallAsElement(authServerElements, writer);
|
||||
}
|
||||
|
||||
writer.writeEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
+31
-47
@@ -14,61 +14,63 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.as.controller.AbstractAddStepHandler;
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
import org.jboss.as.controller.OperationFailedException;
|
||||
import org.jboss.as.controller.OperationStepHandler;
|
||||
import org.jboss.as.controller.PathAddress;
|
||||
import org.jboss.as.controller.ProcessType;
|
||||
import org.jboss.as.controller.SimpleAttributeDefinition;
|
||||
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
|
||||
import org.jboss.as.controller.operations.common.Util;
|
||||
import org.jboss.as.controller.registry.Resource;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.jboss.dmr.ModelType;
|
||||
import static org.keycloak.subsystem.extension.authserver.AuthServerUtil.getHandler;
|
||||
|
||||
/**
|
||||
* Base class for operations that create overlays for an auth server.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
|
||||
*/
|
||||
public abstract class AbstractAddOverlayHandler implements OperationStepHandler {
|
||||
public abstract class AbstractAddOverlayHandler extends AbstractAddStepHandler{
|
||||
|
||||
protected static final String UPLOADED_FILE_OP_NAME = "uploaded-file-name";
|
||||
|
||||
protected static final SimpleAttributeDefinition BYTES_TO_UPLOAD
|
||||
= new SimpleAttributeDefinitionBuilder("bytes-to-upload", ModelType.BYTES, false)
|
||||
protected static final SimpleAttributeDefinition UPLOADED_FILE_NAME =new SimpleAttributeDefinitionBuilder(UPLOADED_FILE_OP_NAME, ModelType.STRING, false)
|
||||
.setAllowExpression(false)
|
||||
.setAllowNull(false)
|
||||
.build();
|
||||
|
||||
protected static final SimpleAttributeDefinition BYTES_TO_UPLOAD= new SimpleAttributeDefinitionBuilder("bytes-to-upload", ModelType.BYTES, false)
|
||||
.setAllowExpression(false)
|
||||
.build();
|
||||
|
||||
static final SimpleAttributeDefinition REDEPLOY_SERVER =
|
||||
new SimpleAttributeDefinitionBuilder("redeploy", ModelType.BOOLEAN, true)
|
||||
.setXmlName("redeploy")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
|
||||
protected static final SimpleAttributeDefinition OVERWRITE =
|
||||
new SimpleAttributeDefinitionBuilder("overwrite", ModelType.BOOLEAN, true)
|
||||
.setXmlName("overwrite")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public void execute(final OperationContext context, final ModelNode operation) throws OperationFailedException {
|
||||
//System.out.println("*** execute operation ***");
|
||||
//System.out.println(scrub(operation));
|
||||
public AbstractAddOverlayHandler() {
|
||||
super(AddProviderHandler.DEFINITION.getParameters());
|
||||
}
|
||||
|
||||
String uploadFileName = operation.get(UPLOADED_FILE_OP_NAME).asString();
|
||||
boolean isRedeploy = isRedeploy(context, operation);
|
||||
boolean isOverwrite = getBooleanFromOperation(operation, OVERWRITE);
|
||||
@Override
|
||||
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
|
||||
final String uploadFileName = UPLOADED_FILE_NAME.resolveModelAttribute(context, model).asString();
|
||||
final boolean isRedeploy = isRedeploy(context, operation);
|
||||
final boolean isOverwrite = OVERWRITE.resolveModelAttribute(context, model).asBoolean();
|
||||
|
||||
String overlayPath = getOverlayPath(uploadFileName);
|
||||
String overlayName = AuthServerUtil.getOverlayName(operation);
|
||||
@@ -95,21 +97,21 @@ public abstract class AbstractAddOverlayHandler implements OperationStepHandler
|
||||
}
|
||||
}
|
||||
|
||||
addContent(context, overlayAddress, operation.get(BYTES_TO_UPLOAD.getName()).asBytes(), overlayPath);
|
||||
addContent(context, overlayAddress, BYTES_TO_UPLOAD.resolveModelAttribute(context, model).asBytes(), overlayPath);
|
||||
|
||||
if (isRedeploy) AuthServerUtil.addStepToRedeployAuthServer(context, deploymentName);
|
||||
if (!isRedeploy) context.restartRequired();
|
||||
if (isRedeploy) { AuthServerUtil.addStepToRedeployAuthServer(context, deploymentName); }
|
||||
if (!isRedeploy) { context.restartRequired(); }
|
||||
context.completeStep(OperationContext.ResultHandler.NOOP_RESULT_HANDLER);
|
||||
}
|
||||
|
||||
static void removeContent(OperationContext context, PathAddress overlayAddress, String overlayPath) {
|
||||
PathAddress contentAddress = overlayAddress.append("content", overlayPath);
|
||||
ModelNode operation = Util.createRemoveOperation(contentAddress);
|
||||
context.addStep(operation, getHandler(context, contentAddress, REMOVE), OperationContext.Stage.MODEL);
|
||||
context.addStep(operation, AuthServerUtil.getHandler(context, contentAddress, REMOVE), OperationContext.Stage.MODEL);
|
||||
}
|
||||
|
||||
static boolean isRedeploy(OperationContext context, ModelNode operation) {
|
||||
return isAuthServerEnabled(context) && getBooleanFromOperation(operation, REDEPLOY_SERVER);
|
||||
static boolean isRedeploy(OperationContext context, ModelNode model) throws OperationFailedException {
|
||||
return isAuthServerEnabled(context) && REDEPLOY_SERVER.resolveModelAttribute(context, model).asBoolean();
|
||||
}
|
||||
|
||||
private boolean isHostController(OperationContext context) {
|
||||
@@ -141,7 +143,7 @@ public abstract class AbstractAddOverlayHandler implements OperationStepHandler
|
||||
|
||||
// only call this if context.getProcessType() == ProcessType.HOST_CONTROLLER
|
||||
private void addOverlayToServerGroups(OperationContext context, PathAddress overlayAddress, ModelNode operation, String overlayName) {
|
||||
String myProfile = findMyProfile(operation);
|
||||
String myProfile = context.getCurrentAddressValue();
|
||||
for (String serverGroup : getServerGroupNames(context)) {
|
||||
PathAddress address = PathAddress.pathAddress("server-group", serverGroup);
|
||||
ModelNode serverGroupModel = context.readResourceFromRoot(address).getModel();
|
||||
@@ -156,12 +158,6 @@ public abstract class AbstractAddOverlayHandler implements OperationStepHandler
|
||||
}
|
||||
}
|
||||
|
||||
// only call this if context.getProcessType() == ProcessType.HOST_CONTROLLER
|
||||
private String findMyProfile(ModelNode operation) {
|
||||
PathAddress address = PathAddress.pathAddress(operation.get("address"));
|
||||
return address.getElement(0).getValue();
|
||||
}
|
||||
|
||||
private Set<String> getServerGroupNames(OperationContext context) {
|
||||
return context.readResourceFromRoot(PathAddress.EMPTY_ADDRESS).getChildrenNames("server-group");
|
||||
}
|
||||
@@ -180,24 +176,12 @@ public abstract class AbstractAddOverlayHandler implements OperationStepHandler
|
||||
private void doAddStep(OperationContext context, PathAddress address, ModelNode operation) {
|
||||
//System.out.println("**** Adding Add Step ****");
|
||||
//System.out.println(scrub(operation).toString());
|
||||
context.addStep(operation, getHandler(context, address, ADD), OperationContext.Stage.MODEL);
|
||||
context.addStep(operation, AuthServerUtil.getHandler(context, address, ADD), OperationContext.Stage.MODEL);
|
||||
}
|
||||
|
||||
private static boolean isAuthServerEnabled(OperationContext context) {
|
||||
boolean defaultValue = AuthServerDefinition.ENABLED.getDefaultValue().asBoolean();
|
||||
private static boolean isAuthServerEnabled(OperationContext context) throws OperationFailedException {
|
||||
ModelNode authServerModel = context.readResource(PathAddress.EMPTY_ADDRESS).getModel().clone();
|
||||
String attrName = AuthServerDefinition.ENABLED.getName();
|
||||
if (!authServerModel.get(attrName).isDefined()) return defaultValue;
|
||||
return authServerModel.get(attrName).asBoolean();
|
||||
}
|
||||
|
||||
private static boolean getBooleanFromOperation(ModelNode operation, SimpleAttributeDefinition definition) {
|
||||
boolean defaultValue = definition.getDefaultValue().asBoolean();
|
||||
if (!operation.get(definition.getName()).isDefined()) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
return operation.get(definition.getName()).asBoolean();
|
||||
}
|
||||
return AuthServerDefinition.ENABLED.resolveModelAttribute(context, authServerModel).asBoolean();
|
||||
}
|
||||
|
||||
// used for debugging
|
||||
@@ -215,7 +199,7 @@ public abstract class AbstractAddOverlayHandler implements OperationStepHandler
|
||||
/**
|
||||
* Get the WAR path where the overlay will live.
|
||||
*
|
||||
* @param file The name of the file being uploaded.
|
||||
* @param fileName The name of the file being uploaded.
|
||||
* @return The overlay path as a String.
|
||||
*/
|
||||
abstract String getOverlayPath(String fileName);
|
||||
+3
-14
@@ -15,14 +15,10 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import org.jboss.as.controller.OperationDefinition;
|
||||
import org.jboss.as.controller.SimpleAttributeDefinition;
|
||||
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
|
||||
import org.jboss.as.controller.SimpleOperationDefinitionBuilder;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.jboss.dmr.ModelType;
|
||||
|
||||
/**
|
||||
* Operation to add a provider jar to WEB-INF/lib.
|
||||
@@ -33,15 +29,6 @@ public class AddProviderHandler extends AbstractAddOverlayHandler {
|
||||
|
||||
public static final String OP = "add-provider";
|
||||
|
||||
public static final AddProviderHandler INSTANCE = new AddProviderHandler();
|
||||
|
||||
protected static final SimpleAttributeDefinition UPLOADED_FILE_NAME =
|
||||
new SimpleAttributeDefinitionBuilder(UPLOADED_FILE_OP_NAME, ModelType.STRING, false)
|
||||
.setAllowExpression(false)
|
||||
.setAllowNull(false)
|
||||
.setDefaultValue(new ModelNode().set("myprovider.jar"))
|
||||
.build();
|
||||
|
||||
public static OperationDefinition DEFINITION = new SimpleOperationDefinitionBuilder(OP, AuthServerDefinition.rscDescriptionResolver)
|
||||
.addParameter(BYTES_TO_UPLOAD)
|
||||
.addParameter(UPLOADED_FILE_NAME)
|
||||
@@ -49,6 +36,8 @@ public class AddProviderHandler extends AbstractAddOverlayHandler {
|
||||
.addParameter(OVERWRITE)
|
||||
.build();
|
||||
|
||||
public static final AddProviderHandler INSTANCE = new AddProviderHandler();
|
||||
|
||||
private AddProviderHandler() {}
|
||||
|
||||
@Override
|
||||
+2
-7
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import org.jboss.as.controller.AbstractAddStepHandler;
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
@@ -26,7 +26,7 @@ import org.jboss.dmr.ModelNode;
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
|
||||
import org.jboss.as.controller.registry.Resource;
|
||||
import org.keycloak.subsystem.extension.KeycloakAdapterConfigService;
|
||||
import org.keycloak.subsystem.server.extension.KeycloakAdapterConfigService;
|
||||
|
||||
/**
|
||||
* Add an auth server.
|
||||
@@ -71,9 +71,4 @@ public final class AuthServerAddHandler extends AbstractAddStepHandler {
|
||||
authServerUtil.addStepToUploadAuthServer(context, enabled);
|
||||
KeycloakAdapterConfigService.getInstance().addServerDeployment(authServerUtil.getDeploymentName(), webContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean requiresRuntimeVerification() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+3
-5
@@ -14,7 +14,7 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
import org.jboss.as.controller.PathElement;
|
||||
@@ -34,8 +34,8 @@ import org.jboss.as.controller.OperationFailedException;
|
||||
import org.jboss.as.controller.descriptions.ResourceDescriptionResolver;
|
||||
import org.jboss.as.controller.operations.validation.ParameterValidator;
|
||||
import org.jboss.as.controller.registry.OperationEntry;
|
||||
import org.keycloak.subsystem.extension.KeycloakAdapterConfigService;
|
||||
import org.keycloak.subsystem.extension.KeycloakExtension;
|
||||
import org.keycloak.subsystem.server.extension.KeycloakAdapterConfigService;
|
||||
import org.keycloak.subsystem.server.extension.KeycloakExtension;
|
||||
|
||||
/**
|
||||
* Defines attributes and operations for an Auth Server
|
||||
@@ -48,7 +48,6 @@ public class AuthServerDefinition extends SimpleResourceDefinition {
|
||||
|
||||
protected static final SimpleAttributeDefinition ENABLED =
|
||||
new SimpleAttributeDefinitionBuilder("enabled", ModelType.BOOLEAN, true)
|
||||
.setXmlName("enabled")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode(false))
|
||||
.setRestartAllServices()
|
||||
@@ -56,7 +55,6 @@ public class AuthServerDefinition extends SimpleResourceDefinition {
|
||||
|
||||
protected static final SimpleAttributeDefinition WEB_CONTEXT =
|
||||
new SimpleAttributeDefinitionBuilder("web-context", ModelType.STRING, true)
|
||||
.setXmlName("web-context")
|
||||
.setAllowExpression(true)
|
||||
.setDefaultValue(new ModelNode("auth"))
|
||||
.setValidator(new WebContextValidator())
|
||||
+2
-2
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import org.jboss.as.controller.AbstractRemoveStepHandler;
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
@@ -25,7 +25,7 @@ import org.jboss.as.controller.PathAddress;
|
||||
import org.jboss.as.controller.PathElement;
|
||||
import org.jboss.as.controller.operations.common.Util;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.keycloak.subsystem.extension.KeycloakAdapterConfigService;
|
||||
import org.keycloak.subsystem.server.extension.KeycloakAdapterConfigService;
|
||||
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DEPLOYMENT;
|
||||
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
|
||||
+6
-6
@@ -14,7 +14,7 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
@@ -46,7 +46,7 @@ import org.jboss.dmr.ModelNode;
|
||||
import org.jboss.modules.Module;
|
||||
import org.jboss.modules.ModuleIdentifier;
|
||||
import org.jboss.modules.ModuleLoadException;
|
||||
import org.keycloak.subsystem.extension.KeycloakExtension;
|
||||
import org.keycloak.subsystem.server.extension.KeycloakExtension;
|
||||
|
||||
/**
|
||||
* Utility methods that help assemble and start an auth server.
|
||||
@@ -55,7 +55,7 @@ import org.keycloak.subsystem.extension.KeycloakExtension;
|
||||
*/
|
||||
public class AuthServerUtil {
|
||||
|
||||
private static final ModuleIdentifier KEYCLOAK_SUBSYSTEM = ModuleIdentifier.create("org.keycloak.keycloak-subsystem");
|
||||
private static final ModuleIdentifier KEYCLOAK_SUBSYSTEM = ModuleIdentifier.create("org.keycloak.keycloak-server-subsystem");
|
||||
|
||||
private final String deploymentName;
|
||||
private final Module subsysModule;
|
||||
@@ -85,8 +85,8 @@ public class AuthServerUtil {
|
||||
|
||||
private URI findAuthServerUri() throws IllegalStateException {
|
||||
try {
|
||||
URL subsysJar = this.subsysModule.getExportedResource("keycloak-subsystem-" + this.keycloakVersion + ".jar");
|
||||
File subsysDir = new File(subsysJar.toURI()).getParentFile();
|
||||
URL subsysResource = this.subsysModule.getExportedResource("module.xml");
|
||||
File subsysDir = new File(subsysResource.toURI()).getParentFile();
|
||||
File authServerDir = new File(subsysDir, "auth-server");
|
||||
if (this.isAuthServerExploded) {
|
||||
return authServerDir.toURI();
|
||||
@@ -110,7 +110,7 @@ public class AuthServerUtil {
|
||||
op.get("owner").set(new ModelNode().add("subsystem", KeycloakExtension.SUBSYSTEM_NAME));
|
||||
|
||||
if (authServerUri == null) {
|
||||
throw new OperationFailedException("Keycloak Auth Server WAR not found in keycloak-subsystem module");
|
||||
throw new OperationFailedException("Keycloak Auth Server WAR not found in keycloak-server-subsystem module");
|
||||
}
|
||||
|
||||
op.get(CONTENT).add(makeContentItem());
|
||||
+3
-11
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import org.jboss.as.controller.AttributeDefinition;
|
||||
import org.jboss.as.controller.SimpleAttributeDefinition;
|
||||
@@ -26,7 +26,7 @@ import org.jboss.as.controller.OperationContext;
|
||||
import org.jboss.as.controller.OperationFailedException;
|
||||
import org.jboss.as.controller.registry.Resource;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.keycloak.subsystem.extension.KeycloakAdapterConfigService;
|
||||
import org.keycloak.subsystem.server.extension.KeycloakAdapterConfigService;
|
||||
|
||||
/**
|
||||
* Update an attribute on an Auth Server.
|
||||
@@ -50,7 +50,7 @@ public class AuthServerWriteAttributeHandler extends ModelOnlyWriteAttributeHand
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isEnabled = isEnabled(model); // is server currently enabled?
|
||||
boolean isEnabled = AuthServerDefinition.ENABLED.resolveModelAttribute(context, model.getModel()).asBoolean();
|
||||
String deploymentName = AuthServerUtil.getDeploymentName(operation);
|
||||
|
||||
if (attributeName.equals(AuthServerDefinition.WEB_CONTEXT.getName())) {
|
||||
@@ -73,14 +73,6 @@ public class AuthServerWriteAttributeHandler extends ModelOnlyWriteAttributeHand
|
||||
super.finishModelStage(context, operation, attributeName, newValue, oldValue, model);
|
||||
}
|
||||
|
||||
// Is auth server currently enabled?
|
||||
private boolean isEnabled(Resource model) {
|
||||
ModelNode authServer = model.getModel();
|
||||
ModelNode isEnabled = authServer.get(AuthServerDefinition.ENABLED.getName());
|
||||
if (!isEnabled.isDefined()) isEnabled = AuthServerDefinition.ENABLED.getDefaultValue();
|
||||
return isEnabled.asBoolean();
|
||||
}
|
||||
|
||||
private boolean attribNotChanging(String attributeName, ModelNode newValue, ModelNode oldValue) {
|
||||
SimpleAttributeDefinition attribDef = AuthServerDefinition.lookup(attributeName);
|
||||
if (!oldValue.isDefined()) oldValue = attribDef.getDefaultValue();
|
||||
+2
-2
@@ -14,14 +14,14 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import org.jboss.as.ee.component.EEModuleDescription;
|
||||
import org.jboss.as.server.deployment.DeploymentPhaseContext;
|
||||
import org.jboss.as.server.deployment.DeploymentUnit;
|
||||
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
|
||||
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
|
||||
import org.keycloak.subsystem.extension.KeycloakAdapterConfigService;
|
||||
import org.keycloak.subsystem.server.extension.KeycloakAdapterConfigService;
|
||||
|
||||
/**
|
||||
* DUP responsible for setting the web context of a Keycloak auth server.
|
||||
+1
-3
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
@@ -64,8 +64,6 @@ public class ListOverlaysHandler implements OperationStepHandler {
|
||||
result.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
context.stepCompleted();
|
||||
}
|
||||
|
||||
private Set<String> getOverlayNames(OperationContext context, String overlayName) {
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import org.jboss.as.controller.OperationDefinition;
|
||||
import org.jboss.as.controller.SimpleOperationDefinitionBuilder;
|
||||
+8
-6
@@ -15,7 +15,9 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.subsystem.extension.authserver;
|
||||
package org.keycloak.subsystem.server.extension.authserver;
|
||||
|
||||
import static org.keycloak.subsystem.server.extension.authserver.AbstractAddOverlayHandler.REDEPLOY_SERVER;
|
||||
|
||||
import org.jboss.as.controller.OperationContext;
|
||||
import org.jboss.as.controller.OperationDefinition;
|
||||
@@ -41,12 +43,11 @@ public class RemoveOverlayHandler implements OperationStepHandler {
|
||||
new SimpleAttributeDefinitionBuilder("overlay-file-path", ModelType.STRING, false)
|
||||
.setAllowExpression(true)
|
||||
.setAllowNull(false)
|
||||
.setDefaultValue(new ModelNode().set("/WEB-INF/lib/myprovider.jar"))
|
||||
.build();
|
||||
|
||||
static final OperationDefinition DEFINITION = new SimpleOperationDefinitionBuilder(REMOVE_OVERLAY_OPERATION, AuthServerDefinition.rscDescriptionResolver)
|
||||
.addParameter(OVERLAY_FILE_PATH)
|
||||
.addParameter(AbstractAddOverlayHandler.REDEPLOY_SERVER)
|
||||
.addParameter(REDEPLOY_SERVER)
|
||||
.build();
|
||||
|
||||
static final OperationStepHandler INSTANCE = new RemoveOverlayHandler();
|
||||
@@ -55,9 +56,12 @@ public class RemoveOverlayHandler implements OperationStepHandler {
|
||||
|
||||
@Override
|
||||
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
|
||||
final ModelNode model = new ModelNode();
|
||||
OVERLAY_FILE_PATH.validateAndSet(operation, model);
|
||||
REDEPLOY_SERVER.validateAndSet(operation, model);
|
||||
String overlayName = AuthServerUtil.getOverlayName(operation);
|
||||
boolean isOverlayExists = AuthServerUtil.isOverlayExists(context, overlayName, PathAddress.EMPTY_ADDRESS);
|
||||
String overlayPath = operation.get(OVERLAY_FILE_PATH.getName()).asString();
|
||||
String overlayPath = OVERLAY_FILE_PATH.resolveModelAttribute(context, model).asString();
|
||||
if (isOverlayExists) {
|
||||
PathAddress overlayAddress = AuthServerUtil.getOverlayAddress(overlayName);
|
||||
AbstractAddOverlayHandler.removeContent(context, overlayAddress, overlayPath);
|
||||
@@ -70,7 +74,5 @@ public class RemoveOverlayHandler implements OperationStepHandler {
|
||||
String deploymentName = AuthServerUtil.getDeploymentName(operation);
|
||||
if (isRedeploy) AuthServerUtil.addStepToRedeployAuthServer(context, deploymentName);
|
||||
if (!isRedeploy) context.restartRequired();
|
||||
|
||||
context.stepCompleted();
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.server.logging;
|
||||
|
||||
import org.jboss.logging.BasicLogger;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jboss.logging.annotations.LogMessage;
|
||||
import org.jboss.logging.annotations.Message;
|
||||
import org.jboss.logging.annotations.MessageLogger;
|
||||
|
||||
import static org.jboss.logging.Logger.Level.INFO;
|
||||
|
||||
/**
|
||||
* This interface to be fleshed out later when error messages are fully externalized.
|
||||
*
|
||||
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
|
||||
*/
|
||||
@MessageLogger(projectCode = "KEYCLOAK")
|
||||
public interface KeycloakLogger extends BasicLogger {
|
||||
|
||||
/**
|
||||
* A logger with a category of the package name.
|
||||
*/
|
||||
KeycloakLogger ROOT_LOGGER = Logger.getMessageLogger(KeycloakLogger.class, "org.jboss.keycloak");
|
||||
}
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.logging;
|
||||
package org.keycloak.subsystem.server.logging;
|
||||
|
||||
import org.jboss.logging.Messages;
|
||||
import org.jboss.logging.annotations.MessageBundle;
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.keycloak.subsystem.server.extension.KeycloakExtension
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
keycloak-server.subsystem=Keycloak subsystem
|
||||
keycloak-server.subsystem.add=Operation Adds Keycloak subsystem
|
||||
keycloak-server.subsystem.remove=Operation removes Keycloak subsystem
|
||||
keycloak-server.subsystem.auth-server=Keycloak Auth Server
|
||||
keycloak-server.subsystem.realm=A Keycloak realm.
|
||||
keycloak-server.subsystem.secure-deployment=A deployment secured by Keycloak.
|
||||
|
||||
|
||||
keycloak-server.auth-server=A Keycloak Auth Server
|
||||
keycloak-server.auth-server.add=Add an Auth Server to the subsystem.
|
||||
keycloak-server.auth-server.remove=Remove an Auth Server from the subsystem.
|
||||
keycloak-server.auth-server.add-provider=Add a provider service jar to the Keycloak auth server.
|
||||
keycloak-server.auth-server.add-provider.uploaded-file-name=The file name of the provider service jar to be added or updated.
|
||||
keycloak-server.auth-server.add-provider.bytes-to-upload=The bytes of the provider service jar to be added or updated.
|
||||
keycloak-server.auth-server.add-provider.redeploy=Redeploy the auth server after adding the provider. Ignored if auth server is disabled.
|
||||
keycloak-server.auth-server.add-provider.overwrite=Overwrite even if the uploaded-file-name already exists as an overlay.
|
||||
keycloak-server.auth-server.list-overlays=List the overlays uploaded for this auth server.
|
||||
keycloak-server.auth-server.remove-overlay=Remove a provider jar, theme jar, or keycloak-server.json that has been uploaded to the auth server.
|
||||
keycloak-server.auth-server.remove-overlay.overlay-file-path=The uploaded path and file name of the overlay to be removed.
|
||||
keycloak-server.auth-server.remove-overlay.redeploy=Redeploy the auth server after removing the overlay.
|
||||
keycloak-server.auth-server.update-server-config=Upload a new keycloak-server.json configuration file for the Keycloak auth server.
|
||||
keycloak-server.auth-server.update-server-config.bytes-to-upload=The bytes of the keycloak-server.json file to be added or updated.
|
||||
keycloak-server.auth-server.update-server-config.redeploy=Redeploy the auth server after updating the server config.
|
||||
keycloak-server.auth-server.update-server-config.overwrite=Overwrite even if keycloak-server.json already exitss as an overlay.
|
||||
keycloak-server.auth-server.enabled=Enable or disable the Auth Server.
|
||||
keycloak-server.auth-server.web-context=Web context the auth-server will use. Also, the module name of the auth-server deployment.
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="urn:jboss:domain:keycloak-server:1.1"
|
||||
xmlns="urn:jboss:domain:keycloak-server:1.1"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified"
|
||||
version="1.0">
|
||||
|
||||
<!-- The subsystem root element -->
|
||||
<xs:element name="subsystem" type="subsystem-type"/>
|
||||
|
||||
<xs:complexType name="subsystem-type">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
<![CDATA[
|
||||
The Keycloak server subsystem, used to configure the Keycloak server
|
||||
]]>
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="auth-server" maxOccurs="1" minOccurs="0" type="auth-server-type"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="auth-server-type">
|
||||
<xs:all>
|
||||
<xs:element name="web-context" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="enabled" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
|
||||
</xs:all>
|
||||
<xs:attribute name="name" type="xs:string" use="required">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The name of the war archive containing the Keycloak server web application.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
|
||||
</xs:schema>
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
|
||||
<config>
|
||||
<extension-module>org.jboss.as.connector</extension-module>
|
||||
<subsystem xmlns="urn:jboss:domain:datasources:3.0">
|
||||
<datasources>
|
||||
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
|
||||
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
|
||||
<driver>h2</driver>
|
||||
<security>
|
||||
<user-name>sa</user-name>
|
||||
<password>sa</password>
|
||||
</security>
|
||||
</datasource>
|
||||
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
|
||||
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
|
||||
<driver>h2</driver>
|
||||
<security>
|
||||
<user-name>sa</user-name>
|
||||
<password>sa</password>
|
||||
</security>
|
||||
</datasource>
|
||||
<drivers>
|
||||
<driver name="h2" module="com.h2database.h2">
|
||||
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
|
||||
</driver>
|
||||
</drivers>
|
||||
</datasources>
|
||||
</subsystem>
|
||||
</config>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Template used by WildFly build when directed to include Keycloak subsystem in a configuration. -->
|
||||
<config>
|
||||
<extension-module>org.keycloak.keycloak-server-subsystem</extension-module>
|
||||
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
|
||||
<auth-server name="main-auth-server">
|
||||
<enabled>true</enabled>
|
||||
<web-context>auth</web-context>
|
||||
</auth-server>
|
||||
</subsystem>
|
||||
</config>
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
|
||||
* as indicated by the @author tags. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package org.keycloak.subsystem.server.extension;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jboss.as.subsystem.test.AbstractSubsystemBaseTest;
|
||||
import org.jboss.dmr.ModelNode;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests all management expects for subsystem, parsing, marshaling, model definition and other
|
||||
* Here is an example that allows you a fine grained controller over what is tested and how. So it can give you ideas what can be done and tested.
|
||||
* If you have no need for advanced testing of subsystem you look at {@link AbstractSubsystemBaseTest} that testes same stuff but most of the code
|
||||
* is hidden inside of test harness
|
||||
*
|
||||
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
|
||||
* @author Tomaz Cerar
|
||||
* @author Marko Strukelj
|
||||
*/
|
||||
public class SubsystemParsingTestCase extends AbstractSubsystemBaseTest {
|
||||
|
||||
public SubsystemParsingTestCase() {
|
||||
super(KeycloakExtension.SUBSYSTEM_NAME, new KeycloakExtension());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJson() throws Exception {
|
||||
ModelNode node = new ModelNode();
|
||||
node.get("enabled").set(true);
|
||||
node.get("web-context").set("auth");
|
||||
|
||||
System.out.println("json=" + node.toJSONString(false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSubsystemXml() throws IOException {
|
||||
return readResource("keycloak-server-1.1.xml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSubsystemXsdPath() throws Exception {
|
||||
return "schema/wildfly-keycloak-server_1_1.xsd";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getSubsystemTemplatePaths() throws IOException {
|
||||
return new String[]{
|
||||
"/subsystem-templates/keycloak-server.xml"
|
||||
};
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
|
||||
<auth-server name="main-auth-server">
|
||||
<enabled>true</enabled>
|
||||
<web-context>auth</web-context>
|
||||
</auth-server>
|
||||
</subsystem>
|
||||
Reference in new issue
Block a user