Remove EAP6 and AS7 adapters (#11605)

Closes #11604
This commit is contained in:
Stian Thorgersen 2022-04-28 11:20:44 +02:00 committed by GitHub
parent 2ecf250e37
commit b65d76edab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
179 changed files with 0 additions and 15865 deletions

View file

@ -1,99 +0,0 @@
<?xml version="1.0"?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-as7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-as7-adapter-spi</artifactId>
<name>Keycloak AS7 SPI</name>
<description/>
<repositories>
<!-- for org.jboss.web:jbossweb -->
<repository>
<id>jboss</id>
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.web</groupId>
<artifactId>jbossweb</artifactId>
<version>7.0.17.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-web</artifactId>
<version>7.1.2.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-tomcat-adapter-spi</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View file

@ -1,179 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.adapters.jbossweb;
import org.apache.catalina.Realm;
import org.apache.catalina.realm.GenericPrincipal;
import org.jboss.as.web.security.JBossGenericPrincipal;
import org.jboss.security.NestableGroup;
import org.jboss.security.SecurityConstants;
import org.jboss.security.SecurityContext;
import org.jboss.security.SecurityContextAssociation;
import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.keycloak.adapters.spi.KeycloakAccount;
import org.keycloak.adapters.tomcat.PrincipalFactory;
import javax.security.auth.Subject;
import java.lang.reflect.Constructor;
import java.security.Principal;
import java.security.acl.Group;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class JBossWebPrincipalFactory implements PrincipalFactory {
private static Constructor jbossWebPrincipalConstructor = findJBossGenericPrincipalConstructor();
@Override
public GenericPrincipal createPrincipal(Realm realm, final Principal identity, final Set<String> roleSet) {
KeycloakAccount account = new KeycloakAccount() {
@Override
public Principal getPrincipal() {
return identity;
}
@Override
public Set<String> getRoles() {
return roleSet;
}
};
Subject subject = new Subject();
Set<Principal> principals = subject.getPrincipals();
principals.add(identity);
Group[] roleSets = getRoleSets(roleSet);
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(identity);
principals.add(callerGroup);
SecurityContext sc = SecurityContextAssociation.getSecurityContext();
Principal userPrincipal = getPrincipal(subject);
sc.getUtil().createSubjectInfo(userPrincipal, account, subject);
List<String> rolesAsStringList = new ArrayList<>(roleSet);
try {
return (GenericPrincipal) jbossWebPrincipalConstructor.newInstance(realm, userPrincipal.getName(), null, rolesAsStringList, userPrincipal, null, account, null, subject);
} catch (Throwable t) {
throw new RuntimeException("Failed to create JBossGenericPrincipal", t);
}
}
/**
* 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))
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;
}
static Constructor findJBossGenericPrincipalConstructor() {
for (Constructor<?> c : JBossGenericPrincipal.class.getConstructors()) {
if (c.getParameterTypes().length == 9 &&
c.getParameterTypes()[0].equals(Realm.class) &&
c.getParameterTypes()[1].equals(String.class) &&
c.getParameterTypes()[3].equals(List.class) &&
c.getParameterTypes()[4].equals(Principal.class) &&
c.getParameterTypes()[6].equals(Object.class) &&
c.getParameterTypes()[8].equals(Subject.class)) {
return c;
}
}
return null;
}
}

View file

@ -1,46 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.adapters.jbossweb;
import org.apache.catalina.Realm;
import org.junit.Assert;
import org.junit.Test;
import javax.security.auth.Subject;
import java.lang.reflect.Constructor;
import java.security.Principal;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class JBossWebPrincipalFactoryTest {
@Test
public void test() {
Constructor constructor = JBossWebPrincipalFactory.findJBossGenericPrincipalConstructor();
Assert.assertNotNull(constructor);
Assert.assertEquals(Realm.class, constructor.getParameterTypes()[0]);
Assert.assertEquals(String.class, constructor.getParameterTypes()[1]);
Assert.assertEquals(List.class, constructor.getParameterTypes()[3]);
Assert.assertEquals(Principal.class, constructor.getParameterTypes()[4]);
Assert.assertEquals(Object.class, constructor.getParameterTypes()[6]);
Assert.assertEquals(Subject.class, constructor.getParameterTypes()[8]);
}
}

View file

@ -1,132 +0,0 @@
<?xml version="1.0"?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-as7-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-as7-adapter</artifactId>
<name>Keycloak AS7 Integration</name>
<description/>
<repositories>
<!-- for org.jboss.web:jbossweb -->
<repository>
<id>jboss</id>
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</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>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>${jboss.logging.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.web</groupId>
<artifactId>jbossweb</artifactId>
<version>7.0.17.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-web</artifactId>
<version>7.1.2.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-tomcat-core-adapter</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View file

@ -1,13 +0,0 @@
package org.keycloak.adapters.jbossweb;
import org.apache.catalina.Container;
import org.apache.catalina.Valve;
import org.keycloak.adapters.AdapterDeploymentContext;
import org.keycloak.adapters.tomcat.AbstractAuthenticatedActionsValve;
public class AuthenticatedActionsValve extends AbstractAuthenticatedActionsValve {
public AuthenticatedActionsValve(AdapterDeploymentContext deploymentContext, Valve next, Container container) {
super(deploymentContext, next, container);
}
}

View file

@ -1,76 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.adapters.jbossweb;
import org.apache.catalina.Container;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Valve;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.deploy.LoginConfig;
import org.keycloak.adapters.AdapterDeploymentContext;
import org.keycloak.adapters.tomcat.AbstractAuthenticatedActionsValve;
import org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve;
import org.keycloak.adapters.tomcat.PrincipalFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Keycloak authentication valve
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class KeycloakAuthenticatorValve extends AbstractKeycloakAuthenticatorValve {
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws java.io.IOException {
return authenticateInternal(request, response, config);
}
@Override
protected boolean forwardToErrorPageInternal(Request request, HttpServletResponse response, Object loginConfig) throws IOException {
if (loginConfig == null) return false;
LoginConfig config = (LoginConfig)loginConfig;
if (config.getErrorPage() == null) return false;
forwardToErrorPage(request, (Response)response, config);
return true;
}
@Override
public void start() throws LifecycleException {
StandardContext standardContext = (StandardContext) context;
standardContext.addLifecycleListener(this);
super.start();
}
public void logout(Request request) {
logoutInternal(request);
}
@Override
protected PrincipalFactory createPrincipalFactory() {
return new JBossWebPrincipalFactory();
}
@Override
protected AbstractAuthenticatedActionsValve createAuthenticatedActionsValve(AdapterDeploymentContext deploymentContext, Valve next, Container container) {
return new AuthenticatedActionsValve(deploymentContext, next, container);
}
}

View file

@ -1,112 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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-as7-integration-pom</artifactId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>keycloak-as7-subsystem</artifactId>
<name>Keycloak AS7 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>
<argLine>-Xmx512m</argLine>
<systemProperties>
<property>
<name>jboss.home</name>
<value>${jboss.home}</value>
</property>
</systemProperties>
<includes>
<include>**/*TestCase.java</include>
</includes>
<forkMode>once</forkMode>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-adapter</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-naming</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-server</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-ee</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-web</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<!-- Needed for jboss-logging-processor-->
<version>3.3.2.Final</version>
</dependency>
<!-- Do not ever delete this dependency. It's needed for eap6 adapter build in PNC.-->
<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>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.msc</groupId>
<artifactId>jboss-msc</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View file

@ -1,62 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
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.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* Add a credential to a deployment.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
*/
public class CredentialAddHandler extends AbstractAddStepHandler {
protected Collection<AttributeDefinition> attributes = new LinkedList<>();
public CredentialAddHandler(AttributeDefinition... attrs) {
for (AttributeDefinition attr : attrs) {
attributes.add(attr);
}
}
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
if (attributes != null) {
for (AttributeDefinition attr : attributes) {
attr.validateAndSet(operation, model);
}
}
}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
ckService.addCredential(operation, context.resolveExpressions(model));
}
}

View file

@ -1,63 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
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.operations.validation.StringLengthValidator;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.controller.registry.OperationEntry;
import org.jboss.dmr.ModelType;
/**
* Defines attributes and operations for a credential.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
public class CredentialDefinition extends SimpleResourceDefinition {
public static final String TAG_NAME = "credential";
protected static final AttributeDefinition VALUE =
new SimpleAttributeDefinitionBuilder("value", ModelType.STRING, false)
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, false, true))
.build();
public CredentialDefinition() {
super(PathElement.pathElement(TAG_NAME),
KeycloakExtension.getResourceDescriptionResolver(TAG_NAME),
new CredentialAddHandler(VALUE),
CredentialRemoveHandler.INSTANCE);
}
@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);
resourceRegistration.registerOperationHandler(ModelDescriptionConstants.DESCRIBE, GenericSubsystemDescribeHandler.INSTANCE, GenericSubsystemDescribeHandler.INSTANCE, false, OperationEntry.EntryType.PRIVATE);
}
@Override
public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
super.registerAttributes(resourceRegistration);
resourceRegistration.registerReadWriteAttribute(VALUE, null, new CredentialReadWriteAttributeHandler());
}
}

View file

@ -1,50 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.AbstractWriteAttributeHandler;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.dmr.ModelNode;
/**
* Update a credential value.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
*/
public class CredentialReadWriteAttributeHandler extends AbstractWriteAttributeHandler<KeycloakAdapterConfigService> {
@Override
protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
ModelNode resolvedValue, ModelNode currentValue, AbstractWriteAttributeHandler.HandbackHolder<KeycloakAdapterConfigService> hh) throws OperationFailedException {
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
ckService.updateCredential(operation, attributeName, resolvedValue);
hh.setHandback(ckService);
return false;
}
@Override
protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
ModelNode valueToRestore, ModelNode valueToRevert, KeycloakAdapterConfigService ckService) throws OperationFailedException {
ckService.updateCredential(operation, attributeName, valueToRestore);
}
}

View file

@ -1,42 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.AbstractRemoveStepHandler;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.dmr.ModelNode;
/**
* Remove a credential from a deployment.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
*/
public final class CredentialRemoveHandler extends AbstractRemoveStepHandler {
public static CredentialRemoveHandler INSTANCE = new CredentialRemoveHandler();
private CredentialRemoveHandler() {}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
ckService.removeCredential(operation);
}
}

View file

@ -1,129 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
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.as7.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.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
*/
public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitProcessor {
protected Logger log = Logger.getLogger(KeycloakAdapterConfigDeploymentProcessor.class);
// This param name is defined again in Keycloak Undertow Integration class
// org.keycloak.adapters.undertow.KeycloakServletExtension. We have this value in
// two places to avoid dependency between Keycloak Subsystem and Keyclaok Undertow Integration.
public static final String AUTH_DATA_PARAM_NAME = "org.keycloak.json.adapterConfig";
@Override
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
// if it's not a web-app there's nothing to secure
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
webMetaData = new JBossWebMetaData();
warMetaData.setMergedJBossWebMetaData(webMetaData);
}
KeycloakAdapterConfigService service = KeycloakAdapterConfigService.getInstance();
// otherwise
LoginConfigMetaData loginConfig = webMetaData.getLoginConfig();
boolean hasSubsystemConfig = service.isSecureDeployment(deploymentUnit);
boolean webRequiresKC = loginConfig != null && "KEYCLOAK".equalsIgnoreCase(loginConfig.getAuthMethod());
boolean isConfigured = service.isDeploymentConfigured(deploymentUnit);
if ((hasSubsystemConfig && isConfigured) || webRequiresKC) {
log.debug("Setting up KEYCLOAK auth method for WAR: " + deploymentUnit.getName());
// if secure-deployment configuration exists for web app, we force KEYCLOAK auth method on it
if (hasSubsystemConfig) {
addJSONData(service.getJSON(deploymentUnit), warMetaData);
if (loginConfig != null) {
loginConfig.setAuthMethod("KEYCLOAK");
loginConfig.setRealmName(service.getRealmName(deploymentUnit));
} else {
log.warn("Failed to set up KEYCLOAK auth method for WAR: " + deploymentUnit.getName() + " (loginConfig == null)");
}
}
addValve(webMetaData);
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentUnit.getName());
}
}
private void addValve(JBossWebMetaData webMetaData) {
List<ValveMetaData> valves = webMetaData.getValves();
if (valves == null) {
valves = new ArrayList<>(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 param = new ParamValueMetaData();
param.setParamName(AUTH_DATA_PARAM_NAME);
param.setParamValue(json);
contextParams.add(param);
webMetaData.setContextParams(contextParams);
}
@Override
public void undeploy(DeploymentUnit du) {
}
}

View file

@ -1,231 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.web.deployment.WarMetaData;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.logging.Logger;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
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 {
protected Logger log = Logger.getLogger(KeycloakAdapterConfigService.class);
private static final String CREDENTIALS_JSON_NAME = "credentials";
private static final KeycloakAdapterConfigService INSTANCE = new KeycloakAdapterConfigService();
public static KeycloakAdapterConfigService getInstance() {
return INSTANCE;
}
private final Map<String, ModelNode> realms = new HashMap<>();
// keycloak-secured deployments
private final Map<String, ModelNode> secureDeployments = new HashMap<>();
private KeycloakAdapterConfigService() {
}
public void addRealm(ModelNode operation, ModelNode model) {
this.realms.put(realmNameFromOp(operation), model.clone());
}
public void updateRealm(ModelNode operation, String attrName, ModelNode resolvedValue) {
ModelNode realm = this.realms.get(realmNameFromOp(operation));
realm.get(attrName).set(resolvedValue);
}
public void removeRealm(ModelNode operation) {
this.realms.remove(realmNameFromOp(operation));
}
public void addSecureDeployment(ModelNode operation, ModelNode model) {
ModelNode deployment = model.clone();
this.secureDeployments.put(deploymentNameFromOp(operation), deployment);
}
public void updateSecureDeployment(ModelNode operation, String attrName, ModelNode resolvedValue) {
ModelNode deployment = this.secureDeployments.get(deploymentNameFromOp(operation));
deployment.get(attrName).set(resolvedValue);
}
public void removeSecureDeployment(ModelNode operation) {
this.secureDeployments.remove(deploymentNameFromOp(operation));
}
public void addCredential(ModelNode operation, ModelNode model) {
ModelNode credentials = credentialsFromOp(operation);
if (!credentials.isDefined()) {
credentials = new ModelNode();
}
String credentialName = credentialNameFromOp(operation);
if (!credentialName.contains(".")) {
credentials.get(credentialName).set(model.get("value").asString());
} else {
String[] parts = credentialName.split("\\.");
String provider = parts[0];
String property = parts[1];
ModelNode credential = credentials.get(provider);
if (!credential.isDefined()) {
credential = new ModelNode();
}
credential.get(property).set(model.get("value").asString());
credentials.set(provider, credential);
}
ModelNode deployment = this.secureDeployments.get(deploymentNameFromOp(operation));
deployment.get(CREDENTIALS_JSON_NAME).set(credentials);
}
public void removeCredential(ModelNode operation) {
ModelNode credentials = credentialsFromOp(operation);
if (!credentials.isDefined()) {
throw new RuntimeException("Can not remove credential. No credential defined for deployment in op " + operation.toString());
}
String credentialName = credentialNameFromOp(operation);
credentials.remove(credentialName);
}
public void updateCredential(ModelNode operation, String attrName, ModelNode resolvedValue) {
ModelNode credentials = credentialsFromOp(operation);
if (!credentials.isDefined()) {
throw new RuntimeException("Can not update credential. No credential defined for deployment in op " + operation.toString());
}
String credentialName = credentialNameFromOp(operation);
credentials.get(credentialName).set(resolvedValue);
}
private ModelNode credentialsFromOp(ModelNode operation) {
ModelNode deployment = this.secureDeployments.get(deploymentNameFromOp(operation));
return deployment.get(CREDENTIALS_JSON_NAME);
}
private String realmNameFromOp(ModelNode operation) {
return valueFromOpAddress(RealmDefinition.TAG_NAME, operation);
}
private String deploymentNameFromOp(ModelNode operation) {
return valueFromOpAddress(SecureDeploymentDefinition.TAG_NAME, operation);
}
private String credentialNameFromOp(ModelNode operation) {
return valueFromOpAddress(CredentialDefinition.TAG_NAME, operation);
}
private String valueFromOpAddress(String addrElement, ModelNode operation) {
String deploymentName = getValueOfAddrElement(operation.get(ADDRESS), addrElement);
if (deploymentName == null) throw new RuntimeException("Can't find '" + addrElement + "' in address " + operation.toString());
return deploymentName;
}
private String getValueOfAddrElement(ModelNode address, String elementName) {
for (ModelNode element : address.asList()) {
if (element.has(elementName)) return element.get(elementName).asString();
}
return null;
}
public String getRealmName(DeploymentUnit deploymentUnit) {
ModelNode deployment = getSecureDeployment(deploymentUnit);
return deployment.get(RealmDefinition.TAG_NAME).asString();
}
protected boolean isDeploymentConfigured(DeploymentUnit deploymentUnit) {
ModelNode deployment = getSecureDeployment(deploymentUnit);
if (! deployment.isDefined()) {
return false;
}
ModelNode resource = deployment.get(SecureDeploymentDefinition.RESOURCE.getName());
return resource.isDefined();
}
public String getJSON(DeploymentUnit deploymentUnit) {
ModelNode deployment = getSecureDeployment(deploymentUnit);
String realmName = deployment.get(RealmDefinition.TAG_NAME).asString();
ModelNode realm = this.realms.get(realmName);
ModelNode json = new ModelNode();
json.get(RealmDefinition.TAG_NAME).set(realmName);
// Realm values set first. Some can be overridden by deployment values.
if (realm != null) setJSONValues(json, realm);
setJSONValues(json, deployment);
return json.toJSONString(true);
}
private void setJSONValues(ModelNode json, ModelNode values) {
for (Property prop : values.asPropertyList()) {
String name = prop.getName();
ModelNode value = prop.getValue();
if (value.isDefined()) {
json.get(name).set(value);
}
}
}
public boolean isSecureDeployment(DeploymentUnit deploymentUnit) {
//log.info("********* CHECK KEYCLOAK DEPLOYMENT: deployments.size()" + deployments.size());
String deploymentName = preferredDeploymentName(deploymentUnit);
return this.secureDeployments.containsKey(deploymentName);
}
private ModelNode getSecureDeployment(DeploymentUnit deploymentUnit) {
String deploymentName = preferredDeploymentName(deploymentUnit);
return this.secureDeployments.containsKey(deploymentName)
? this.secureDeployments.get(deploymentName)
: new ModelNode();
}
// KEYCLOAK-3273: prefer module name if available
private String preferredDeploymentName(DeploymentUnit deploymentUnit) {
String deploymentName = deploymentUnit.getName();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return deploymentName;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
return deploymentName;
}
String moduleName = webMetaData.getModuleName();
if (moduleName != null) return moduleName + ".war";
return deploymentName;
}
}

View file

@ -1,85 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
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.as.web.deployment.WarMetaData;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
import org.jboss.metadata.web.spec.LoginConfigMetaData;
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");
private static final ModuleIdentifier KEYCLOAK_COMMON = ModuleIdentifier.create("org.keycloak.keycloak-common");
@Override
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
if (!KeycloakAdapterConfigService.getInstance().isSecureDeployment(deploymentUnit)) {
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) return;
if (loginConfig.getAuthMethod() == null) return;
if (!loginConfig.getAuthMethod().equals("KEYCLOAK")) return;
}
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));
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_COMMON, false, false, false, false));
}
abstract protected void addPlatformSpecificModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader);
@Override
public void undeploy(DeploymentUnit du) {
}
}

View file

@ -1,36 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.server.deployment.module.ModuleDependency;
import org.jboss.as.server.deployment.module.ModuleSpecification;
import org.jboss.modules.ModuleIdentifier;
import org.jboss.modules.ModuleLoader;
/**
* @author <a href="mailto:marko.strukelj@gmail.com">Marko Strukelj</a>
*/
public class KeycloakDependencyProcessorAS7 extends KeycloakDependencyProcessor {
private static final ModuleIdentifier KEYCLOAK_AS7_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-as7-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));
}}

View file

@ -1,87 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.Extension;
import org.jboss.as.controller.ExtensionContext;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.ResourceDefinition;
import org.jboss.as.controller.SubsystemRegistration;
import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
import org.jboss.as.controller.parsing.ExtensionParsingContext;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.keycloak.subsystem.as7.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";
public static final String NAMESPACE_1_1 = "urn:jboss:domain:keycloak:1.1";
public static final String NAMESPACE_1_2 = "urn:jboss:domain:keycloak:1.2";
public static final String CURRENT_NAMESPACE = NAMESPACE_1_2;
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 MGMT_API_VERSION_MAJOR = 1;
private static final int MGMT_API_VERSION_MINOR = 1;
static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
private static final ResourceDefinition KEYCLOAK_SUBSYSTEM_RESOURCE = new KeycloakSubsystemDefinition();
static final RealmDefinition REALM_DEFINITION = new RealmDefinition();
static final SecureDeploymentDefinition SECURE_DEPLOYMENT_DEFINITION = new SecureDeploymentDefinition();
static final CredentialDefinition CREDENTIAL_DEFINITION = new CredentialDefinition();
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_1_1, PARSER);
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, KeycloakExtension.NAMESPACE_1_2, 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_MAJOR, MGMT_API_VERSION_MINOR);
ManagementResourceRegistration registration = subsystem.registerSubsystemModel(KEYCLOAK_SUBSYSTEM_RESOURCE);
registration.registerSubModel(REALM_DEFINITION);
ManagementResourceRegistration secureDeploymentRegistration = registration.registerSubModel(SECURE_DEPLOYMENT_DEFINITION);
secureDeploymentRegistration.registerSubModel(CREDENTIAL_DEFINITION);
subsystem.registerXMLElementWriter(PARSER);
}
}

View file

@ -1,59 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
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;
/**
* 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, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) {
context.addStep(new AbstractDeploymentChainStep() {
@Override
protected void execute(DeploymentProcessorTarget processorTarget) {
processorTarget.addDeploymentProcessor(Phase.DEPENDENCIES, 0, new KeycloakDependencyProcessorAS7());
processorTarget.addDeploymentProcessor(
Phase.POST_MODULE, // PHASE
Phase.POST_MODULE_VALIDATOR_FACTORY - 1, // PRIORITY
new KeycloakAdapterConfigDeploymentProcessor());
}
}, OperationContext.Stage.RUNTIME);
}
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
model.setEmptyObject();
}
}

View file

@ -1,47 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
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;
import org.jboss.as.controller.registry.OperationEntry;
/**
* 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(ModelDescriptionConstants.DESCRIBE, GenericSubsystemDescribeHandler.INSTANCE, GenericSubsystemDescribeHandler.INSTANCE, false, OperationEntry.EntryType.PRIVATE);
}
}

View file

@ -1,294 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
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.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.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 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(RealmDefinition.TAG_NAME)) {
readRealm(reader, list);
}
else if (reader.getLocalName().equals(SecureDeploymentDefinition.TAG_NAME)) {
readDeployment(reader, list);
}
}
}
// used for debugging
private int nextTag(XMLExtendedStreamReader reader) throws XMLStreamException {
return reader.nextTag();
}
private void readRealm(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException {
String realmName = readNameAttribute(reader);
ModelNode addRealm = new ModelNode();
addRealm.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
PathElement.pathElement(RealmDefinition.TAG_NAME, realmName));
addRealm.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
SimpleAttributeDefinition def = RealmDefinition.lookup(tagName);
if (def == null) throw new XMLStreamException("Unknown realm tag " + tagName);
def.parseAndSetParameter(reader.getElementText(), addRealm, reader);
}
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addRealm)) {
//TODO: externalize the message
throw new XMLStreamException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-manager is false.");
}
list.add(addRealm);
}
private void readDeployment(XMLExtendedStreamReader reader, List<ModelNode> resourcesToAdd) throws XMLStreamException {
String name = readNameAttribute(reader);
ModelNode addSecureDeployment = new ModelNode();
addSecureDeployment.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakExtension.SUBSYSTEM_NAME),
PathElement.pathElement(SecureDeploymentDefinition.TAG_NAME, name));
addSecureDeployment.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
List<ModelNode> credentialsToAdd = new ArrayList<>();
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
if (tagName.equals(CredentialDefinition.TAG_NAME)) {
readCredential(reader, addr, credentialsToAdd);
continue;
}
SimpleAttributeDefinition def = SecureDeploymentDefinition.lookup(tagName);
if (def == null) throw new XMLStreamException("Unknown secure-deployment tag " + tagName);
def.parseAndSetParameter(reader.getElementText(), addSecureDeployment, reader);
}
/**
* TODO need to check realm-ref first.
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(addSecureDeployment)) {
//TODO: externalize the message
throw new XMLStreamException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-manager is false.");
}
*/
// Must add credentials after the deployment is added.
resourcesToAdd.add(addSecureDeployment);
resourcesToAdd.addAll(credentialsToAdd);
}
public void readCredential(XMLExtendedStreamReader reader, PathAddress parent, List<ModelNode> credentialsToAdd) throws XMLStreamException {
String name = readNameAttribute(reader);
Map<String, String> values = new HashMap<>();
String textValue = null;
while (reader.hasNext()) {
int next = reader.next();
if (next == CHARACTERS) {
// text value of credential element (like for "secret" )
String text = reader.getText();
if (text == null || text.trim().isEmpty()) {
continue;
}
textValue = text;
} else if (next == START_ELEMENT) {
String key = reader.getLocalName();
reader.next();
String value = reader.getText();
reader.next();
values.put(key, value);
} else if (next == END_ELEMENT) {
break;
}
}
if (textValue != null) {
ModelNode addCredential = getCredentialToAdd(parent, name, textValue);
credentialsToAdd.add(addCredential);
} else {
for (Map.Entry<String, String> entry : values.entrySet()) {
ModelNode addCredential = getCredentialToAdd(parent, name + "." + entry.getKey(), entry.getValue());
credentialsToAdd.add(addCredential);
}
}
}
private ModelNode getCredentialToAdd(PathAddress parent, String name, String value) {
ModelNode addCredential = new ModelNode();
addCredential.get(ModelDescriptionConstants.OP).set(ModelDescriptionConstants.ADD);
PathAddress addr = PathAddress.pathAddress(parent, PathElement.pathElement(CredentialDefinition.TAG_NAME, name));
addCredential.get(ModelDescriptionConstants.OP_ADDR).set(addr.toModelNode());
addCredential.get(CredentialDefinition.VALUE.getName()).set(value);
return addCredential;
}
// 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.CURRENT_NAMESPACE, false);
writeRealms(writer, context);
writeSecureDeployments(writer, context);
writer.writeEndElement();
}
private void writeRealms(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
if (!context.getModelNode().get(RealmDefinition.TAG_NAME).isDefined()) {
return;
}
for (Property realm : context.getModelNode().get(RealmDefinition.TAG_NAME).asPropertyList()) {
writer.writeStartElement(RealmDefinition.TAG_NAME);
writer.writeAttribute("name", realm.getName());
ModelNode realmElements = realm.getValue();
for (AttributeDefinition element : RealmDefinition.ALL_ATTRIBUTES) {
element.marshallAsElement(realmElements, writer);
}
writer.writeEndElement();
}
}
private void writeSecureDeployments(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
if (!context.getModelNode().get(SecureDeploymentDefinition.TAG_NAME).isDefined()) {
return;
}
for (Property deployment : context.getModelNode().get(SecureDeploymentDefinition.TAG_NAME).asPropertyList()) {
writer.writeStartElement(SecureDeploymentDefinition.TAG_NAME);
writer.writeAttribute("name", deployment.getName());
ModelNode deploymentElements = deployment.getValue();
for (AttributeDefinition element : SecureDeploymentDefinition.ALL_ATTRIBUTES) {
element.marshallAsElement(deploymentElements, writer);
}
ModelNode credentials = deploymentElements.get(CredentialDefinition.TAG_NAME);
if (credentials.isDefined()) {
writeCredentials(writer, credentials);
}
writer.writeEndElement();
}
}
private void writeCredentials(XMLExtendedStreamWriter writer, ModelNode credentials) throws XMLStreamException {
Map<String, Object> parsed = new LinkedHashMap<>();
for (Property credential : credentials.asPropertyList()) {
String credName = credential.getName();
String credValue = credential.getValue().get(CredentialDefinition.VALUE.getName()).asString();
if (credName.indexOf('.') > -1) {
String[] parts = credName.split("\\.");
String provider = parts[0];
String propKey = parts[1];
Map<String, String> currentProviderMap = (Map<String, String>) parsed.get(provider);
if (currentProviderMap == null) {
currentProviderMap = new LinkedHashMap<>();
parsed.put(provider, currentProviderMap);
}
currentProviderMap.put(propKey, credValue);
} else {
parsed.put(credName, credValue);
}
}
for (Map.Entry<String, Object> entry : parsed.entrySet()) {
writer.writeStartElement(CredentialDefinition.TAG_NAME);
writer.writeAttribute("name", entry.getKey());
Object value = entry.getValue();
if (value instanceof String) {
writeCharacters(writer, (String) value);
} else {
Map<String, String> credentialProps = (Map<String, String>) value;
for (Map.Entry<String, String> prop : credentialProps.entrySet()) {
writer.writeStartElement(prop.getKey());
writeCharacters(writer, prop.getValue());
writer.writeEndElement();
}
}
writer.writeEndElement();
}
}
// code taken from org.jboss.as.controller.AttributeMarshaller
private void writeCharacters(XMLExtendedStreamWriter writer, String content) throws XMLStreamException {
if (content.indexOf('\n') > -1) {
// Multiline content. Use the overloaded variant that staxmapper will format
writer.writeCharacters(content);
} else {
// Staxmapper will just output the chars without adding newlines if this is used
char[] chars = content.toCharArray();
writer.writeCharacters(chars, 0, chars.length);
}
}
}

View file

@ -1,58 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
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 new realm.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
public final class RealmAddHandler extends AbstractAddStepHandler {
public static RealmAddHandler INSTANCE = new RealmAddHandler();
private RealmAddHandler() {}
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
for (AttributeDefinition attrib : RealmDefinition.ALL_ATTRIBUTES) {
attrib.validateAndSet(operation, model);
}
if (!SharedAttributeDefinitons.validateTruststoreSetIfRequired(model.clone())) {
//TODO: externalize message
throw new OperationFailedException("truststore and truststore-password must be set if ssl-required is not none and disable-trust-manager is false.");
}
}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
ckService.addRealm(operation, context.resolveExpressions(model));
}
}

View file

@ -1,89 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.SimpleAttributeDefinition;
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;
import org.jboss.as.controller.registry.OperationEntry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Defines attributes and operations for the Realm
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
class RealmDefinition extends SimpleResourceDefinition {
public static final String TAG_NAME = "realm";
protected static final List<SimpleAttributeDefinition> REALM_ONLY_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
static {
}
protected static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList<SimpleAttributeDefinition>();
static {
ALL_ATTRIBUTES.addAll(REALM_ONLY_ATTRIBUTES);
ALL_ATTRIBUTES.addAll(SharedAttributeDefinitons.ATTRIBUTES);
}
private static final Map<String, SimpleAttributeDefinition> DEFINITION_LOOKUP = new HashMap<String, SimpleAttributeDefinition>();
static {
for (SimpleAttributeDefinition def : ALL_ATTRIBUTES) {
DEFINITION_LOOKUP.put(def.getXmlName(), def);
}
}
private static final RealmWriteAttributeHandler realmAttrHandler = new RealmWriteAttributeHandler(ALL_ATTRIBUTES.toArray(new SimpleAttributeDefinition[0]));
public RealmDefinition() {
super(PathElement.pathElement("realm"),
KeycloakExtension.getResourceDescriptionResolver("realm"),
RealmAddHandler.INSTANCE,
RealmRemoveHandler.INSTANCE);
}
@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);
resourceRegistration.registerOperationHandler(ModelDescriptionConstants.DESCRIBE, GenericSubsystemDescribeHandler.INSTANCE, GenericSubsystemDescribeHandler.INSTANCE, false, OperationEntry.EntryType.PRIVATE);
}
@Override
public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
super.registerAttributes(resourceRegistration);
for (AttributeDefinition attrDef : ALL_ATTRIBUTES) {
//TODO: use subclass of realmAttrHandler that can call RealmDefinition.validateTruststoreSetIfRequired
resourceRegistration.registerReadWriteAttribute(attrDef, null, realmAttrHandler);
}
}
public static SimpleAttributeDefinition lookup(String name) {
return DEFINITION_LOOKUP.get(name);
}
}

View file

@ -1,41 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.AbstractRemoveStepHandler;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.dmr.ModelNode;
/**
* Remove a realm.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
final class RealmRemoveHandler extends AbstractRemoveStepHandler {
public static RealmRemoveHandler INSTANCE = new RealmRemoveHandler();
private RealmRemoveHandler() {}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
ckService.removeRealm(operation);
}
}

View file

@ -1,54 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.AbstractWriteAttributeHandler;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.dmr.ModelNode;
/**
* Update an attribute on a realm.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
class RealmWriteAttributeHandler extends AbstractWriteAttributeHandler<KeycloakAdapterConfigService> {
public RealmWriteAttributeHandler(AttributeDefinition... definitions) {
super(definitions);
}
@Override
protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
ModelNode resolvedValue, ModelNode currentValue, HandbackHolder<KeycloakAdapterConfigService> hh) throws OperationFailedException {
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
ckService.updateRealm(operation, attributeName, resolvedValue);
hh.setHandback(ckService);
return false;
}
@Override
protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
ModelNode valueToRestore, ModelNode valueToRevert, KeycloakAdapterConfigService ckService) throws OperationFailedException {
ckService.updateRealm(operation, attributeName, valueToRestore);
}
}

View file

@ -1,54 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
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 deployment to a realm.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
final class SecureDeploymentAddHandler extends AbstractAddStepHandler {
public static SecureDeploymentAddHandler INSTANCE = new SecureDeploymentAddHandler();
private SecureDeploymentAddHandler() {
}
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
for (AttributeDefinition attr : SecureDeploymentDefinition.ALL_ATTRIBUTES) {
attr.validateAndSet(operation, model);
}
}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
ckService.addSecureDeployment(operation, context.resolveExpressions(model));
}
}

View file

@ -1,161 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
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.operations.validation.IntRangeValidator;
import org.jboss.as.controller.operations.validation.StringLengthValidator;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.controller.registry.OperationEntry;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Defines attributes and operations for a secure-deployment.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
class SecureDeploymentDefinition extends SimpleResourceDefinition {
public static final String TAG_NAME = "secure-deployment";
protected static final SimpleAttributeDefinition REALM =
new SimpleAttributeDefinitionBuilder("realm", ModelType.STRING, true)
.setXmlName("realm")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition RESOURCE =
new SimpleAttributeDefinitionBuilder("resource", ModelType.STRING, true)
.setXmlName("resource")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition USE_RESOURCE_ROLE_MAPPINGS =
new SimpleAttributeDefinitionBuilder("use-resource-role-mappings", ModelType.BOOLEAN, true)
.setXmlName("use-resource-role-mappings")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition BEARER_ONLY =
new SimpleAttributeDefinitionBuilder("bearer-only", ModelType.BOOLEAN, true)
.setXmlName("bearer-only")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition ENABLE_BASIC_AUTH =
new SimpleAttributeDefinitionBuilder("enable-basic-auth", ModelType.BOOLEAN, true)
.setXmlName("enable-basic-auth")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition PUBLIC_CLIENT =
new SimpleAttributeDefinitionBuilder("public-client", ModelType.BOOLEAN, true)
.setXmlName("public-client")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition TURN_OFF_CHANGE_SESSION =
new SimpleAttributeDefinitionBuilder("turn-off-change-session-id-on-login", ModelType.BOOLEAN, true)
.setXmlName("turn-off-change-session-id-on-login")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition TOKEN_MINIMUM_TIME_TO_LIVE =
new SimpleAttributeDefinitionBuilder("token-minimum-time-to-live", ModelType.INT, true)
.setXmlName("token-minimum-time-to-live")
.setValidator(new IntRangeValidator(-1, true))
.setAllowExpression(true)
.build();
protected static final SimpleAttributeDefinition MIN_TIME_BETWEEN_JWKS_REQUESTS =
new SimpleAttributeDefinitionBuilder("min-time-between-jwks-requests", ModelType.INT, true)
.setXmlName("min-time-between-jwks-requests")
.setValidator(new IntRangeValidator(-1, true))
.setAllowExpression(true)
.build();
protected static final SimpleAttributeDefinition PUBLIC_KEY_CACHE_TTL =
new SimpleAttributeDefinitionBuilder("public-key-cache-ttl", ModelType.INT, true)
.setXmlName("public-key-cache-ttl")
.setAllowExpression(true)
.setValidator(new IntRangeValidator(-1, true))
.build();
protected static final List<SimpleAttributeDefinition> DEPLOYMENT_ONLY_ATTRIBUTES = new ArrayList<>();
static {
DEPLOYMENT_ONLY_ATTRIBUTES.add(REALM);
DEPLOYMENT_ONLY_ATTRIBUTES.add(RESOURCE);
DEPLOYMENT_ONLY_ATTRIBUTES.add(USE_RESOURCE_ROLE_MAPPINGS);
DEPLOYMENT_ONLY_ATTRIBUTES.add(BEARER_ONLY);
DEPLOYMENT_ONLY_ATTRIBUTES.add(ENABLE_BASIC_AUTH);
DEPLOYMENT_ONLY_ATTRIBUTES.add(PUBLIC_CLIENT);
DEPLOYMENT_ONLY_ATTRIBUTES.add(TURN_OFF_CHANGE_SESSION);
DEPLOYMENT_ONLY_ATTRIBUTES.add(TOKEN_MINIMUM_TIME_TO_LIVE);
DEPLOYMENT_ONLY_ATTRIBUTES.add(MIN_TIME_BETWEEN_JWKS_REQUESTS);
DEPLOYMENT_ONLY_ATTRIBUTES.add(PUBLIC_KEY_CACHE_TTL);
}
protected static final List<SimpleAttributeDefinition> ALL_ATTRIBUTES = new ArrayList<>();
static {
ALL_ATTRIBUTES.addAll(DEPLOYMENT_ONLY_ATTRIBUTES);
ALL_ATTRIBUTES.addAll(SharedAttributeDefinitons.ATTRIBUTES);
}
private static final Map<String, SimpleAttributeDefinition> DEFINITION_LOOKUP = new HashMap<>();
static {
for (SimpleAttributeDefinition def : ALL_ATTRIBUTES) {
DEFINITION_LOOKUP.put(def.getXmlName(), def);
}
}
private static SecureDeploymentWriteAttributeHandler attrHandler = new SecureDeploymentWriteAttributeHandler(ALL_ATTRIBUTES);
public SecureDeploymentDefinition() {
super(PathElement.pathElement(TAG_NAME),
KeycloakExtension.getResourceDescriptionResolver(TAG_NAME),
SecureDeploymentAddHandler.INSTANCE,
SecureDeploymentRemoveHandler.INSTANCE);
}
@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);
resourceRegistration.registerOperationHandler(ModelDescriptionConstants.DESCRIBE, GenericSubsystemDescribeHandler.INSTANCE, GenericSubsystemDescribeHandler.INSTANCE, false, OperationEntry.EntryType.PRIVATE);
}
@Override
public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
super.registerAttributes(resourceRegistration);
for (AttributeDefinition attrDef : ALL_ATTRIBUTES) {
resourceRegistration.registerReadWriteAttribute(attrDef, null, attrHandler);
}
}
public static SimpleAttributeDefinition lookup(String name) {
return DEFINITION_LOOKUP.get(name);
}
}

View file

@ -1,41 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.AbstractRemoveStepHandler;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.dmr.ModelNode;
/**
* Remove a secure-deployment from a realm.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
final class SecureDeploymentRemoveHandler extends AbstractRemoveStepHandler {
public static SecureDeploymentRemoveHandler INSTANCE = new SecureDeploymentRemoveHandler();
private SecureDeploymentRemoveHandler() {}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
ckService.removeSecureDeployment(operation);
}
}

View file

@ -1,59 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.AbstractWriteAttributeHandler;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.dmr.ModelNode;
import java.util.List;
/**
* Update an attribute on a secure-deployment.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
class SecureDeploymentWriteAttributeHandler extends AbstractWriteAttributeHandler<KeycloakAdapterConfigService> {
public SecureDeploymentWriteAttributeHandler(List<SimpleAttributeDefinition> definitions) {
this(definitions.toArray(new AttributeDefinition[definitions.size()]));
}
public SecureDeploymentWriteAttributeHandler(AttributeDefinition... definitions) {
super(definitions);
}
@Override
protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
ModelNode resolvedValue, ModelNode currentValue, HandbackHolder<KeycloakAdapterConfigService> hh) throws OperationFailedException {
KeycloakAdapterConfigService ckService = KeycloakAdapterConfigService.getInstance();
hh.setHandback(ckService);
ckService.updateSecureDeployment(operation, attributeName, resolvedValue);
return false;
}
@Override
protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
ModelNode valueToRestore, ModelNode valueToRevert, KeycloakAdapterConfigService ckService) throws OperationFailedException {
ckService.updateSecureDeployment(operation, attributeName, valueToRestore);
}
}

View file

@ -1,265 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.operations.validation.IntRangeValidator;
import org.jboss.as.controller.operations.validation.LongRangeValidator;
import org.jboss.as.controller.operations.validation.StringLengthValidator;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import java.util.ArrayList;
import java.util.List;
/**
* Defines attributes that can be present in both a realm and an application (secure-deployment).
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
class SharedAttributeDefinitons {
protected static final SimpleAttributeDefinition REALM_PUBLIC_KEY =
new SimpleAttributeDefinitionBuilder("realm-public-key", ModelType.STRING, true)
.setXmlName("realm-public-key")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition AUTH_SERVER_URL =
new SimpleAttributeDefinitionBuilder("auth-server-url", ModelType.STRING, true)
.setXmlName("auth-server-url")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition SSL_REQUIRED =
new SimpleAttributeDefinitionBuilder("ssl-required", ModelType.STRING, true)
.setXmlName("ssl-required")
.setAllowExpression(true)
.setDefaultValue(new ModelNode("external"))
.build();
protected static final SimpleAttributeDefinition ALLOW_ANY_HOSTNAME =
new SimpleAttributeDefinitionBuilder("allow-any-hostname", ModelType.BOOLEAN, true)
.setXmlName("allow-any-hostname")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition DISABLE_TRUST_MANAGER =
new SimpleAttributeDefinitionBuilder("disable-trust-manager", ModelType.BOOLEAN, true)
.setXmlName("disable-trust-manager")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition TRUSTSTORE =
new SimpleAttributeDefinitionBuilder("truststore", ModelType.STRING, true)
.setXmlName("truststore")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition TRUSTSTORE_PASSWORD =
new SimpleAttributeDefinitionBuilder("truststore-password", ModelType.STRING, true)
.setXmlName("truststore-password")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition CONNECTION_POOL_SIZE =
new SimpleAttributeDefinitionBuilder("connection-pool-size", ModelType.INT, true)
.setXmlName("connection-pool-size")
.setAllowExpression(true)
.setValidator(new IntRangeValidator(0, true))
.build();
protected static final SimpleAttributeDefinition SOCKET_TIMEOUT =
new SimpleAttributeDefinitionBuilder("socket-timeout-millis", ModelType.LONG, true)
.setXmlName("socket-timeout-millis")
.setAllowExpression(true)
.setValidator(new LongRangeValidator(-1L, true))
.build();
protected static final SimpleAttributeDefinition CONNECTION_TTL =
new SimpleAttributeDefinitionBuilder("connection-ttl-millis", ModelType.LONG, true)
.setXmlName("connection-ttl-millis")
.setAllowExpression(true)
.setValidator(new LongRangeValidator(-1L, true))
.build();
protected static final SimpleAttributeDefinition CONNECTION_TIMEOUT =
new SimpleAttributeDefinitionBuilder("connection-timeout-millis", ModelType.LONG, true)
.setXmlName("connection-timeout-millis")
.setAllowExpression(true)
.setValidator(new LongRangeValidator(-1L, true))
.build();
protected static final SimpleAttributeDefinition ENABLE_CORS =
new SimpleAttributeDefinitionBuilder("enable-cors", ModelType.BOOLEAN, true)
.setXmlName("enable-cors")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition CLIENT_KEYSTORE =
new SimpleAttributeDefinitionBuilder("client-keystore", ModelType.STRING, true)
.setXmlName("client-keystore")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition CLIENT_KEYSTORE_PASSWORD =
new SimpleAttributeDefinitionBuilder("client-keystore-password", ModelType.STRING, true)
.setXmlName("client-keystore-password")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition CLIENT_KEY_PASSWORD =
new SimpleAttributeDefinitionBuilder("client-key-password", ModelType.STRING, true)
.setXmlName("client-key-password")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition CORS_MAX_AGE =
new SimpleAttributeDefinitionBuilder("cors-max-age", ModelType.INT, true)
.setXmlName("cors-max-age")
.setAllowExpression(true)
.setValidator(new IntRangeValidator(-1, true))
.build();
protected static final SimpleAttributeDefinition CORS_ALLOWED_HEADERS =
new SimpleAttributeDefinitionBuilder("cors-allowed-headers", ModelType.STRING, true)
.setXmlName("cors-allowed-headers")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition CORS_ALLOWED_METHODS =
new SimpleAttributeDefinitionBuilder("cors-allowed-methods", ModelType.STRING, true)
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition EXPOSE_TOKEN =
new SimpleAttributeDefinitionBuilder("expose-token", ModelType.BOOLEAN, true)
.setXmlName("expose-token")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition AUTH_SERVER_URL_FOR_BACKEND_REQUESTS =
new SimpleAttributeDefinitionBuilder("auth-server-url-for-backend-requests", ModelType.STRING, true)
.setXmlName("auth-server-url-for-backend-requests")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition ALWAYS_REFRESH_TOKEN =
new SimpleAttributeDefinitionBuilder("always-refresh-token", ModelType.BOOLEAN, true)
.setXmlName("always-refresh-token")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition REGISTER_NODE_AT_STARTUP =
new SimpleAttributeDefinitionBuilder("register-node-at-startup", ModelType.BOOLEAN, true)
.setXmlName("register-node-at-startup")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final SimpleAttributeDefinition REGISTER_NODE_PERIOD =
new SimpleAttributeDefinitionBuilder("register-node-period", ModelType.INT, true)
.setXmlName("register-node-period")
.setAllowExpression(true)
.setValidator(new IntRangeValidator(-1, true))
.build();
protected static final SimpleAttributeDefinition TOKEN_STORE =
new SimpleAttributeDefinitionBuilder("token-store", ModelType.STRING, true)
.setXmlName("token-store")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition PRINCIPAL_ATTRIBUTE =
new SimpleAttributeDefinitionBuilder("principal-attribute", ModelType.STRING, true)
.setXmlName("principal-attribute")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition PROXY_URL =
new SimpleAttributeDefinitionBuilder("proxy-url", ModelType.STRING, true)
.setXmlName("proxy-url")
.setAllowExpression(true)
.setValidator(new StringLengthValidator(1, Integer.MAX_VALUE, true, true))
.build();
protected static final SimpleAttributeDefinition VERIFY_TOKEN_AUDIENCE =
new SimpleAttributeDefinitionBuilder("verify-token-audience", ModelType.BOOLEAN, true)
.setXmlName("verify-token-audience")
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.build();
protected static final List<SimpleAttributeDefinition> ATTRIBUTES = new ArrayList<>();
static {
ATTRIBUTES.add(REALM_PUBLIC_KEY);
ATTRIBUTES.add(AUTH_SERVER_URL);
ATTRIBUTES.add(TRUSTSTORE);
ATTRIBUTES.add(TRUSTSTORE_PASSWORD);
ATTRIBUTES.add(SSL_REQUIRED);
ATTRIBUTES.add(ALLOW_ANY_HOSTNAME);
ATTRIBUTES.add(DISABLE_TRUST_MANAGER);
ATTRIBUTES.add(CONNECTION_POOL_SIZE);
ATTRIBUTES.add(SOCKET_TIMEOUT);
ATTRIBUTES.add(CONNECTION_TTL);
ATTRIBUTES.add(CONNECTION_TIMEOUT);
ATTRIBUTES.add(ENABLE_CORS);
ATTRIBUTES.add(CLIENT_KEYSTORE);
ATTRIBUTES.add(CLIENT_KEYSTORE_PASSWORD);
ATTRIBUTES.add(CLIENT_KEY_PASSWORD);
ATTRIBUTES.add(CORS_MAX_AGE);
ATTRIBUTES.add(CORS_ALLOWED_HEADERS);
ATTRIBUTES.add(CORS_ALLOWED_METHODS);
ATTRIBUTES.add(EXPOSE_TOKEN);
ATTRIBUTES.add(AUTH_SERVER_URL_FOR_BACKEND_REQUESTS);
ATTRIBUTES.add(ALWAYS_REFRESH_TOKEN);
ATTRIBUTES.add(REGISTER_NODE_AT_STARTUP);
ATTRIBUTES.add(REGISTER_NODE_PERIOD);
ATTRIBUTES.add(TOKEN_STORE);
ATTRIBUTES.add(PRINCIPAL_ATTRIBUTE);
ATTRIBUTES.add(PROXY_URL);
ATTRIBUTES.add(VERIFY_TOKEN_AUDIENCE);
}
/**
* truststore and truststore-password must be set if ssl-required is not none and disable-trust-manager is false.
*
* @param attributes The full set of attributes.
*
* @return <code>true</code> if the attributes are valid, <code>false</code> otherwise.
*/
public static boolean validateTruststoreSetIfRequired(ModelNode attributes) {
if (isSet(attributes, DISABLE_TRUST_MANAGER)) {
return true;
}
if (isSet(attributes, SSL_REQUIRED) && attributes.get(SSL_REQUIRED.getName()).asString().equals("none")) {
return true;
}
//TODO, look into alternatives & requires properties on AttributeDefinition
return isSet(attributes, TRUSTSTORE) && isSet(attributes, TRUSTSTORE_PASSWORD);
}
private static boolean isSet(ModelNode attributes, SimpleAttributeDefinition def) {
ModelNode attribute = attributes.get(def.getName());
if (def.getType() == ModelType.BOOLEAN) {
return attribute.isDefined() && attribute.asBoolean();
}
return attribute.isDefined() && !attribute.asString().isEmpty();
}
}

View file

@ -1,59 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.dmr.ModelNode;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class Util {
public static ModelNode createAddOperation(final PathAddress address) {
return createOperation(ModelDescriptionConstants.ADD, address);
}
public static ModelNode createAddOperation() {
return createEmptyOperation(ModelDescriptionConstants.ADD, null);
}
public static ModelNode createRemoveOperation(final PathAddress address) {
return createOperation(ModelDescriptionConstants.REMOVE, address);
}
public static ModelNode createOperation(final String operationName, final PathAddress address) {
return createEmptyOperation(operationName, address);
}
public static ModelNode createEmptyOperation(String operationName, final PathAddress address) {
ModelNode op = new ModelNode();
op.get(OP).set(operationName);
if (address != null) {
op.get(OP_ADDR).set(address.toModelNode());
} else {
// Just establish the standard structure; caller can fill in address later
op.get(OP_ADDR);
}
return op;
}
}

View file

@ -1,49 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7.logging;
import org.jboss.logging.BasicLogger;
import org.jboss.logging.LogMessage;
import org.jboss.logging.Logger;
import org.jboss.logging.Message;
import org.jboss.logging.MessageLogger;
import static org.jboss.logging.Logger.Level.DEBUG;
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");
@LogMessage(level = INFO)
@Message(value = "Keycloak subsystem override for deployment %s")
void deploymentSecured(String deployment);
@LogMessage(level = DEBUG)
@Message(value = "Keycloak has overriden and secured deployment %s")
void warSecured(String deployment);
}

View file

@ -1,34 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7.logging;
import org.jboss.logging.MessageBundle;
import org.jboss.logging.Messages;
/**
* 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 = "TLIP")
public interface KeycloakMessages {
/**
* The messages
*/
KeycloakMessages MESSAGES = Messages.getBundle(KeycloakMessages.class);
}

View file

@ -1,18 +0,0 @@
#
# Copyright 2016 Red Hat, Inc. and/or its affiliates
# and other contributors as indicated by the @author tags.
#
# 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.
#
org.keycloak.subsystem.as7.KeycloakExtension

View file

@ -1,101 +0,0 @@
#
# Copyright 2016 Red Hat, Inc. and/or its affiliates
# and other contributors as indicated by the @author tags.
#
# 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.
#
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.realm=A Keycloak realm.
keycloak.realm.add=Add a realm definition to the subsystem.
keycloak.realm.remove=Remove a realm from the subsystem.
keycloak.realm.realm-public-key=Public key of the realm
keycloak.realm.auth-server-url=Base URL of the Realm Auth Server
keycloak.realm.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
keycloak.realm.ssl-required=Specify if SSL is required (valid values are all, external and none)
keycloak.realm.allow-any-hostname=SSL Setting
keycloak.realm.truststore=Truststore used for adapter client HTTPS requests
keycloak.realm.truststore-password=Password of the Truststore
keycloak.realm.connection-pool-size=Connection pool size for the client used by the adapter
keycloak.realm.socket-timeout-millis=Timeout for socket waiting for data in milliseconds
keycloak.realm.connection-ttl-millis=Connection time to live in milliseconds
keycloak.realm.connection-timeout-millis=Timeout for establishing the connection with the remote host in milliseconds
keycloak.realm.enable-cors=Enable Keycloak CORS support
keycloak.realm.client-keystore=n/a
keycloak.realm.client-keystore-password=n/a
keycloak.realm.client-key-password=n/a
keycloak.realm.cors-max-age=CORS max-age header
keycloak.realm.cors-allowed-headers=CORS allowed headers
keycloak.realm.cors-allowed-methods=CORS allowed methods
keycloak.realm.expose-token=Enable secure URL that exposes access token
keycloak.realm.auth-server-url-for-backend-requests=URL to use to make background calls to auth server
keycloak.realm.always-refresh-token=Refresh token on every single web request
keycloak.realm.register-node-at-startup=Cluster setting
keycloak.realm.register-node-period=how often to re-register node
keycloak.realm.token-store=cookie or session storage for auth session data
keycloak.realm.principal-attribute=token attribute to use to set Principal name
keycloak.realm.proxy-url=The URL for the HTTP proxy if one is used.
keycloak.realm.verify-token-audience=If true, then during bearer-only authentication, the adapter will verify if token contains this client name (resource) as an audience
keycloak.secure-deployment=A deployment secured by Keycloak
keycloak.secure-deployment.add=Add a deployment to be secured by Keycloak
keycloak.secure-deployment.realm=Keycloak realm
keycloak.secure-deployment.remove=Remove a deployment to be secured by Keycloak
keycloak.secure-deployment.realm-public-key=Public key of the realm
keycloak.secure-deployment.auth-server-url=Base URL of the Realm Auth Server
keycloak.secure-deployment.disable-trust-manager=Adapter will not use a trust manager when making adapter HTTPS requests
keycloak.secure-deployment.ssl-required=Specify if SSL is required (valid values are all, external and none)
keycloak.secure-deployment.allow-any-hostname=SSL Setting
keycloak.secure-deployment.truststore=Truststore used for adapter client HTTPS requests
keycloak.secure-deployment.truststore-password=Password of the Truststore
keycloak.secure-deployment.connection-pool-size=Connection pool size for the client used by the adapter
keycloak.secure-deployment.socket-timeout-millis=Timeout for socket waiting for data in milliseconds
keycloak.secure-deployment.connection-ttl-millis=Connection time to live in milliseconds
keycloak.secure-deployment.connection-timeout-millis=Timeout for establishing the connection with the remote host in milliseconds
keycloak.secure-deployment.resource=Application name
keycloak.secure-deployment.use-resource-role-mappings=Use resource level permissions from token
keycloak.secure-deployment.credentials=Adapter credentials
keycloak.secure-deployment.bearer-only=Bearer Token Auth only
keycloak.secure-deployment.enable-basic-auth=Enable Basic Authentication
keycloak.secure-deployment.public-client=Public client
keycloak.secure-deployment.enable-cors=Enable Keycloak CORS support
keycloak.secure-deployment.client-keystore=n/a
keycloak.secure-deployment.client-keystore-password=n/a
keycloak.secure-deployment.client-key-password=n/a
keycloak.secure-deployment.cors-max-age=CORS max-age header
keycloak.secure-deployment.cors-allowed-headers=CORS allowed headers
keycloak.secure-deployment.cors-allowed-methods=CORS allowed methods
keycloak.secure-deployment.expose-token=Enable secure URL that exposes access token
keycloak.secure-deployment.auth-server-url-for-backend-requests=URL to use to make background calls to auth server
keycloak.secure-deployment.always-refresh-token=Refresh token on every single web request
keycloak.secure-deployment.register-node-at-startup=Cluster setting
keycloak.secure-deployment.register-node-period=how often to re-register node
keycloak.secure-deployment.token-store=cookie or session storage for auth session data
keycloak.secure-deployment.principal-attribute=token attribute to use to set Principal name
keycloak.secure-deployment.turn-off-change-session-id-on-login=The session id is changed by default on a successful login. Change this to true if you want to turn this off
keycloak.secure-deployment.token-minimum-time-to-live=The adapter will refresh the token if the current token is expired OR will expire in 'token-minimum-time-to-live' seconds or less
keycloak.secure-deployment.min-time-between-jwks-requests=If adapter recognize token signed by unknown public key, it will try to download new public key from keycloak server. However it won't try to download if already tried it in less than 'min-time-between-jwks-requests' seconds
keycloak.secure-deployment.public-key-cache-ttl=Maximum time the downloaded public keys are considered valid. When this time reach, the adapter is forced to download public keys from keycloak server
keycloak.secure-deployment.proxy-url=The URL for the HTTP proxy if one is used.
keycloak.secure-deployment.verify-token-audience=If true, then during bearer-only authentication, the adapter will verify if token contains this client name (resource) as an audience
keycloak.secure-deployment.credential=Credential value
keycloak.credential=Credential
keycloak.credential.value=Credential value
keycloak.credential.add=Credential add
keycloak.credential.remove=Credential remove

View file

@ -1,129 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:jboss:domain:keycloak:1.1"
xmlns="urn:jboss:domain:keycloak: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 adapter subsystem, used to register deployments managed by Keycloak
]]>
</xs:documentation>
</xs:annotation>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="realm" maxOccurs="unbounded" minOccurs="0" type="realm-type"/>
<xs:element name="secure-deployment" maxOccurs="unbounded" minOccurs="0" type="secure-deployment-type"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="realm-type">
<xs:all>
<xs:element name="cors-allowed-headers" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="client-keystore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="client-keystore" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="truststore" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="truststore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="enable-cors" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="allow-any-hostname" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="client-key-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="connection-pool-size" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="cors-max-age" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="auth-server-url" type="xs:string" minOccurs="1" maxOccurs="1"/>
<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="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"/>
<xs:element name="register-node-at-startup" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="register-node-period" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="token-store" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="proxy-url" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="verify-token-audience" 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 realm.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="secure-deployment-type">
<xs:all>
<xs:element name="client-keystore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="client-keystore" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="enable-cors" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="allow-any-hostname" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="use-resource-role-mappings" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="cors-max-age" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<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="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" />
<xs:element name="truststore" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="truststore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="client-key-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="public-client" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="connection-pool-size" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="expose-token" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="ssl-required" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="credential" type="credential-type" 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"/>
<xs:element name="register-node-at-startup" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="register-node-period" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="token-store" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="enable-basic-auth" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="turn-off-change-session-id-on-login" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="token-minimum-time-to-live" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="min-time-between-jwks-requests" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="public-key-cache-ttl" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="proxy-url" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="verify-token-audience" 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 realm.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="credential-type" mixed="true">
<xs:sequence maxOccurs="unbounded" minOccurs="0">
<xs:any processContents="lax"></xs:any>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:schema>

View file

@ -1,135 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:jboss:domain:keycloak:1.2"
xmlns="urn:jboss:domain:keycloak:1.2"
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 adapter subsystem, used to register deployments managed by Keycloak
]]>
</xs:documentation>
</xs:annotation>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="realm" maxOccurs="unbounded" minOccurs="0" type="realm-type"/>
<xs:element name="secure-deployment" maxOccurs="unbounded" minOccurs="0" type="secure-deployment-type"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="realm-type">
<xs:all>
<xs:element name="cors-allowed-headers" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="client-keystore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="client-keystore" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="truststore" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="truststore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="enable-cors" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="allow-any-hostname" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="client-key-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="connection-pool-size" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="socket-timeout-millis" type="xs:long" minOccurs="0" maxOccurs="1"/>
<xs:element name="connection-ttl-millis" type="xs:long" minOccurs="0" maxOccurs="1"/>
<xs:element name="connection-timeout-millis" type="xs:long" minOccurs="0" maxOccurs="1"/>
<xs:element name="cors-max-age" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="auth-server-url" type="xs:string" minOccurs="1" maxOccurs="1"/>
<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="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"/>
<xs:element name="register-node-at-startup" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="register-node-period" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="token-store" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="proxy-url" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="verify-token-audience" 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 realm.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="secure-deployment-type">
<xs:all>
<xs:element name="client-keystore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="client-keystore" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="enable-cors" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="allow-any-hostname" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="use-resource-role-mappings" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="cors-max-age" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<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="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" />
<xs:element name="truststore" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="truststore-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="client-key-password" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="public-client" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="connection-pool-size" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="socket-timeout-millis" type="xs:long" minOccurs="0" maxOccurs="1"/>
<xs:element name="connection-ttl-millis" type="xs:long" minOccurs="0" maxOccurs="1"/>
<xs:element name="connection-timeout-millis" type="xs:long" minOccurs="0" maxOccurs="1"/>
<xs:element name="expose-token" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="ssl-required" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="realm-public-key" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="credential" type="credential-type" 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"/>
<xs:element name="register-node-at-startup" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="register-node-period" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="token-store" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="principal-attribute" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="enable-basic-auth" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
<xs:element name="turn-off-change-session-id-on-login" type="xs:boolean" minOccurs="0" maxOccurs="1" />
<xs:element name="token-minimum-time-to-live" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="min-time-between-jwks-requests" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="public-key-cache-ttl" type="xs:integer" minOccurs="0" maxOccurs="1"/>
<xs:element name="proxy-url" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="verify-token-audience" 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 realm.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="credential-type" mixed="true">
<xs:sequence maxOccurs="unbounded" minOccurs="0">
<xs:any processContents="lax"></xs:any>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:schema>

View file

@ -1,88 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.as7;
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.
*/
public class RealmDefinitionTestCase {
private ModelNode model;
@Before
public void setUp() {
model = new ModelNode();
model.get("realm").set("demo");
model.get("resource").set("customer-portal");
model.get("realm-public-key").set("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB");
model.get("auth-url").set("http://localhost:8080/auth-server/realms/demo/protocol/openid-connect/login");
model.get("code-url").set("http://localhost:8080/auth-server/realms/demo/protocol/openid-connect/access/codes");
model.get("expose-token").set(true);
ModelNode credential = new ModelNode();
credential.get("password").set("password");
model.get("credentials").set(credential);
}
@Test
public void testIsTruststoreSetIfRequired() throws Exception {
model.get("ssl-required").set("none");
model.get("disable-trust-manager").set(true);
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("none");
model.get("disable-trust-manager").set(false);
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(true);
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(false);
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("external");
model.get("disable-trust-manager").set(false);
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(false);
model.get("truststore").set("foo");
Assert.assertFalse(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("all");
model.get("disable-trust-manager").set(false);
model.get("truststore").set("foo");
model.get("truststore-password").set("password");
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
model.get("ssl-required").set("external");
model.get("disable-trust-manager").set(false);
model.get("truststore").set("foo");
model.get("truststore-password").set("password");
Assert.assertTrue(SharedAttributeDefinitons.validateTruststoreSetIfRequired(model));
}
}

View file

@ -1,55 +0,0 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak AS7 / JBoss EAP 6 Integration</name>
<description/>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-as7-integration-pom</artifactId>
<packaging>pom</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-parent</artifactId>
<version>${jboss.as.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>as7-adapter-spi</module>
<module>as7-adapter</module>
<module>as7-subsystem</module>
</modules>
</project>

View file

@ -48,16 +48,4 @@
<module>wildfly</module>
<module>wildfly-elytron</module>
</modules>
<profiles>
<profile>
<id>AS7</id>
<activation>
<jdk>[,9)</jdk>
</activation>
<modules>
<module>as7-eap6</module>
</modules>
</profile>
</profiles>
</project>

View file

@ -1,128 +0,0 @@
<?xml version="1.0"?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-saml-as7-adapter</artifactId>
<name>Keycloak SAML AS7 Integration</name>
<description/>
<repositories>
<!-- for org.jboss.web:jbossweb -->
<repository>
<id>jboss</id>
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-api-public</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-adapter-core</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.web</groupId>
<artifactId>jbossweb</artifactId>
<version>7.0.17.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-web</artifactId>
<version>7.1.2.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
<scope>provided</scope>
<version>5.2.20.Final</version> <!-- override version to match EAP's -->
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-cachestore-remote</artifactId>
<scope>provided</scope>
<version>5.2.20.Final</version> <!-- override version to match EAP's -->
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-tomcat-adapter-core</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View file

@ -1,82 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.adapters.saml.jbossweb;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.deploy.LoginConfig;
import org.keycloak.adapters.jbossweb.JBossWebPrincipalFactory;
import org.keycloak.adapters.saml.*;
import org.keycloak.adapters.spi.SessionIdMapperUpdater;
import org.keycloak.adapters.tomcat.PrincipalFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Keycloak authentication valve
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class SamlAuthenticatorValve extends AbstractSamlAuthenticatorValve {
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws java.io.IOException {
return authenticateInternal(request, response, config);
}
@Override
protected boolean forwardToErrorPageInternal(Request request, HttpServletResponse response, Object loginConfig) throws IOException {
if (loginConfig == null) return false;
LoginConfig config = (LoginConfig)loginConfig;
if (config.getErrorPage() == null) return false;
forwardToErrorPage(request, (Response)response, config);
return true;
}
@Override
protected void forwardToLogoutPage(Request request, HttpServletResponse response, SamlDeployment deployment) {
super.forwardToLogoutPage(request, response, deployment);
}
@Override
public void start() throws LifecycleException {
StandardContext standardContext = (StandardContext) context;
standardContext.addLifecycleListener(this);
super.start();
}
public void logout(Request request) {
logoutInternal(request);
}
@Override
protected PrincipalFactory createPrincipalFactory() {
return new JBossWebPrincipalFactory();
}
@Override
protected void addTokenStoreUpdaters() {
context.addApplicationListenerInstance(new IdMapperUpdaterSessionListener(mapper));
setIdMapperUpdater(SessionIdMapperUpdater.EXTERNAL);
super.addTokenStoreUpdaters();
}
}

View file

@ -1,121 +0,0 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.adapters.saml.jbossweb.infinispan;
import org.keycloak.adapters.saml.AdapterConstants;
import org.keycloak.adapters.spi.SessionIdMapper;
import org.keycloak.adapters.spi.SessionIdMapperUpdater;
import java.util.List;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import org.apache.catalina.Context;
import org.infinispan.Cache;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.loaders.CacheLoaderManager;
import org.infinispan.loaders.remote.RemoteCacheStore;
import org.infinispan.manager.EmbeddedCacheManager;
import org.jboss.logging.Logger;
/**
*
* @author hmlnarik
*/
public class InfinispanSessionCacheIdMapperUpdater {
private static final Logger LOG = Logger.getLogger(InfinispanSessionCacheIdMapperUpdater.class);
public static final String DEFAULT_CACHE_CONTAINER_JNDI_NAME = "java:jboss/infinispan/container";
public static SessionIdMapperUpdater addTokenStoreUpdaters(Context context, SessionIdMapper mapper, SessionIdMapperUpdater previousIdMapperUpdater) {
ServletContext servletContext = context.getServletContext();
String containerName = servletContext == null ? null : servletContext.getInitParameter(AdapterConstants.REPLICATION_CONFIG_CONTAINER_PARAM_NAME);
String cacheName = servletContext == null ? null : servletContext.getInitParameter(AdapterConstants.REPLICATION_CONFIG_SSO_CACHE_PARAM_NAME);
// the following is based on https://github.com/jbossas/jboss-as/blob/7.2.0.Final/clustering/web-infinispan/src/main/java/org/jboss/as/clustering/web/infinispan/DistributedCacheManagerFactory.java#L116-L122
String host = context.getParent() == null ? "" : context.getParent().getName();
String contextPath = context.getPath();
if ("/".equals(contextPath)) {
contextPath = "/ROOT";
}
String deploymentSessionCacheName = host + contextPath;
if (containerName == null || cacheName == null || deploymentSessionCacheName == null) {
LOG.warnv("Cannot determine parameters of SSO cache for deployment {0}.", host + contextPath);
return previousIdMapperUpdater;
}
String cacheContainerLookup = DEFAULT_CACHE_CONTAINER_JNDI_NAME + "/" + containerName;
try {
EmbeddedCacheManager cacheManager = (EmbeddedCacheManager) new InitialContext().lookup(cacheContainerLookup);
Configuration ssoCacheConfiguration = cacheManager.getCacheConfiguration(cacheName);
if (ssoCacheConfiguration == null) {
Configuration cacheConfiguration = cacheManager.getCacheConfiguration(deploymentSessionCacheName);
if (cacheConfiguration == null) {
LOG.debugv("Using default configuration for SSO cache {0}.{1}.", containerName, cacheName);
ssoCacheConfiguration = cacheManager.getDefaultCacheConfiguration();
} else {
LOG.debugv("Using distributed HTTP session cache configuration for SSO cache {0}.{1}, configuration taken from cache {2}",
containerName, cacheName, deploymentSessionCacheName);
ssoCacheConfiguration = cacheConfiguration;
cacheManager.defineConfiguration(cacheName, ssoCacheConfiguration);
}
} else {
LOG.debugv("Using custom configuration of SSO cache {0}.{1}.", containerName, cacheName);
}
CacheMode ssoCacheMode = ssoCacheConfiguration.clustering().cacheMode();
if (ssoCacheMode != CacheMode.REPL_ASYNC && ssoCacheMode != CacheMode.REPL_SYNC) {
LOG.warnv("SSO cache mode is {0}, it is recommended to use replicated mode instead.", ssoCacheConfiguration.clustering().cacheModeString());
}
Cache<String, String[]> ssoCache = cacheManager.getCache(cacheName, true);
final SsoSessionCacheListener listener = new SsoSessionCacheListener(ssoCache, mapper);
ssoCache.addListener(listener);
// Not possible to add listener for cross-DC support because of too old Infinispan in AS 7
warnIfRemoteStoreIsUsed(ssoCache);
LOG.debugv("Added distributed SSO session cache, lookup={0}, cache name={1}", cacheContainerLookup, cacheName);
SsoCacheSessionIdMapperUpdater updater = new SsoCacheSessionIdMapperUpdater(ssoCache, previousIdMapperUpdater);
return updater;
} catch (NamingException ex) {
LOG.warnv("Failed to obtain distributed session cache container, lookup={0}", cacheContainerLookup);
return previousIdMapperUpdater;
}
}
private static void warnIfRemoteStoreIsUsed(Cache<String, String[]> ssoCache) {
final List<RemoteCacheStore> stores = getRemoteStores(ssoCache);
if (stores == null || stores.isEmpty()) {
return;
}
LOG.warnv("Unable to listen for events on remote stores configured for cache {0} (unsupported in this Infinispan limitations), logouts will not be propagated.", ssoCache.getName());
}
public static List<RemoteCacheStore> getRemoteStores(Cache ssoCache) {
return ssoCache.getAdvancedCache().getComponentRegistry().getComponent(CacheLoaderManager.class).getCacheLoaders(RemoteCacheStore.class);
}
}

View file

@ -1,70 +0,0 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.adapters.saml.jbossweb.infinispan;
import org.keycloak.adapters.spi.SessionIdMapper;
import org.keycloak.adapters.spi.SessionIdMapperUpdater;
import org.infinispan.Cache;
/**
*
* @author hmlnarik
*/
public class SsoCacheSessionIdMapperUpdater implements SessionIdMapperUpdater {
private final SessionIdMapperUpdater delegate;
/**
* Cache where key is a HTTP session ID, and value is a pair (user session ID, principal name) of Strings.
*/
private final Cache<String, String[]> httpSessionToSsoCache;
public SsoCacheSessionIdMapperUpdater(Cache<String, String[]> httpSessionToSsoCache, SessionIdMapperUpdater previousIdMapperUpdater) {
this.delegate = previousIdMapperUpdater;
this.httpSessionToSsoCache = httpSessionToSsoCache;
}
// SessionIdMapperUpdater methods
@Override
public void clear(SessionIdMapper idMapper) {
httpSessionToSsoCache.clear();
this.delegate.clear(idMapper);
}
@Override
public boolean refreshMapping(SessionIdMapper idMapper, String httpSessionId) {
String[] ssoAndPrincipal = httpSessionToSsoCache.get(httpSessionId);
if (ssoAndPrincipal != null) {
this.delegate.map(idMapper, ssoAndPrincipal[0], ssoAndPrincipal[1], httpSessionId);
return true;
}
return false;
}
@Override
public void map(SessionIdMapper idMapper, String sso, String principal, String httpSessionId) {
httpSessionToSsoCache.put(httpSessionId, new String[] {sso, principal});
this.delegate.map(idMapper, sso, principal, httpSessionId);
}
@Override
public void removeSession(SessionIdMapper idMapper, String httpSessionId) {
httpSessionToSsoCache.remove(httpSessionId);
this.delegate.removeSession(idMapper, httpSessionId);
}
}

View file

@ -1,175 +0,0 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.adapters.saml.jbossweb.infinispan;
import org.keycloak.adapters.spi.SessionIdMapper;
import java.util.*;
import java.util.concurrent.*;
import org.infinispan.Cache;
import org.infinispan.notifications.Listener;
import org.infinispan.notifications.cachelistener.annotation.*;
import org.infinispan.notifications.cachelistener.event.*;
import org.infinispan.notifications.cachemanagerlistener.annotation.CacheStarted;
import org.infinispan.notifications.cachemanagerlistener.annotation.CacheStopped;
import org.infinispan.notifications.cachemanagerlistener.event.CacheStartedEvent;
import org.infinispan.notifications.cachemanagerlistener.event.CacheStoppedEvent;
import org.infinispan.transaction.xa.GlobalTransaction;
import org.jboss.logging.Logger;
/**
*
* @author hmlnarik
*/
@Listener
public class SsoSessionCacheListener {
private static final Logger LOG = Logger.getLogger(SsoSessionCacheListener.class);
private final ConcurrentMap<GlobalTransaction, Queue<Event>> map = new ConcurrentHashMap<>();
private final SessionIdMapper idMapper;
private final Cache<String, String[]> ssoCache;
private ExecutorService executor = Executors.newSingleThreadExecutor();
public SsoSessionCacheListener(Cache<String, String[]> ssoCache, SessionIdMapper idMapper) {
this.ssoCache = ssoCache;
this.idMapper = idMapper;
}
@TransactionRegistered
public void startTransaction(TransactionRegisteredEvent event) {
map.put(event.getGlobalTransaction(), new ConcurrentLinkedQueue<Event>());
}
@CacheStarted
public void cacheStarted(CacheStartedEvent event) {
this.executor = Executors.newSingleThreadExecutor();
}
@CacheStopped
public void cacheStopped(CacheStoppedEvent event) {
this.executor.shutdownNow();
}
@CacheEntryCreated
@CacheEntryRemoved
@CacheEntryModified
public void addEvent(TransactionalEvent event) {
if (event.getGlobalTransaction() != null) {
map.get(event.getGlobalTransaction()).add(event);
} else {
processEvent(event);
}
}
@TransactionCompleted
public void endTransaction(TransactionCompletedEvent event) {
Queue<Event> events = map.remove(event.getGlobalTransaction());
if (events == null || ! event.isTransactionSuccessful()) {
return;
}
if (event.isOriginLocal()) {
// Local events are processed by local HTTP session listener
return;
}
for (final Event e : events) {
processEvent(e);
}
}
private void processEvent(final Event e) {
switch (e.getType()) {
case CACHE_ENTRY_CREATED:
this.executor.submit(new Runnable() {
@Override public void run() {
cacheEntryCreated((CacheEntryCreatedEvent) e);
}
});
break;
case CACHE_ENTRY_MODIFIED:
this.executor.submit(new Runnable() {
@Override public void run() {
cacheEntryModified((CacheEntryModifiedEvent) e);
}
});
break;
case CACHE_ENTRY_REMOVED:
this.executor.submit(new Runnable() {
@Override public void run() {
cacheEntryRemoved((CacheEntryRemovedEvent) e);
}
});
break;
}
}
private void cacheEntryCreated(CacheEntryCreatedEvent event) {
if (! (event.getKey() instanceof String)) {
return;
}
String httpSessionId = (String) event.getKey();
if (idMapper.hasSession(httpSessionId)) {
// Ignore local events generated by remote store
LOG.tracev("IGNORING cacheEntryCreated {0}", httpSessionId);
return;
}
String[] value = ssoCache.get((String) httpSessionId);
String ssoId = value[0];
String principal = value[1];
LOG.tracev("cacheEntryCreated {0}:{1}", httpSessionId, ssoId);
this.idMapper.map(ssoId, principal, httpSessionId);
}
private void cacheEntryModified(CacheEntryModifiedEvent event) {
if (! (event.getKey() instanceof String) || ! (event.getValue() instanceof String[])) {
return;
}
String httpSessionId = (String) event.getKey();
String[] value = (String[]) event.getValue();
String ssoId = value[0];
String principal = value[1];
LOG.tracev("cacheEntryModified {0}:{1}", httpSessionId, ssoId);
this.idMapper.removeSession(httpSessionId);
this.idMapper.map(ssoId, principal, httpSessionId);
}
private void cacheEntryRemoved(CacheEntryRemovedEvent event) {
if (! (event.getKey() instanceof String)) {
return;
}
LOG.tracev("cacheEntryRemoved {0}", event.getKey());
this.idMapper.removeSession((String) event.getKey());
}
}

View file

@ -1,54 +0,0 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<name>Keycloak SAML EAP Integration</name>
<description/>
<modelVersion>4.0.0</modelVersion>
<artifactId>keycloak-saml-eap-integration-pom</artifactId>
<packaging>pom</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-parent</artifactId>
<version>${jboss.as.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>adapter</module>
<module>subsystem</module>
</modules>
</project>

View file

@ -1,164 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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-saml-eap-integration-pom</artifactId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>keycloak-saml-as7-subsystem</artifactId>
<name>Keycloak SAML AS7 Subsystem</name>
<description/>
<packaging>jar</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<redirectTestOutputToFile>false</redirectTestOutputToFile>
<enableAssertions>true</enableAssertions>
<argLine>-Xmx512m</argLine>
<systemProperties>
<property>
<name>jboss.home</name>
<value>${jboss.home}</value>
</property>
</systemProperties>
<includes>
<include>**/*TestCase.java</include>
</includes>
<forkMode>once</forkMode>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-saml-as7-adapter</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-naming</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-server</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-ee</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-web</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<!-- Needed for jboss-logging-processor-->
<version>3.3.2.Final</version>
</dependency>
<!-- Do not ever delete this dependency. It's needed for eap6 adapter build in PNC.-->
<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>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-controller</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>community</id>
<activation>
<property>
<name>!product</name>
</property>
</activation>
<dependencies>
<!-- Upstream version 7.2.0.Final is type jar see KEYCLOAK-11527 -->
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-subsystem-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>product</id>
<activation>
<property>
<name>product</name>
</property>
</activation>
<repositories>
<repository>
<id>redhat-ga</id>
<url>https://maven.repository.redhat.com/ga/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<!-- Downstream version 7.5.*.Final is type pom see KEYCLOAK-11527 -->
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-subsystem-test</artifactId>
<version>${jboss.as.subsystem.test.version}</version>
<type>pom</type>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View file

@ -1,50 +0,0 @@
/*
* Copyright 2019 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.operations.validation.EnumValidator;
import org.jboss.as.controller.operations.validation.IntRangeValidator;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
/**
*
* @author rmartinc
*/
abstract public class AllowedClockSkew {
static final SimpleAttributeDefinition ALLOWED_CLOCK_SKEW_VALUE =
new SimpleAttributeDefinitionBuilder(Constants.Model.ALLOWED_CLOCK_SKEW_VALUE, ModelType.INT, false)
.setXmlName(Constants.XML.ALLOWED_CLOCK_SKEW)
.setAllowExpression(true)
.setValidator(new IntRangeValidator(1, Integer.MAX_VALUE, true, true))
.build();
static private enum AllowedClockSkewUnits {MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS};
static final SimpleAttributeDefinition ALLOWED_CLOCK_SKEW_UNIT =
new SimpleAttributeDefinitionBuilder(Constants.Model.ALLOWED_CLOCK_SKEW_UNIT, ModelType.STRING, true)
.setXmlName(Constants.XML.ALLOWED_CLOCK_SKEW_UNIT)
.setAllowExpression(true)
.setDefaultValue(new ModelNode(AllowedClockSkewUnits.SECONDS.name()))
.setValidator(EnumValidator.create(AllowedClockSkewUnits.class, true, true))
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {ALLOWED_CLOCK_SKEW_UNIT, ALLOWED_CLOCK_SKEW_VALUE};
}

View file

@ -1,94 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import java.util.List;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.web.deployment.WarMetaData;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
public class Configuration {
static final Configuration INSTANCE = new Configuration();
private ModelNode config = new ModelNode();
private Configuration() {
}
void updateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
this.updateModel(operation, model, false);
}
void updateModel(final ModelNode operation, final ModelNode model, final boolean checkSingleton) throws OperationFailedException {
ModelNode node = config;
final List<Property> addressNodes = operation.get("address").asPropertyList();
final int lastIndex = addressNodes.size() - 1;
for (int i = 0; i < addressNodes.size(); i++) {
Property addressNode = addressNodes.get(i);
// if checkSingleton is true, we verify if the key for the last element (e.g. SP or IDP) in the address path is already defined
if (i == lastIndex && checkSingleton) {
if (node.get(addressNode.getName()).isDefined()) {
// found an existing resource, throw an exception
throw new OperationFailedException("Duplicate resource: " + addressNode.getName());
}
}
node = node.get(addressNode.getName()).get(addressNode.getValue().asString());
}
node.set(model);
}
public ModelNode getSecureDeployment(DeploymentUnit deploymentUnit) {
String name = preferredDeploymentName(deploymentUnit);
ModelNode secureDeployment = config.get("subsystem").get("keycloak-saml").get(Constants.Model.SECURE_DEPLOYMENT);
if (secureDeployment.hasDefined(name)) {
return secureDeployment.get(name);
}
return null;
}
public boolean isSecureDeployment(DeploymentUnit deploymentUnit) {
return getSecureDeployment(deploymentUnit) != null;
}
// KEYCLOAK-3273: prefer module name if available
private String preferredDeploymentName(DeploymentUnit deploymentUnit) {
String deploymentName = deploymentUnit.getName();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return deploymentName;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
return deploymentName;
}
String moduleName = webMetaData.getModuleName();
if (moduleName != null) return moduleName + ".war";
return deploymentName;
}
}

View file

@ -1,180 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
public class Constants {
static class Model {
static final String SECURE_DEPLOYMENT = "secure-deployment";
static final String SERVICE_PROVIDER = "SP";
static final String SSL_POLICY = "sslPolicy";
static final String NAME_ID_POLICY_FORMAT = "nameIDPolicyFormat";
static final String LOGOUT_PAGE = "logoutPage";
static final String FORCE_AUTHENTICATION = "forceAuthentication";
static final String KEEP_DOM_ASSERTION = "keepDOMAssertion";
static final String IS_PASSIVE = "isPassive";
static final String TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN = "turnOffChangeSessionIdOnLogin";
static final String AUTODETECT_BEARER_ONLY = "autodetectBearerOnly";
static final String ROLE_ATTRIBUTES = "RoleIdentifiers";
static final String SIGNING = "signing";
static final String ENCRYPTION = "encryption";
static final String KEY = "Key";
static final String RESOURCE = "resource";
static final String PASSWORD = "password";
static final String PRIVATE_KEY_ALIAS = "PrivateKey-alias";
static final String PRIVATE_KEY_PASSWORD = "PrivateKey-password";
static final String CERTIFICATE_ALIAS = "Certificate-alias";
static final String KEY_STORE = "KeyStore";
static final String SIGN_REQUEST = "signRequest";
static final String VALIDATE_RESPONSE_SIGNATURE = "validateResponseSignature";
static final String VALIDATE_ASSERTION_SIGNATURE = "validateAssertionSignature";
static final String ASSERTION_CONSUMER_SERVICE_URL = "assertionConsumerServiceUrl";
static final String REQUEST_BINDING = "requestBinding";
static final String BINDING_URL = "bindingUrl";
static final String VALIDATE_REQUEST_SIGNATURE = "validateRequestSignature";
static final String SIGN_RESPONSE = "signResponse";
static final String RESPONSE_BINDING = "responseBinding";
static final String POST_BINDING_URL = "postBindingUrl";
static final String REDIRECT_BINDING_URL = "redirectBindingUrl";
static final String SINGLE_SIGN_ON = "SingleSignOnService";
static final String SINGLE_LOGOUT = "SingleLogoutService";
static final String IDENTITY_PROVIDER = "IDP";
static final String PRINCIPAL_NAME_MAPPING_POLICY = "PrincipalNameMapping-policy";
static final String PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME = "PrincipalNameMapping-attribute-name";
static final String SIGNATURE_ALGORITHM = "signatureAlgorithm";
static final String SIGNATURE_CANONICALIZATION_METHOD = "signatureCanonicalizationMethod";
static final String METADATA_URL = "metadataUrl";
static final String PRIVATE_KEY_PEM = "PrivateKeyPem";
static final String PUBLIC_KEY_PEM = "PublicKeyPem";
static final String CERTIFICATE_PEM = "CertificatePem";
static final String TYPE = "type";
static final String ALIAS = "alias";
static final String FILE = "file";
static final String SIGNATURES_REQUIRED = "signaturesRequired";
// role mappings provider model constants.
static final String ROLE_MAPPINGS_PROVIDER_ID = "roleMappingsProviderId";
static final String ROLE_MAPPINGS_PROVIDER_CONFIG = "roleMappingsProviderConfig";
// allowed clock skew model constants
static final String ALLOWED_CLOCK_SKEW = "AllowedClockSkew";
static final String ALLOWED_CLOCK_SKEW_UNIT = "unit";
static final String ALLOWED_CLOCK_SKEW_VALUE = "value";
// http client model constants
static final String HTTP_CLIENT = "HttpClient";
static final String ALLOW_ANY_HOSTNAME = "allowAnyHostname";
static final String CLIENT_KEYSTORE = "clientKeystore";
static final String CLIENT_KEYSTORE_PASSWORD = "clientKeystorePassword";
static final String CONNECTION_POOL_SIZE = "connectionPoolSize";
static final String DISABLE_TRUST_MANAGER = "disableTrustManager";
static final String PROXY_URL = "proxyUrl";
static final String TRUSTSTORE = "truststore";
static final String TRUSTSTORE_PASSWORD = "truststorePassword";
static final String SOCKET_TIMEOUT = "socketTimeout";
static final String CONNECTION_TIMEOUT = "connectionTimeout";
static final String CONNECTION_TTL = "connectionTtl";
}
static class XML {
static final String SECURE_DEPLOYMENT = "secure-deployment";
static final String SERVICE_PROVIDER = "SP";
static final String NAME = "name";
static final String ENTITY_ID = "entityID";
static final String SSL_POLICY = "sslPolicy";
static final String NAME_ID_POLICY_FORMAT = "nameIDPolicyFormat";
static final String LOGOUT_PAGE = "logoutPage";
static final String FORCE_AUTHENTICATION = "forceAuthentication";
static final String KEEP_DOM_ASSERTION = "keepDOMAssertion";
static final String ROLE_IDENTIFIERS = "RoleIdentifiers";
static final String SIGNING = "signing";
static final String ENCRYPTION = "encryption";
static final String KEYS = "Keys";
static final String KEY = "Key";
static final String RESOURCE = "resource";
static final String PASSWORD = "password";
static final String KEY_STORE = "KeyStore";
static final String PRIVATE_KEY = "PrivateKey";
static final String CERTIFICATE = "Certificate";
static final String IS_PASSIVE = "isPassive";
static final String TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN = "turnOffChangeSessionIdOnLogin";
static final String AUTODETECT_BEARER_ONLY = "autodetectBearerOnly";
static final String PRIVATE_KEY_ALIAS = "alias";
static final String PRIVATE_KEY_PASSWORD = "password";
static final String CERTIFICATE_ALIAS = "alias";
static final String SIGN_REQUEST = "signRequest";
static final String VALIDATE_RESPONSE_SIGNATURE = "validateResponseSignature";
static final String VALIDATE_ASSERTION_SIGNATURE = "validateAssertionSignature";
static final String REQUEST_BINDING = "requestBinding";
static final String BINDING_URL = "bindingUrl";
static final String VALIDATE_REQUEST_SIGNATURE = "validateRequestSignature";
static final String SIGN_RESPONSE = "signResponse";
static final String RESPONSE_BINDING = "responseBinding";
static final String POST_BINDING_URL = "postBindingUrl";
static final String REDIRECT_BINDING_URL = "redirectBindingUrl";
static final String SINGLE_SIGN_ON = "SingleSignOnService";
static final String SINGLE_LOGOUT = "SingleLogoutService";
static final String IDENTITY_PROVIDER = "IDP";
static final String PRINCIPAL_NAME_MAPPING = "PrincipalNameMapping";
static final String PRINCIPAL_NAME_MAPPING_POLICY = "policy";
static final String PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME = "attribute";
static final String ATTRIBUTE = "Attribute";
static final String SIGNATURE_ALGORITHM = "signatureAlgorithm";
static final String SIGNATURE_CANONICALIZATION_METHOD = "signatureCanonicalizationMethod";
static final String METADATA_URL = "metadataUrl";
static final String PRIVATE_KEY_PEM = "PrivateKeyPem";
static final String PUBLIC_KEY_PEM = "PublicKeyPem";
static final String CERTIFICATE_PEM = "CertificatePem";
static final String TYPE = "type";
static final String ALIAS = "alias";
static final String FILE = "file";
static final String SIGNATURES_REQUIRED = "signaturesRequired";
static final String ASSERTION_CONSUMER_SERVICE_URL = "assertionConsumerServiceUrl";
// role mappings provider XML constants
static final String ID = "id";
static final String VALUE = "value";
static final String PROPERTY = "Property";
static final String ROLE_MAPPINGS_PROVIDER = "RoleMappingsProvider";
// allowed clock skew XML constants
static final String ALLOWED_CLOCK_SKEW = "AllowedClockSkew";
static final String ALLOWED_CLOCK_SKEW_UNIT = "unit";
// http client XML constants
static final String HTTP_CLIENT = "HttpClient";
static final String ALLOW_ANY_HOSTNAME = "allowAnyHostname";
static final String CLIENT_KEYSTORE = "clientKeystore";
static final String CLIENT_KEYSTORE_PASSWORD = "clientKeystorePassword";
static final String CONNECTION_POOL_SIZE = "connectionPoolSize";
static final String DISABLE_TRUST_MANAGER = "disableTrustManager";
static final String PROXY_URL = "proxyUrl";
static final String TRUSTSTORE = "truststore";
static final String TRUSTSTORE_PASSWORD = "truststorePassword";
static final String SOCKET_TIMEOUT = "socketTimeout";
static final String CONNECTION_TIMEOUT = "connectionTimeout";
static final String CONNECTION_TTL = "connectionTtl";
}
}

View file

@ -1,113 +0,0 @@
/*
* Copyright 2020 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import java.util.HashMap;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.dmr.ModelType;
/**
* This class contains the definitions for the {@code HttpClient} attributes, as specified in the schema's {@code http-client-type}
* complex type.
*
* @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
*/
abstract class HttpClientDefinition {
private static final SimpleAttributeDefinition ALLOW_ANY_HOSTNAME =
new SimpleAttributeDefinitionBuilder(Constants.Model.ALLOW_ANY_HOSTNAME, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.ALLOW_ANY_HOSTNAME)
.setAllowExpression(true)
.build();
private static final SimpleAttributeDefinition CLIENT_KEYSTORE =
new SimpleAttributeDefinitionBuilder(Constants.Model.CLIENT_KEYSTORE, ModelType.STRING, true)
.setXmlName(Constants.XML.CLIENT_KEYSTORE)
.setAllowExpression(true)
.build();
private static final SimpleAttributeDefinition CLIENT_KEYSTORE_PASSWORD =
new SimpleAttributeDefinitionBuilder(Constants.Model.CLIENT_KEYSTORE_PASSWORD, ModelType.STRING, true)
.setXmlName(Constants.XML.CLIENT_KEYSTORE_PASSWORD)
.setAllowExpression(true)
.build();
private static final SimpleAttributeDefinition CONNECTION_POOL_SIZE =
new SimpleAttributeDefinitionBuilder(Constants.Model.CONNECTION_POOL_SIZE, ModelType.INT, true)
.setXmlName(Constants.XML.CONNECTION_POOL_SIZE)
.setAllowExpression(true)
.build();
private static final SimpleAttributeDefinition DISABLE_TRUST_MANAGER =
new SimpleAttributeDefinitionBuilder(Constants.Model.DISABLE_TRUST_MANAGER, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.DISABLE_TRUST_MANAGER)
.setAllowExpression(true)
.build();
private static final SimpleAttributeDefinition PROXY_URL =
new SimpleAttributeDefinitionBuilder(Constants.Model.PROXY_URL, ModelType.STRING, true)
.setXmlName(Constants.XML.PROXY_URL)
.setAllowExpression(true)
.build();
private static final SimpleAttributeDefinition TRUSTSTORE =
new SimpleAttributeDefinitionBuilder(Constants.Model.TRUSTSTORE, ModelType.STRING, true)
.setXmlName(Constants.XML.TRUSTSTORE)
.setAllowExpression(true)
.build();
private static final SimpleAttributeDefinition TRUSTSTORE_PASSWORD =
new SimpleAttributeDefinitionBuilder(Constants.Model.TRUSTSTORE_PASSWORD, ModelType.STRING, true)
.setXmlName(Constants.XML.TRUSTSTORE_PASSWORD)
.setAllowExpression(true)
.build();
private static final SimpleAttributeDefinition SOCKET_TIMEOUT =
new SimpleAttributeDefinitionBuilder(Constants.Model.SOCKET_TIMEOUT, ModelType.LONG, true)
.setXmlName(Constants.XML.SOCKET_TIMEOUT)
.setAllowExpression(true)
.build();
private static final SimpleAttributeDefinition CONNECTION_TIMEOUT =
new SimpleAttributeDefinitionBuilder(Constants.Model.CONNECTION_TIMEOUT, ModelType.LONG, true)
.setXmlName(Constants.XML.CONNECTION_TIMEOUT)
.setAllowExpression(true)
.build();
private static final SimpleAttributeDefinition CONNECTION_TTL =
new SimpleAttributeDefinitionBuilder(Constants.Model.CONNECTION_TTL, ModelType.LONG, true)
.setXmlName(Constants.XML.CONNECTION_TTL)
.setAllowExpression(true)
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {ALLOW_ANY_HOSTNAME, CLIENT_KEYSTORE, CLIENT_KEYSTORE_PASSWORD,
CONNECTION_POOL_SIZE, DISABLE_TRUST_MANAGER, PROXY_URL, TRUSTSTORE, TRUSTSTORE_PASSWORD, SOCKET_TIMEOUT, CONNECTION_TIMEOUT, CONNECTION_TTL};
private static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
static {
for (SimpleAttributeDefinition def : ATTRIBUTES) {
ATTRIBUTE_MAP.put(def.getXmlName(), def);
}
}
static SimpleAttributeDefinition lookup(String xmlName) {
return ATTRIBUTE_MAP.get(xmlName);
}
}

View file

@ -1,48 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
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;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
class IdentityProviderAddHandler extends AbstractAddStepHandler {
IdentityProviderAddHandler() {
}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
Configuration.INSTANCE.updateModel(operation, model, true);
}
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
for (AttributeDefinition attr : IdentityProviderDefinition.ALL_ATTRIBUTES) {
attr.validateAndSet(operation, model);
}
}
}

View file

@ -1,125 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.ObjectTypeAttributeDefinition;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
import org.jboss.as.controller.ReloadRequiredWriteAttributeHandler;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.dmr.ModelType;
import java.util.HashMap;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
public class IdentityProviderDefinition extends SimpleResourceDefinition {
private static final SimpleAttributeDefinition SIGNATURES_REQUIRED =
new SimpleAttributeDefinitionBuilder(Constants.Model.SIGNATURES_REQUIRED, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.SIGNATURES_REQUIRED)
.build();
private static final SimpleAttributeDefinition SIGNATURE_ALGORITHM =
new SimpleAttributeDefinitionBuilder(Constants.Model.SIGNATURE_ALGORITHM, ModelType.STRING, true)
.setXmlName(Constants.XML.SIGNATURE_ALGORITHM)
.build();
private static final SimpleAttributeDefinition SIGNATURE_CANONICALIZATION_METHOD =
new SimpleAttributeDefinitionBuilder(Constants.Model.SIGNATURE_CANONICALIZATION_METHOD, ModelType.STRING, true)
.setXmlName(Constants.XML.SIGNATURE_CANONICALIZATION_METHOD)
.build();
private static final SimpleAttributeDefinition METADATA_URL =
new SimpleAttributeDefinitionBuilder(Constants.Model.METADATA_URL, ModelType.STRING, true)
.setXmlName(Constants.XML.METADATA_URL)
.setAllowExpression(true)
.build();
private static final ObjectTypeAttributeDefinition SINGLE_SIGN_ON =
ObjectTypeAttributeDefinition.Builder.of(Constants.Model.SINGLE_SIGN_ON,
SingleSignOnDefinition.ATTRIBUTES)
.setAllowNull(false)
.build();
private static final ObjectTypeAttributeDefinition SINGLE_LOGOUT =
ObjectTypeAttributeDefinition.Builder.of(Constants.Model.SINGLE_LOGOUT,
SingleLogoutDefinition.ATTRIBUTES)
.setAllowNull(false)
.build();
private static final ObjectTypeAttributeDefinition ALLOWED_CLOCK_SKEW =
ObjectTypeAttributeDefinition.Builder.of(Constants.Model.ALLOWED_CLOCK_SKEW,
AllowedClockSkew.ATTRIBUTES)
.setAllowNull(true)
.build();
private static final ObjectTypeAttributeDefinition HTTP_CLIENT =
ObjectTypeAttributeDefinition.Builder.of(Constants.Model.HTTP_CLIENT,
HttpClientDefinition.ATTRIBUTES)
.setAllowNull(true)
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {SIGNATURES_REQUIRED, SIGNATURE_ALGORITHM, SIGNATURE_CANONICALIZATION_METHOD, METADATA_URL};
static final SimpleAttributeDefinition[] ALL_ATTRIBUTES = {SIGNATURES_REQUIRED, SIGNATURE_ALGORITHM, SIGNATURE_CANONICALIZATION_METHOD, METADATA_URL,
SINGLE_SIGN_ON, SINGLE_LOGOUT, ALLOWED_CLOCK_SKEW, HTTP_CLIENT};
private static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
static {
for (SimpleAttributeDefinition def : ALL_ATTRIBUTES) {
ATTRIBUTE_MAP.put(def.getXmlName(), def);
}
}
static final IdentityProviderDefinition INSTANCE = new IdentityProviderDefinition();
private IdentityProviderDefinition() {
super(PathElement.pathElement(Constants.Model.IDENTITY_PROVIDER),
KeycloakSamlExtension.getResourceDescriptionResolver(Constants.Model.IDENTITY_PROVIDER),
new IdentityProviderAddHandler(),
ReloadRequiredRemoveStepHandler.INSTANCE);
}
@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);
resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
}
@Override
public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
super.registerAttributes(resourceRegistration);
final OperationStepHandler writeHandler = new ReloadRequiredWriteAttributeHandler(ALL_ATTRIBUTES);
for (AttributeDefinition attribute : ALL_ATTRIBUTES) {
resourceRegistration.registerReadWriteAttribute(attribute, null, writeHandler);
}
}
static SimpleAttributeDefinition lookup(String xmlName) {
return ATTRIBUTE_MAP.get(xmlName);
}
}

View file

@ -1,48 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
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;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
class KeyAddHandler extends AbstractAddStepHandler {
KeyAddHandler() {
}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
Configuration.INSTANCE.updateModel(operation, model);
}
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
for (AttributeDefinition attr : KeyDefinition.ALL_ATTRIBUTES) {
attr.validateAndSet(operation, model);
}
}
}

View file

@ -1,121 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.ObjectTypeAttributeDefinition;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
import org.jboss.as.controller.ReloadRequiredWriteAttributeHandler;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.dmr.ModelType;
import java.util.HashMap;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
public class KeyDefinition extends SimpleResourceDefinition {
static final SimpleAttributeDefinition SIGNING =
new SimpleAttributeDefinitionBuilder(Constants.Model.SIGNING, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.SIGNING)
.build();
static final SimpleAttributeDefinition ENCRYPTION =
new SimpleAttributeDefinitionBuilder(Constants.Model.ENCRYPTION, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.ENCRYPTION)
.build();
static final SimpleAttributeDefinition PRIVATE_KEY_PEM =
new SimpleAttributeDefinitionBuilder(Constants.Model.PRIVATE_KEY_PEM, ModelType.STRING, true)
.setXmlName(Constants.XML.PRIVATE_KEY_PEM)
.build();
static final SimpleAttributeDefinition PUBLIC_KEY_PEM =
new SimpleAttributeDefinitionBuilder(Constants.Model.PUBLIC_KEY_PEM, ModelType.STRING, true)
.setXmlName(Constants.XML.PUBLIC_KEY_PEM)
.build();
static final SimpleAttributeDefinition CERTIFICATE_PEM =
new SimpleAttributeDefinitionBuilder(Constants.Model.CERTIFICATE_PEM, ModelType.STRING, true)
.setXmlName(Constants.XML.CERTIFICATE_PEM)
.build();
static final ObjectTypeAttributeDefinition KEY_STORE =
ObjectTypeAttributeDefinition.Builder.of(Constants.Model.KEY_STORE,
KeyStoreDefinition.ALL_ATTRIBUTES)
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {SIGNING, ENCRYPTION};
static final SimpleAttributeDefinition[] ELEMENTS = {PRIVATE_KEY_PEM, PUBLIC_KEY_PEM, CERTIFICATE_PEM};
static final AttributeDefinition[] ALL_ATTRIBUTES = {SIGNING, ENCRYPTION, PRIVATE_KEY_PEM, PUBLIC_KEY_PEM, CERTIFICATE_PEM, KEY_STORE};
static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
static {
for (SimpleAttributeDefinition def : ATTRIBUTES) {
ATTRIBUTE_MAP.put(def.getXmlName(), def);
}
}
static final HashMap<String, SimpleAttributeDefinition> ELEMENT_MAP = new HashMap<>();
static {
for (SimpleAttributeDefinition def : ELEMENTS) {
ELEMENT_MAP.put(def.getXmlName(), def);
}
}
static final KeyDefinition INSTANCE = new KeyDefinition();
private KeyDefinition() {
super(PathElement.pathElement(Constants.Model.KEY),
KeycloakSamlExtension.getResourceDescriptionResolver(Constants.Model.KEY),
new KeyAddHandler(),
ReloadRequiredRemoveStepHandler.INSTANCE);
}
@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);
resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
}
@Override
public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
super.registerAttributes(resourceRegistration);
final OperationStepHandler writeHandler = new ReloadRequiredWriteAttributeHandler(ALL_ATTRIBUTES);
for (AttributeDefinition attribute : ALL_ATTRIBUTES) {
resourceRegistration.registerReadWriteAttribute(attribute, null, writeHandler);
}
}
static SimpleAttributeDefinition lookup(String xmlName) {
return ATTRIBUTE_MAP.get(xmlName);
}
static SimpleAttributeDefinition lookupElement(String xmlName) {
return ELEMENT_MAP.get(xmlName);
}
}

View file

@ -1,36 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.dmr.ModelType;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
public class KeyStoreCertificateDefinition {
static final SimpleAttributeDefinition CERTIFICATE_ALIAS =
new SimpleAttributeDefinitionBuilder(Constants.Model.CERTIFICATE_ALIAS, ModelType.STRING, true)
.setXmlName(Constants.XML.CERTIFICATE_ALIAS)
.build();
static SimpleAttributeDefinition lookup(String xmlName) {
return Constants.XML.CERTIFICATE_ALIAS.equals(xmlName) ? CERTIFICATE_ALIAS : null;
}
}

View file

@ -1,73 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.dmr.ModelType;
import java.util.HashMap;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
abstract class KeyStoreDefinition {
static final SimpleAttributeDefinition RESOURCE =
new SimpleAttributeDefinitionBuilder(Constants.Model.RESOURCE, ModelType.STRING, true)
.setXmlName(Constants.XML.RESOURCE)
.build();
static final SimpleAttributeDefinition PASSWORD =
new SimpleAttributeDefinitionBuilder(Constants.Model.PASSWORD, ModelType.STRING, true)
.setXmlName(Constants.XML.PASSWORD)
.build();
static final SimpleAttributeDefinition FILE =
new SimpleAttributeDefinitionBuilder(Constants.Model.FILE, ModelType.STRING, true)
.setXmlName(Constants.XML.FILE)
.build();
static final SimpleAttributeDefinition TYPE =
new SimpleAttributeDefinitionBuilder(Constants.Model.TYPE, ModelType.STRING, true)
.setXmlName(Constants.XML.TYPE)
.build();
static final SimpleAttributeDefinition ALIAS =
new SimpleAttributeDefinitionBuilder(Constants.Model.ALIAS, ModelType.STRING, true)
.setXmlName(Constants.XML.ALIAS)
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {RESOURCE, PASSWORD, FILE, TYPE, ALIAS};
static final SimpleAttributeDefinition[] ALL_ATTRIBUTES = {RESOURCE, PASSWORD, FILE, TYPE, ALIAS,
KeyStorePrivateKeyDefinition.PRIVATE_KEY_ALIAS,
KeyStorePrivateKeyDefinition.PRIVATE_KEY_PASSWORD,
KeyStoreCertificateDefinition.CERTIFICATE_ALIAS
};
static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
static {
for (SimpleAttributeDefinition def : ATTRIBUTES) {
ATTRIBUTE_MAP.put(def.getXmlName(), def);
}
}
static SimpleAttributeDefinition lookup(String xmlName) {
return ATTRIBUTE_MAP.get(xmlName);
}
}

View file

@ -1,52 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.dmr.ModelType;
import java.util.HashMap;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
public class KeyStorePrivateKeyDefinition {
static final SimpleAttributeDefinition PRIVATE_KEY_ALIAS =
new SimpleAttributeDefinitionBuilder(Constants.Model.PRIVATE_KEY_ALIAS, ModelType.STRING, true)
.setXmlName(Constants.XML.PRIVATE_KEY_ALIAS)
.build();
static final SimpleAttributeDefinition PRIVATE_KEY_PASSWORD =
new SimpleAttributeDefinitionBuilder(Constants.Model.PRIVATE_KEY_PASSWORD, ModelType.STRING, true)
.setXmlName(Constants.XML.PRIVATE_KEY_PASSWORD)
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {PRIVATE_KEY_ALIAS, PRIVATE_KEY_PASSWORD};
static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
static {
for (SimpleAttributeDefinition def : ATTRIBUTES) {
ATTRIBUTE_MAP.put(def.getXmlName(), def);
}
}
static SimpleAttributeDefinition lookup(String xmlName) {
return ATTRIBUTE_MAP.get(xmlName);
}
}

View file

@ -1,148 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
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.dmr.ModelNode;
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.jboss.staxmapper.XMLExtendedStreamWriter;
import org.keycloak.adapters.saml.AdapterConstants;
import org.keycloak.adapters.saml.jbossweb.SamlAuthenticatorValve;
import org.keycloak.subsystem.saml.as7.logging.KeycloakLogger;
import org.keycloak.subsystem.saml.as7.xml.FormattingXMLStreamWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
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.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2014 Red Hat Inc.
*/
public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitProcessor {
protected Logger log = Logger.getLogger(KeycloakAdapterConfigDeploymentProcessor.class);
@Override
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
webMetaData = new JBossWebMetaData();
warMetaData.setMergedJBossWebMetaData(webMetaData);
}
// otherwise
LoginConfigMetaData loginConfig = webMetaData.getLoginConfig();
try {
boolean webRequiresKC = loginConfig != null && "KEYCLOAK-SAML".equalsIgnoreCase(loginConfig.getAuthMethod());
boolean hasSubsystemConfig = Configuration.INSTANCE.isSecureDeployment(deploymentUnit);
if (hasSubsystemConfig || webRequiresKC) {
log.debug("Setting up KEYCLOAK-SAML auth method for WAR: " + deploymentUnit.getName());
// if secure-deployment configuration exists for web app, we force KEYCLOAK-SAML auth method on it
if (hasSubsystemConfig) {
addXMLData(getXML(deploymentUnit), warMetaData);
if (loginConfig != null) {
loginConfig.setAuthMethod("KEYCLOAK-SAML");
//loginConfig.setRealmName(service.getRealmName(deploymentName));
} else {
log.warn("Failed to set up KEYCLOAK-SAML auth method for WAR: " + deploymentUnit.getName() + " (loginConfig == null)");
}
}
addValve(webMetaData);
KeycloakLogger.ROOT_LOGGER.deploymentSecured(deploymentUnit.getName());
}
} catch (Exception e) {
throw new DeploymentUnitProcessingException("Failed to configure KeycloakSamlExtension from subsystem model", e);
}
}
private String getXML(DeploymentUnit deploymentUnit) throws XMLStreamException {
ModelNode node = Configuration.INSTANCE.getSecureDeployment(deploymentUnit);
if (node != null) {
KeycloakSubsystemParser writer = new KeycloakSubsystemParser();
ByteArrayOutputStream output = new ByteArrayOutputStream();
XMLExtendedStreamWriter streamWriter = new FormattingXMLStreamWriter(XMLOutputFactory.newInstance().createXMLStreamWriter(output));
try {
streamWriter.writeStartElement("keycloak-saml-adapter");
writer.writeSps(streamWriter, node);
streamWriter.writeEndElement();
} finally {
streamWriter.close();
}
return new String(output.toByteArray(), Charset.forName("utf-8"));
}
return null;
}
private void addXMLData(String xml, 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 param = new ParamValueMetaData();
param.setParamName(AdapterConstants.AUTH_DATA_PARAM_NAME);
param.setParamValue(xml);
contextParams.add(param);
webMetaData.setContextParams(contextParams);
}
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(SamlAuthenticatorValve.class.getName());
valve.setModule("org.keycloak.keycloak-saml-as7-adapter");
//log.info("******* adding Keycloak valve to: " + deploymentName);
valves.add(valve);
}
@Override
public void undeploy(DeploymentUnit du) {
}
}

View file

@ -1,157 +0,0 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.keycloak.adapters.saml.AdapterConstants;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
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.spec.LoginConfigMetaData;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceTarget;
/**
*
* @author hmlnarik
*/
public class KeycloakClusteredSsoDeploymentProcessor implements DeploymentUnitProcessor {
private static final Logger LOG = Logger.getLogger(KeycloakClusteredSsoDeploymentProcessor.class);
private static final String DEFAULT_CACHE_CONTAINER = "web";
private static final String SSO_CACHE_CONTAINER_NAME_PARAM_NAME = "keycloak.sessionIdMapperUpdater.infinispan.containerName";
private static final String SSO_CACHE_NAME_PARAM_NAME = "keycloak.sessionIdMapperUpdater.infinispan.cacheName";
@Override
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
if (isKeycloakSamlAuthMethod(deploymentUnit) && isDistributable(deploymentUnit)) {
addSamlReplicationConfiguration(deploymentUnit, phaseContext);
}
}
public static boolean isDistributable(final DeploymentUnit deploymentUnit) {
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return false;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
return false;
}
return webMetaData.getDistributable() != null || webMetaData.getReplicationConfig() != null;
}
public static boolean isKeycloakSamlAuthMethod(final DeploymentUnit deploymentUnit) {
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return false;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
return false;
}
if (Configuration.INSTANCE.isSecureDeployment(deploymentUnit)) {
return true;
}
LoginConfigMetaData loginConfig = webMetaData.getLoginConfig();
return loginConfig != null && Objects.equals(loginConfig.getAuthMethod(), "KEYCLOAK-SAML");
}
@Override
public void undeploy(DeploymentUnit du) {
}
private void addSamlReplicationConfiguration(DeploymentUnit deploymentUnit, DeploymentPhaseContext context) {
WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
if (warMetaData == null) {
return;
}
JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData();
if (webMetaData == null) {
webMetaData = new JBossWebMetaData();
warMetaData.setMergedJBossWebMetaData(webMetaData);
}
// Find out default names of cache container and cache
String cacheContainer = DEFAULT_CACHE_CONTAINER;
String deploymentSessionCacheName =
(deploymentUnit.getParent() == null
? ""
: deploymentUnit.getParent().getName() + ".")
+ deploymentUnit.getName();
// Update names from jboss-web.xml's <replicationConfig>
if (webMetaData.getReplicationConfig() != null && webMetaData.getReplicationConfig().getCacheName() != null) {
ServiceName sn = ServiceName.parse(webMetaData.getReplicationConfig().getCacheName());
cacheContainer = (sn.length() > 1) ? sn.getParent().getSimpleName() : sn.getSimpleName();
deploymentSessionCacheName = sn.getSimpleName();
}
String ssoCacheName = deploymentSessionCacheName + ".ssoCache";
// Override if they were set in the context parameters
List<ParamValueMetaData> contextParams = webMetaData.getContextParams();
if (contextParams == null) {
contextParams = new ArrayList<>();
}
for (ParamValueMetaData contextParam : contextParams) {
if (Objects.equals(contextParam.getParamName(), SSO_CACHE_CONTAINER_NAME_PARAM_NAME)) {
cacheContainer = contextParam.getParamValue();
} else if (Objects.equals(contextParam.getParamName(), SSO_CACHE_NAME_PARAM_NAME)) {
ssoCacheName = contextParam.getParamValue();
}
}
LOG.debugv("Determined SSO cache container configuration: container: {0}, cache: {1}", cacheContainer, ssoCacheName);
// addCacheDependency(context, deploymentUnit, cacheContainer, cacheName);
// Set context parameters for SSO cache container/name
ParamValueMetaData paramContainer = new ParamValueMetaData();
paramContainer.setParamName(AdapterConstants.REPLICATION_CONFIG_CONTAINER_PARAM_NAME);
paramContainer.setParamValue(cacheContainer);
contextParams.add(paramContainer);
ParamValueMetaData paramSsoCache = new ParamValueMetaData();
paramSsoCache.setParamName(AdapterConstants.REPLICATION_CONFIG_SSO_CACHE_PARAM_NAME);
paramSsoCache.setParamValue(ssoCacheName);
contextParams.add(paramSsoCache);
webMetaData.setContextParams(contextParams);
}
private void addCacheDependency(DeploymentPhaseContext context, DeploymentUnit deploymentUnit, String cacheContainer, String cacheName) {
ServiceName jbossAsCacheContainerService = ServiceName.of("jboss", "infinispan", cacheContainer);
ServiceTarget st = context.getServiceTarget();
st.addDependency(jbossAsCacheContainerService.append(cacheName));
}
}

View file

@ -1,85 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
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.as.web.deployment.WarMetaData;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
import org.jboss.metadata.web.spec.LoginConfigMetaData;
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-saml-adapter-core");
private static final ModuleIdentifier KEYCLOAK_API_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-saml-adapter-api-public");
private static final ModuleIdentifier KEYCLOAK_COMMON = ModuleIdentifier.create("org.keycloak.keycloak-common");
@Override
public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
if (Configuration.INSTANCE.getSecureDeployment(deploymentUnit) == null) {
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) return;
if (loginConfig.getAuthMethod() == null) return;
if (!loginConfig.getAuthMethod().equals("KEYCLOAK-SAML")) return;
}
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_API_ADAPTER, false, false, false, false));
moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_COMMON, false, false, false, false));
}
abstract protected void addPlatformSpecificModules(ModuleSpecification moduleSpecification, ModuleLoader moduleLoader);
@Override
public void undeploy(DeploymentUnit du) {
}
}

View file

@ -1,36 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.server.deployment.module.ModuleDependency;
import org.jboss.as.server.deployment.module.ModuleSpecification;
import org.jboss.modules.ModuleIdentifier;
import org.jboss.modules.ModuleLoader;
/**
* @author <a href="mailto:marko.strukelj@gmail.com">Marko Strukelj</a>
*/
public class KeycloakDependencyProcessorAS7 extends KeycloakDependencyProcessor {
private static final ModuleIdentifier KEYCLOAK_AS7_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-saml-as7-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));
}}

View file

@ -1,86 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
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.SubsystemRegistration;
import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
import org.jboss.as.controller.parsing.ExtensionParsingContext;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
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 KeycloakSamlExtension implements Extension {
static final String SUBSYSTEM_NAME = "keycloak-saml";
private static final String NAMESPACE_1_1 = "urn:jboss:domain:keycloak-saml:1.1";
private static final String NAMESPACE_1_2 = "urn:jboss:domain:keycloak-saml:1.2";
private static final String NAMESPACE_1_3 = "urn:jboss:domain:keycloak-saml:1.3";
private static final String NAMESPACE_1_4 = "urn:jboss:domain:keycloak-saml:1.4";
static final String CURRENT_NAMESPACE = NAMESPACE_1_4;
private static final KeycloakSubsystemParser PARSER = new KeycloakSubsystemParser();
static final PathElement PATH_SUBSYSTEM = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
private static final String RESOURCE_NAME = KeycloakSamlExtension.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);
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, KeycloakSamlExtension.class.getClassLoader(), true, false);
}
/**
* {@inheritDoc}
*/
@Override
public void initializeParsers(final ExtensionParsingContext context) {
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, KeycloakSamlExtension.NAMESPACE_1_1, PARSER);
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, KeycloakSamlExtension.NAMESPACE_1_2, PARSER);
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, KeycloakSamlExtension.NAMESPACE_1_3, PARSER);
context.setSubsystemXmlMapping(SUBSYSTEM_NAME, KeycloakSamlExtension.NAMESPACE_1_4, PARSER);
}
/**
* {@inheritDoc}
*/
@Override
public void initialize(final ExtensionContext context) {
final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME,
MGMT_API_VERSION.getMajor(), MGMT_API_VERSION.getMinor(), MGMT_API_VERSION.getMicro());
ManagementResourceRegistration registration = subsystem.registerSubsystemModel(KeycloakSubsystemDefinition.INSTANCE);
ManagementResourceRegistration secureDeploymentRegistration = registration.registerSubModel(SecureDeploymentDefinition.INSTANCE);
ManagementResourceRegistration serviceProviderRegistration = secureDeploymentRegistration.registerSubModel(ServiceProviderDefinition.INSTANCE);
serviceProviderRegistration.registerSubModel(KeyDefinition.INSTANCE);
ManagementResourceRegistration idpRegistration = serviceProviderRegistration.registerSubModel(IdentityProviderDefinition.INSTANCE);
idpRegistration.registerSubModel(KeyDefinition.INSTANCE);
subsystem.registerXMLElementWriter(PARSER);
}
}

View file

@ -1,74 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
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.DeploymentUnitProcessor;
import org.jboss.as.server.deployment.Phase;
import org.jboss.dmr.ModelNode;
import org.jboss.msc.service.ServiceController;
import java.util.List;
/**
* 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, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) {
context.addStep(new AbstractDeploymentChainStep() {
@Override
protected void execute(DeploymentProcessorTarget processorTarget) {
processorTarget.addDeploymentProcessor(KeycloakSamlExtension.SUBSYSTEM_NAME, Phase.DEPENDENCIES, 0, chooseDependencyProcessor());
processorTarget.addDeploymentProcessor(KeycloakSamlExtension.SUBSYSTEM_NAME,
Phase.POST_MODULE, // PHASE
Phase.POST_MODULE_VALIDATOR_FACTORY - 1, // PRIORITY
chooseConfigDeploymentProcessor());
processorTarget.addDeploymentProcessor(KeycloakSamlExtension.SUBSYSTEM_NAME,
Phase.POST_MODULE, // PHASE
Phase.POST_MODULE_VALIDATOR_FACTORY - 1, // PRIORITY
chooseClusteredSsoDeploymentProcessor());
}
}, OperationContext.Stage.RUNTIME);
}
private DeploymentUnitProcessor chooseDependencyProcessor() {
return new KeycloakDependencyProcessorAS7();
}
private DeploymentUnitProcessor chooseConfigDeploymentProcessor() {
return new KeycloakAdapterConfigDeploymentProcessor();
}
private DeploymentUnitProcessor chooseClusteredSsoDeploymentProcessor() {
return new KeycloakClusteredSsoDeploymentProcessor();
}
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
}
}

View file

@ -1,46 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
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-saml.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2013 Red Hat Inc.
*/
public class KeycloakSubsystemDefinition extends SimpleResourceDefinition {
static final KeycloakSubsystemDefinition INSTANCE = new KeycloakSubsystemDefinition();
private KeycloakSubsystemDefinition() {
super(KeycloakSamlExtension.SUBSYSTEM_PATH,
KeycloakSamlExtension.getResourceDescriptionResolver("subsystem"),
KeycloakSubsystemAdd.INSTANCE,
ReloadRequiredRemoveStepHandler.INSTANCE
);
}
@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);
resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
}
}

View file

@ -1,703 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
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.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* 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(KeycloakSamlExtension.PATH_SUBSYSTEM));
list.add(addKeycloakSub);
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
if (reader.getLocalName().equals(Constants.XML.SECURE_DEPLOYMENT)) {
readSecureDeployment(reader, list);
} else {
throw ParseUtils.unexpectedElement(reader);
}
}
}
// used for debugging
private int nextTag(XMLExtendedStreamReader reader) throws XMLStreamException {
return reader.nextTag();
}
void readSecureDeployment(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException {
String name = readRequiredAttribute(reader, Constants.XML.NAME);
PathAddress addr = PathAddress.pathAddress(
PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakSamlExtension.SUBSYSTEM_NAME),
PathElement.pathElement(Constants.Model.SECURE_DEPLOYMENT, name));
ModelNode addSecureDeployment = Util.createAddOperation(addr);
list.add(addSecureDeployment);
Set<String> parsedElements = new HashSet<>();
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
if (parsedElements.contains(tagName)) {
// all sub-elements of the secure deployment type should occur only once.
throw ParseUtils.unexpectedElement(reader);
}
if (tagName.equals(Constants.XML.SERVICE_PROVIDER)) {
readServiceProvider(reader, list, addr);
} else {
throw ParseUtils.unexpectedElement(reader);
}
parsedElements.add(tagName);
}
}
void readServiceProvider(XMLExtendedStreamReader reader, List<ModelNode> list, PathAddress parentAddr) throws XMLStreamException {
String entityId = readRequiredAttribute(reader, Constants.XML.ENTITY_ID);
PathAddress addr = PathAddress.pathAddress(parentAddr,
PathElement.pathElement(Constants.Model.SERVICE_PROVIDER, entityId));
ModelNode addServiceProvider = Util.createAddOperation(addr);
list.add(addServiceProvider);
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
if (Constants.XML.ENTITY_ID.equals(name)) {
continue;
}
String value = reader.getAttributeValue(i);
SimpleAttributeDefinition attr = ServiceProviderDefinition.lookup(name);
if (attr == null) {
throw ParseUtils.unexpectedAttribute(reader, i);
}
attr.parseAndSetParameter(value, addServiceProvider, reader);
}
Set parsedElements = new HashSet<>();
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
if (parsedElements.contains(tagName)) {
// all sub-elements of the service provider type should occur only once.
throw ParseUtils.unexpectedElement(reader);
}
if (Constants.XML.KEYS.equals(tagName)) {
readKeys(list, reader, addr);
} else if (Constants.XML.PRINCIPAL_NAME_MAPPING.equals(tagName)) {
readPrincipalNameMapping(addServiceProvider, reader);
} else if (Constants.XML.ROLE_IDENTIFIERS.equals(tagName)) {
readRoleIdentifiers(addServiceProvider, reader);
} else if (Constants.XML.ROLE_MAPPINGS_PROVIDER.equals(tagName)) {
readRoleMappingsProvider(addServiceProvider, reader);
} else if (Constants.XML.IDENTITY_PROVIDER.equals(tagName)) {
readIdentityProvider(list, reader, addr);
} else {
throw ParseUtils.unexpectedElement(reader);
}
parsedElements.add(tagName);
}
}
void readIdentityProvider(List<ModelNode> list, XMLExtendedStreamReader reader, PathAddress parentAddr) throws XMLStreamException {
String entityId = readRequiredAttribute(reader, Constants.XML.ENTITY_ID);
PathAddress addr = PathAddress.pathAddress(parentAddr,
PathElement.pathElement(Constants.Model.IDENTITY_PROVIDER, entityId));
ModelNode addIdentityProvider = Util.createAddOperation(addr);
list.add(addIdentityProvider);
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
if (Constants.XML.ENTITY_ID.equals(name)
// don't break if encountering this noop attr from client-adapter/core keycloak_saml_adapter_1_6.xsd
|| "encryption".equals(name)) {
continue;
}
SimpleAttributeDefinition attr = IdentityProviderDefinition.lookup(name);
if (attr == null) {
throw ParseUtils.unexpectedAttribute(reader, i);
}
attr.parseAndSetParameter(value, addIdentityProvider, reader);
}
Set<String> parsedElements = new HashSet<>();
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
if (parsedElements.contains(tagName)) {
// all sub-elements of the identity provider type should occur only once.
throw ParseUtils.unexpectedElement(reader);
}
if (Constants.XML.SINGLE_SIGN_ON.equals(tagName)) {
readSingleSignOn(addIdentityProvider, reader);
} else if (Constants.XML.SINGLE_LOGOUT.equals(tagName)) {
readSingleLogout(addIdentityProvider, reader);
} else if (Constants.XML.KEYS.equals(tagName)) {
readKeys(list, reader, addr);
} else if (Constants.XML.HTTP_CLIENT.equals(tagName)) {
readHttpClient(addIdentityProvider, reader);
} else if (Constants.XML.ALLOWED_CLOCK_SKEW.equals(tagName)) {
readAllowedClockSkew(addIdentityProvider, reader);
} else {
throw ParseUtils.unexpectedElement(reader);
}
parsedElements.add(tagName);
}
}
void readSingleSignOn(ModelNode addIdentityProvider, XMLExtendedStreamReader reader) throws XMLStreamException {
ModelNode sso = addIdentityProvider.get(Constants.Model.SINGLE_SIGN_ON);
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
SimpleAttributeDefinition attr = SingleSignOnDefinition.lookup(name);
if (attr == null) {
throw ParseUtils.unexpectedAttribute(reader, i);
}
attr.parseAndSetParameter(value, sso, reader);
}
ParseUtils.requireNoContent(reader);
}
void readSingleLogout(ModelNode addIdentityProvider, XMLExtendedStreamReader reader) throws XMLStreamException {
ModelNode slo = addIdentityProvider.get(Constants.Model.SINGLE_LOGOUT);
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
SimpleAttributeDefinition attr = SingleLogoutDefinition.lookup(name);
if (attr == null) {
throw ParseUtils.unexpectedAttribute(reader, i);
}
attr.parseAndSetParameter(value, slo, reader);
}
ParseUtils.requireNoContent(reader);
}
void readKeys(List<ModelNode> list, XMLExtendedStreamReader reader, PathAddress parentAddr) throws XMLStreamException {
ParseUtils.requireNoAttributes(reader);
List<ModelNode> keyList = new LinkedList<>();
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
if (!Constants.XML.KEY.equals(tagName)) {
throw ParseUtils.unexpectedElement(reader);
}
readKey(keyList, reader, parentAddr);
}
list.addAll(keyList);
}
void readHttpClient(final ModelNode addIdentityProvider, final XMLExtendedStreamReader reader) throws XMLStreamException {
ModelNode httpClientNode = addIdentityProvider.get(Constants.Model.HTTP_CLIENT);
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
SimpleAttributeDefinition attr = HttpClientDefinition.lookup(name);
if (attr == null) {
throw ParseUtils.unexpectedAttribute(reader, i);
}
attr.parseAndSetParameter(value, httpClientNode, reader);
}
ParseUtils.requireNoContent(reader);
}
void readAllowedClockSkew(ModelNode addIdentityProvider, XMLExtendedStreamReader reader) throws XMLStreamException {
ModelNode allowedClockSkew = addIdentityProvider.get(Constants.Model.ALLOWED_CLOCK_SKEW);
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
if (Constants.XML.ALLOWED_CLOCK_SKEW_UNIT.equals(name)) {
SimpleAttributeDefinition attr = AllowedClockSkew.ALLOWED_CLOCK_SKEW_UNIT;
attr.parseAndSetParameter(value, allowedClockSkew, reader);
} else {
throw ParseUtils.unexpectedAttribute(reader, i);
}
}
// the real value is the content
String value = reader.getElementText();
SimpleAttributeDefinition attr = AllowedClockSkew.ALLOWED_CLOCK_SKEW_VALUE;
attr.parseAndSetParameter(value, allowedClockSkew, reader);
}
void readKey(List<ModelNode> list, XMLExtendedStreamReader reader, PathAddress parentAddr) throws XMLStreamException {
PathAddress addr = PathAddress.pathAddress(parentAddr,
PathElement.pathElement(Constants.Model.KEY, "key-" + list.size()));
ModelNode addKey = Util.createAddOperation(addr);
list.add(addKey);
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
SimpleAttributeDefinition attr = KeyDefinition.lookup(name);
if (attr == null) {
throw ParseUtils.unexpectedAttribute(reader, i);
}
attr.parseAndSetParameter(value, addKey, reader);
}
Set<String> parsedElements = new HashSet<>();
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
if (parsedElements.contains(tagName)) {
// all sub-elements of the key type should occur only once.
throw ParseUtils.unexpectedElement(reader);
}
if (Constants.XML.KEY_STORE.equals(tagName)) {
readKeyStore(addKey, reader);
} else if (Constants.XML.PRIVATE_KEY_PEM.equals(tagName)
|| Constants.XML.PUBLIC_KEY_PEM.equals(tagName)
|| Constants.XML.CERTIFICATE_PEM.equals(tagName)) {
readNoAttrElementContent(KeyDefinition.lookupElement(tagName), addKey, reader);
} else {
throw ParseUtils.unexpectedElement(reader);
}
parsedElements.add(tagName);
}
}
void readNoAttrElementContent(SimpleAttributeDefinition attr, ModelNode model, XMLExtendedStreamReader reader) throws XMLStreamException {
ParseUtils.requireNoAttributes(reader);
String value = reader.getElementText();
attr.parseAndSetParameter(value, model, reader);
}
void readKeyStore(ModelNode addKey, XMLExtendedStreamReader reader) throws XMLStreamException {
ModelNode addKeyStore = addKey.get(Constants.Model.KEY_STORE);
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
SimpleAttributeDefinition attr = KeyStoreDefinition.lookup(name);
if (attr == null) {
throw ParseUtils.unexpectedAttribute(reader, i);
}
attr.parseAndSetParameter(value, addKeyStore, reader);
}
if (!addKeyStore.hasDefined(Constants.Model.FILE) && !addKeyStore.hasDefined(Constants.Model.RESOURCE)) {
throw new XMLStreamException("KeyStore element must have 'file' or 'resource' attribute set", reader.getLocation());
}
if (!addKeyStore.hasDefined(Constants.Model.PASSWORD)) {
throw ParseUtils.missingRequired(reader, asSet(Constants.XML.PASSWORD));
}
Set<String> parsedElements = new HashSet<>();
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
if (parsedElements.contains(tagName)) {
// all sub-elements of the keystore type should occur only once.
throw ParseUtils.unexpectedElement(reader);
}
if (Constants.XML.PRIVATE_KEY.equals(tagName)) {
readPrivateKey(reader, addKeyStore);
} else if (Constants.XML.CERTIFICATE.equals(tagName)) {
readCertificate(reader, addKeyStore);
} else {
throw ParseUtils.unexpectedElement(reader);
}
parsedElements.add(tagName);
}
}
void readPrivateKey(XMLExtendedStreamReader reader, ModelNode addKeyStore) throws XMLStreamException {
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
SimpleAttributeDefinition attr = KeyStorePrivateKeyDefinition.lookup(name);
if (attr == null) {
throw ParseUtils.unexpectedAttribute(reader, i);
}
attr.parseAndSetParameter(value, addKeyStore, reader);
}
if (!addKeyStore.hasDefined(Constants.Model.PRIVATE_KEY_ALIAS)) {
throw ParseUtils.missingRequired(reader, asSet(Constants.XML.PRIVATE_KEY_ALIAS));
}
if (!addKeyStore.hasDefined(Constants.Model.PRIVATE_KEY_PASSWORD)) {
throw ParseUtils.missingRequired(reader, asSet(Constants.XML.PRIVATE_KEY_PASSWORD));
}
ParseUtils.requireNoContent(reader);
}
void readCertificate(XMLExtendedStreamReader reader, ModelNode addKeyStore) throws XMLStreamException {
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
SimpleAttributeDefinition attr = KeyStoreCertificateDefinition.lookup(name);
if (attr == null) {
throw ParseUtils.unexpectedAttribute(reader, i);
}
attr.parseAndSetParameter(value, addKeyStore, reader);
}
if (!addKeyStore.hasDefined(Constants.Model.CERTIFICATE_ALIAS)) {
throw ParseUtils.missingRequired(reader, asSet(Constants.XML.CERTIFICATE_ALIAS));
}
ParseUtils.requireNoContent(reader);
}
void readRoleIdentifiers(ModelNode addServiceProvider, XMLExtendedStreamReader reader) throws XMLStreamException {
ParseUtils.requireNoAttributes(reader);
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
if (!Constants.XML.ATTRIBUTE.equals(tagName)) {
throw ParseUtils.unexpectedElement(reader);
}
ParseUtils.requireSingleAttribute(reader, Constants.XML.NAME);
String name = ParseUtils.readStringAttributeElement(reader, Constants.XML.NAME);
ServiceProviderDefinition.ROLE_ATTRIBUTES.parseAndAddParameterElement(name, addServiceProvider, reader);
}
}
void readRoleMappingsProvider(final ModelNode addServiceProvider, final XMLExtendedStreamReader reader) throws XMLStreamException {
String providerId = readRequiredAttribute(reader, Constants.XML.ID);
ServiceProviderDefinition.ROLE_MAPPINGS_PROVIDER_ID.parseAndSetParameter(providerId, addServiceProvider, reader);
while (reader.hasNext() && nextTag(reader) != END_ELEMENT) {
String tagName = reader.getLocalName();
if (!Constants.XML.PROPERTY.equals(tagName)) {
throw ParseUtils.unexpectedElement(reader);
}
final String[] array = ParseUtils.requireAttributes(reader, Constants.XML.NAME, Constants.XML.VALUE);
ServiceProviderDefinition.ROLE_MAPPINGS_PROVIDER_CONFIG.parseAndAddParameterElement(array[0], array[1], addServiceProvider, reader);
ParseUtils.requireNoContent(reader);
}
}
void readPrincipalNameMapping(ModelNode addServiceProvider, XMLExtendedStreamReader reader) throws XMLStreamException {
boolean policySet = false;
for (int i = 0; i < reader.getAttributeCount(); i++) {
String name = reader.getAttributeLocalName(i);
String value = reader.getAttributeValue(i);
if (Constants.XML.PRINCIPAL_NAME_MAPPING_POLICY.equals(name)) {
policySet = true;
ServiceProviderDefinition.PRINCIPAL_NAME_MAPPING_POLICY.parseAndSetParameter(value, addServiceProvider, reader);
} else if (Constants.XML.PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME.equals(name)) {
ServiceProviderDefinition.PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME.parseAndSetParameter(value, addServiceProvider, reader);
} else {
throw ParseUtils.unexpectedAttribute(reader, i);
}
}
if (!policySet) {
throw ParseUtils.missingRequired(reader, asSet(Constants.XML.PRINCIPAL_NAME_MAPPING_POLICY));
}
ParseUtils.requireNoContent(reader);
}
/**
* Read an attribute, and throw exception if attribute is not present
*/
String readRequiredAttribute(XMLExtendedStreamReader reader, String attrName) throws XMLStreamException {
String value = null;
for (int i = 0; i < reader.getAttributeCount(); i++) {
String attr = reader.getAttributeLocalName(i);
if (attr.equals(attrName)) {
value = reader.getAttributeValue(i);
break;
}
}
if (value == null) {
throw ParseUtils.missingRequired(reader, Collections.singleton(attrName));
}
return value;
}
/**
* {@inheritDoc}
*/
@Override
public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context) throws XMLStreamException {
context.startSubsystemElement(KeycloakSamlExtension.CURRENT_NAMESPACE, false);
writeSecureDeployment(writer, context.getModelNode());
writer.writeEndElement();
}
public void writeSecureDeployment(XMLExtendedStreamWriter writer, ModelNode model) throws XMLStreamException {
if (!model.get(Constants.Model.SECURE_DEPLOYMENT).isDefined()) {
return;
}
for (Property sp : model.get(Constants.Model.SECURE_DEPLOYMENT).asPropertyList()) {
writer.writeStartElement(Constants.XML.SECURE_DEPLOYMENT);
writer.writeAttribute(Constants.XML.NAME, sp.getName());
writeSps(writer, sp.getValue());
writer.writeEndElement();
}
}
void writeSps(final XMLExtendedStreamWriter writer, final ModelNode model) throws XMLStreamException {
if (!model.isDefined()) {
return;
}
for (Property sp : model.get(Constants.Model.SERVICE_PROVIDER).asPropertyList()) {
writer.writeStartElement(Constants.XML.SERVICE_PROVIDER);
writer.writeAttribute(Constants.XML.ENTITY_ID, sp.getName());
ModelNode spAttributes = sp.getValue();
for (SimpleAttributeDefinition attr : ServiceProviderDefinition.ATTRIBUTES) {
attr.getAttributeMarshaller().marshallAsAttribute(attr, spAttributes, false, writer);
}
writeKeys(writer, spAttributes.get(Constants.Model.KEY));
writePrincipalNameMapping(writer, spAttributes);
writeRoleIdentifiers(writer, spAttributes);
writeRoleMappingsProvider(writer, spAttributes);
writeIdentityProvider(writer, spAttributes.get(Constants.Model.IDENTITY_PROVIDER));
writer.writeEndElement();
}
}
void writeIdentityProvider(XMLExtendedStreamWriter writer, ModelNode model) throws XMLStreamException {
if (!model.isDefined()) {
return;
}
for (Property idp : model.asPropertyList()) {
writer.writeStartElement(Constants.XML.IDENTITY_PROVIDER);
writer.writeAttribute(Constants.XML.ENTITY_ID, idp.getName());
ModelNode idpAttributes = idp.getValue();
for (SimpleAttributeDefinition attr : IdentityProviderDefinition.ATTRIBUTES) {
attr.getAttributeMarshaller().marshallAsAttribute(attr, idpAttributes, false, writer);
}
writeSingleSignOn(writer, idpAttributes.get(Constants.Model.SINGLE_SIGN_ON));
writeSingleLogout(writer, idpAttributes.get(Constants.Model.SINGLE_LOGOUT));
writeKeys(writer, idpAttributes.get(Constants.Model.KEY));
writeHttpClient(writer, idpAttributes.get(Constants.Model.HTTP_CLIENT));
writeAllowedClockSkew(writer, idpAttributes.get(Constants.Model.ALLOWED_CLOCK_SKEW));
writer.writeEndElement();
}
}
void writeSingleSignOn(XMLExtendedStreamWriter writer, ModelNode model) throws XMLStreamException {
if (!model.isDefined()) {
return;
}
writer.writeStartElement(Constants.XML.SINGLE_SIGN_ON);
for (SimpleAttributeDefinition attr : SingleSignOnDefinition.ATTRIBUTES) {
attr.getAttributeMarshaller().marshallAsAttribute(attr, model, false, writer);
}
writer.writeEndElement();
}
void writeSingleLogout(XMLExtendedStreamWriter writer, ModelNode model) throws XMLStreamException {
if (!model.isDefined()) {
return;
}
writer.writeStartElement(Constants.XML.SINGLE_LOGOUT);
for (SimpleAttributeDefinition attr : SingleLogoutDefinition.ATTRIBUTES) {
attr.getAttributeMarshaller().marshallAsAttribute(attr, model, false, writer);
}
writer.writeEndElement();
}
void writeKeys(XMLExtendedStreamWriter writer, ModelNode model) throws XMLStreamException {
if (!model.isDefined()) {
return;
}
boolean contains = false;
for (Property key : model.asPropertyList()) {
if (!contains) {
writer.writeStartElement(Constants.XML.KEYS);
contains = true;
}
writer.writeStartElement(Constants.XML.KEY);
ModelNode keyAttributes = key.getValue();
for (SimpleAttributeDefinition attr : KeyDefinition.ATTRIBUTES) {
attr.getAttributeMarshaller().marshallAsAttribute(attr, keyAttributes, false, writer);
}
for (SimpleAttributeDefinition attr : KeyDefinition.ELEMENTS) {
attr.getAttributeMarshaller().marshallAsElement(attr, keyAttributes, false, writer);
}
writeKeyStore(writer, keyAttributes.get(Constants.Model.KEY_STORE));
writer.writeEndElement();
}
if (contains) {
writer.writeEndElement();
}
}
void writeHttpClient(XMLExtendedStreamWriter writer, ModelNode httpClientModel) throws XMLStreamException {
if (!httpClientModel.isDefined()) {
return;
}
writer.writeStartElement(Constants.XML.HTTP_CLIENT);
for (SimpleAttributeDefinition attr : HttpClientDefinition.ATTRIBUTES) {
attr.marshallAsAttribute(httpClientModel, false, writer);
}
writer.writeEndElement();
}
void writeAllowedClockSkew(XMLExtendedStreamWriter writer, ModelNode allowedClockSkew) throws XMLStreamException {
if (!allowedClockSkew.isDefined()) {
return;
}
writer.writeStartElement(Constants.XML.ALLOWED_CLOCK_SKEW);
AllowedClockSkew.ALLOWED_CLOCK_SKEW_UNIT.getAttributeMarshaller().marshallAsAttribute(AllowedClockSkew.ALLOWED_CLOCK_SKEW_UNIT, allowedClockSkew, false, writer);
ModelNode allowedClockSkewValue = allowedClockSkew.get(Constants.Model.ALLOWED_CLOCK_SKEW_VALUE);
char[] chars = allowedClockSkewValue.asString().toCharArray();
writer.writeCharacters(chars, 0, chars.length);
writer.writeEndElement();
}
void writeKeyStore(XMLExtendedStreamWriter writer, ModelNode model) throws XMLStreamException {
if (!model.isDefined()) {
return;
}
writer.writeStartElement(Constants.XML.KEY_STORE);
for (SimpleAttributeDefinition attr : KeyStoreDefinition.ATTRIBUTES) {
attr.getAttributeMarshaller().marshallAsAttribute(attr, model, false, writer);
}
writePrivateKey(writer, model);
writeCertificate(writer, model);
writer.writeEndElement();
}
void writeCertificate(XMLExtendedStreamWriter writer, ModelNode model) throws XMLStreamException {
ModelNode value = model.get(Constants.Model.CERTIFICATE_ALIAS);
if (!value.isDefined()) {
return;
}
writer.writeStartElement(Constants.XML.CERTIFICATE);
SimpleAttributeDefinition attr = KeyStoreCertificateDefinition.CERTIFICATE_ALIAS;
attr.getAttributeMarshaller().marshallAsAttribute(attr, model, false, writer);
writer.writeEndElement();
}
void writePrivateKey(XMLExtendedStreamWriter writer, ModelNode model) throws XMLStreamException {
ModelNode pk_alias = model.get(Constants.Model.PRIVATE_KEY_ALIAS);
ModelNode pk_password = model.get(Constants.Model.PRIVATE_KEY_PASSWORD);
if (!pk_alias.isDefined() && !pk_password.isDefined()) {
return;
}
writer.writeStartElement(Constants.XML.PRIVATE_KEY);
for (SimpleAttributeDefinition attr : KeyStorePrivateKeyDefinition.ATTRIBUTES) {
attr.getAttributeMarshaller().marshallAsAttribute(attr, model, false, writer);
}
writer.writeEndElement();
}
void writeRoleIdentifiers(XMLExtendedStreamWriter writer, ModelNode model) throws XMLStreamException {
ModelNode value = model.get(Constants.Model.ROLE_ATTRIBUTES);
if (!value.isDefined()) {
return;
}
List<ModelNode> items = value.asList();
if (items.size() == 0) {
return;
}
writer.writeStartElement(Constants.XML.ROLE_IDENTIFIERS);
for (ModelNode item : items) {
writer.writeStartElement(Constants.XML.ATTRIBUTE);
writer.writeAttribute("name", item.asString());
writer.writeEndElement();
}
writer.writeEndElement();
}
void writeRoleMappingsProvider(final XMLExtendedStreamWriter writer, final ModelNode model) throws XMLStreamException {
ModelNode providerId = model.get(Constants.Model.ROLE_MAPPINGS_PROVIDER_ID);
if (!providerId.isDefined()) {
return;
}
writer.writeStartElement(Constants.XML.ROLE_MAPPINGS_PROVIDER);
writer.writeAttribute(Constants.XML.ID, providerId.asString());
ServiceProviderDefinition.ROLE_MAPPINGS_PROVIDER_CONFIG.marshallAsElement(model, false, writer);
writer.writeEndElement();
}
void writePrincipalNameMapping(XMLExtendedStreamWriter writer, ModelNode model) throws XMLStreamException {
ModelNode policy = model.get(Constants.Model.PRINCIPAL_NAME_MAPPING_POLICY);
ModelNode mappingAttribute = model.get(Constants.Model.PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME);
if (!policy.isDefined() && !mappingAttribute.isDefined()) {
return;
}
writer.writeStartElement(Constants.XML.PRINCIPAL_NAME_MAPPING);
if (policy.isDefined()) {
writer.writeAttribute(Constants.XML.PRINCIPAL_NAME_MAPPING_POLICY, policy.asString());
}
if (mappingAttribute.isDefined()) {
writer.writeAttribute(Constants.XML.PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME, mappingAttribute.asString());
}
writer.writeEndElement();
}
private static Set<String> asSet(String ... values) {
HashSet ret = new HashSet();
for (String value: values) {
ret.add(value);
}
return ret;
}
}

View file

@ -1,46 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.AbstractAddStepHandler;
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;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
class SecureDeploymentAddHandler extends AbstractAddStepHandler {
static SecureDeploymentAddHandler INSTANCE = new SecureDeploymentAddHandler();
private SecureDeploymentAddHandler() {
}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
Configuration.INSTANCE.updateModel(operation, model);
}
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
}
}

View file

@ -1,44 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.PathElement;
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;
/**
* Defines attributes and operations for a secure-deployment.
*/
public class SecureDeploymentDefinition extends SimpleResourceDefinition {
static final SecureDeploymentDefinition INSTANCE = new SecureDeploymentDefinition();
private SecureDeploymentDefinition() {
super(PathElement.pathElement(Constants.Model.SECURE_DEPLOYMENT),
KeycloakSamlExtension.getResourceDescriptionResolver(Constants.Model.SECURE_DEPLOYMENT),
SecureDeploymentAddHandler.INSTANCE,
ReloadRequiredRemoveStepHandler.INSTANCE);
}
@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);
resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
}
}

View file

@ -1,50 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
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;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
class ServiceProviderAddHandler extends AbstractAddStepHandler {
static final ServiceProviderAddHandler INSTANCE = new ServiceProviderAddHandler();
ServiceProviderAddHandler() {
}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
Configuration.INSTANCE.updateModel(operation, model, true);
}
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
for (AttributeDefinition attr : ServiceProviderDefinition.ALL_ATTRIBUTES) {
attr.validateAndSet(operation, model);
}
}
}

View file

@ -1,160 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.ListAttributeDefinition;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.PropertiesAttributeDefinition;
import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
import org.jboss.as.controller.ReloadRequiredWriteAttributeHandler;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.StringListAttributeDefinition;
import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.dmr.ModelType;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
public class ServiceProviderDefinition extends SimpleResourceDefinition {
private static final SimpleAttributeDefinition SSL_POLICY =
new SimpleAttributeDefinitionBuilder(Constants.Model.SSL_POLICY, ModelType.STRING, true)
.setXmlName(Constants.XML.SSL_POLICY)
.build();
private static final SimpleAttributeDefinition NAME_ID_POLICY_FORMAT =
new SimpleAttributeDefinitionBuilder(Constants.Model.NAME_ID_POLICY_FORMAT, ModelType.STRING, true)
.setXmlName(Constants.XML.NAME_ID_POLICY_FORMAT)
.build();
private static final SimpleAttributeDefinition LOGOUT_PAGE =
new SimpleAttributeDefinitionBuilder(Constants.Model.LOGOUT_PAGE, ModelType.STRING, true)
.setXmlName(Constants.XML.LOGOUT_PAGE)
.build();
private static final SimpleAttributeDefinition FORCE_AUTHENTICATION =
new SimpleAttributeDefinitionBuilder(Constants.Model.FORCE_AUTHENTICATION, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.FORCE_AUTHENTICATION)
.build();
private static final SimpleAttributeDefinition KEEP_DOM_ASSERTION =
new SimpleAttributeDefinitionBuilder(Constants.Model.KEEP_DOM_ASSERTION, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.KEEP_DOM_ASSERTION)
.build();
private static final SimpleAttributeDefinition IS_PASSIVE =
new SimpleAttributeDefinitionBuilder(Constants.Model.IS_PASSIVE, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.IS_PASSIVE)
.build();
private static final SimpleAttributeDefinition TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN =
new SimpleAttributeDefinitionBuilder(Constants.Model.TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN)
.build();
private static final SimpleAttributeDefinition AUTODETECT_BEARER_ONLY =
new SimpleAttributeDefinitionBuilder(Constants.Model.AUTODETECT_BEARER_ONLY, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.AUTODETECT_BEARER_ONLY)
.setAllowExpression(true)
.build();
static final SimpleAttributeDefinition PRINCIPAL_NAME_MAPPING_POLICY =
new SimpleAttributeDefinitionBuilder(Constants.Model.PRINCIPAL_NAME_MAPPING_POLICY, ModelType.STRING, true)
.setXmlName(Constants.XML.PRINCIPAL_NAME_MAPPING_POLICY)
.build();
static final SimpleAttributeDefinition PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME =
new SimpleAttributeDefinitionBuilder(Constants.Model.PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME, ModelType.STRING, true)
.setXmlName(Constants.XML.PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME)
.build();
static final ListAttributeDefinition ROLE_ATTRIBUTES =
new StringListAttributeDefinition.Builder(Constants.Model.ROLE_ATTRIBUTES)
.setAllowNull(true)
.build();
static final SimpleAttributeDefinition ROLE_MAPPINGS_PROVIDER_ID =
new SimpleAttributeDefinitionBuilder(Constants.Model.ROLE_MAPPINGS_PROVIDER_ID, ModelType.STRING, true)
.setXmlName(Constants.XML.ID)
.build();
static final PropertiesAttributeDefinition ROLE_MAPPINGS_PROVIDER_CONFIG =
new PropertiesAttributeDefinition.Builder(Constants.Model.ROLE_MAPPINGS_PROVIDER_CONFIG, true)
.setXmlName(Constants.XML.PROPERTY)
.setWrapXmlElement(false)
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {SSL_POLICY, NAME_ID_POLICY_FORMAT, LOGOUT_PAGE, FORCE_AUTHENTICATION,
IS_PASSIVE, TURN_OFF_CHANGE_SESSSION_ID_ON_LOGIN, KEEP_DOM_ASSERTION, AUTODETECT_BEARER_ONLY};
static final AttributeDefinition[] ELEMENTS = {PRINCIPAL_NAME_MAPPING_POLICY, PRINCIPAL_NAME_MAPPING_ATTRIBUTE_NAME, ROLE_ATTRIBUTES,
ROLE_MAPPINGS_PROVIDER_ID, ROLE_MAPPINGS_PROVIDER_CONFIG};
private static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
private static final HashMap<String, AttributeDefinition> ALL_MAP = new HashMap<>();
static final Collection<AttributeDefinition> ALL_ATTRIBUTES;
static {
for (SimpleAttributeDefinition def : ATTRIBUTES) {
ATTRIBUTE_MAP.put(def.getXmlName(), def);
}
ALL_MAP.putAll(ATTRIBUTE_MAP);
for (AttributeDefinition def : ELEMENTS) {
ALL_MAP.put(def.getXmlName(), def);
}
ALL_ATTRIBUTES = Collections.unmodifiableCollection(ALL_MAP.values());
}
static final ServiceProviderDefinition INSTANCE = new ServiceProviderDefinition();
private ServiceProviderDefinition() {
super(PathElement.pathElement(Constants.Model.SERVICE_PROVIDER),
KeycloakSamlExtension.getResourceDescriptionResolver(Constants.Model.SERVICE_PROVIDER),
ServiceProviderAddHandler.INSTANCE,
ReloadRequiredRemoveStepHandler.INSTANCE);
}
@Override
public void registerOperations(ManagementResourceRegistration resourceRegistration) {
super.registerOperations(resourceRegistration);
resourceRegistration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);
}
@Override
public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
super.registerAttributes(resourceRegistration);
final OperationStepHandler writeHandler = new ReloadRequiredWriteAttributeHandler(ALL_ATTRIBUTES);
for (AttributeDefinition attribute : ALL_ATTRIBUTES) {
resourceRegistration.registerReadWriteAttribute(attribute, null, writeHandler);
}
}
static SimpleAttributeDefinition lookup(String xmlName) {
return ATTRIBUTE_MAP.get(xmlName);
}
}

View file

@ -1,84 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.dmr.ModelType;
import java.util.HashMap;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
abstract class SingleLogoutDefinition {
static final SimpleAttributeDefinition VALIDATE_REQUEST_SIGNATURE =
new SimpleAttributeDefinitionBuilder(Constants.Model.VALIDATE_REQUEST_SIGNATURE, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.VALIDATE_REQUEST_SIGNATURE)
.build();
static final SimpleAttributeDefinition VALIDATE_RESPONSE_SIGNATURE =
new SimpleAttributeDefinitionBuilder(Constants.Model.VALIDATE_RESPONSE_SIGNATURE, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.VALIDATE_RESPONSE_SIGNATURE)
.build();
static final SimpleAttributeDefinition SIGN_REQUEST =
new SimpleAttributeDefinitionBuilder(Constants.Model.SIGN_REQUEST, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.SIGN_REQUEST)
.build();
static final SimpleAttributeDefinition SIGN_RESPONSE =
new SimpleAttributeDefinitionBuilder(Constants.Model.SIGN_RESPONSE, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.SIGN_RESPONSE)
.build();
static final SimpleAttributeDefinition REQUEST_BINDING =
new SimpleAttributeDefinitionBuilder(Constants.Model.REQUEST_BINDING, ModelType.STRING, true)
.setXmlName(Constants.XML.REQUEST_BINDING)
.build();
static final SimpleAttributeDefinition RESPONSE_BINDING =
new SimpleAttributeDefinitionBuilder(Constants.Model.RESPONSE_BINDING, ModelType.STRING, true)
.setXmlName(Constants.XML.RESPONSE_BINDING)
.build();
static final SimpleAttributeDefinition POST_BINDING_URL =
new SimpleAttributeDefinitionBuilder(Constants.Model.POST_BINDING_URL, ModelType.STRING, true)
.setXmlName(Constants.XML.POST_BINDING_URL)
.build();
static final SimpleAttributeDefinition REDIRECT_BINDING_URL =
new SimpleAttributeDefinitionBuilder(Constants.Model.REDIRECT_BINDING_URL, ModelType.STRING, true)
.setXmlName(Constants.XML.REDIRECT_BINDING_URL)
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {VALIDATE_REQUEST_SIGNATURE, VALIDATE_RESPONSE_SIGNATURE,
SIGN_REQUEST, SIGN_RESPONSE, REQUEST_BINDING, RESPONSE_BINDING, POST_BINDING_URL, REDIRECT_BINDING_URL};
static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
static {
for (SimpleAttributeDefinition def : ATTRIBUTES) {
ATTRIBUTE_MAP.put(def.getXmlName(), def);
}
}
static SimpleAttributeDefinition lookup(String xmlName) {
return ATTRIBUTE_MAP.get(xmlName);
}
}

View file

@ -1,78 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.dmr.ModelType;
import java.util.HashMap;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
abstract class SingleSignOnDefinition {
static final SimpleAttributeDefinition SIGN_REQUEST =
new SimpleAttributeDefinitionBuilder(Constants.Model.SIGN_REQUEST, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.SIGN_REQUEST)
.build();
static final SimpleAttributeDefinition VALIDATE_RESPONSE_SIGNATURE =
new SimpleAttributeDefinitionBuilder(Constants.Model.VALIDATE_RESPONSE_SIGNATURE, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.VALIDATE_RESPONSE_SIGNATURE)
.build();
static final SimpleAttributeDefinition VALIDATE_ASSERTION_SIGNATURE =
new SimpleAttributeDefinitionBuilder(Constants.Model.VALIDATE_ASSERTION_SIGNATURE, ModelType.BOOLEAN, true)
.setXmlName(Constants.XML.VALIDATE_ASSERTION_SIGNATURE)
.build();
static final SimpleAttributeDefinition REQUEST_BINDING =
new SimpleAttributeDefinitionBuilder(Constants.Model.REQUEST_BINDING, ModelType.STRING, true)
.setXmlName(Constants.XML.REQUEST_BINDING)
.build();
static final SimpleAttributeDefinition RESPONSE_BINDING =
new SimpleAttributeDefinitionBuilder(Constants.Model.RESPONSE_BINDING, ModelType.STRING, true)
.setXmlName(Constants.XML.RESPONSE_BINDING)
.build();
static final SimpleAttributeDefinition BINDING_URL =
new SimpleAttributeDefinitionBuilder(Constants.Model.BINDING_URL, ModelType.STRING, true)
.setXmlName(Constants.XML.BINDING_URL)
.build();
static final SimpleAttributeDefinition ASSERTION_CONSUMER_SERVICE_URL =
new SimpleAttributeDefinitionBuilder(Constants.Model.ASSERTION_CONSUMER_SERVICE_URL, ModelType.STRING, true)
.setXmlName(Constants.XML.ASSERTION_CONSUMER_SERVICE_URL)
.build();
static final SimpleAttributeDefinition[] ATTRIBUTES = {SIGN_REQUEST, VALIDATE_RESPONSE_SIGNATURE, VALIDATE_ASSERTION_SIGNATURE, REQUEST_BINDING, RESPONSE_BINDING, BINDING_URL, ASSERTION_CONSUMER_SERVICE_URL};
static final HashMap<String, SimpleAttributeDefinition> ATTRIBUTE_MAP = new HashMap<>();
static {
for (SimpleAttributeDefinition def : ATTRIBUTES) {
ATTRIBUTE_MAP.put(def.getXmlName(), def);
}
}
static SimpleAttributeDefinition lookup(String xmlName) {
return ATTRIBUTE_MAP.get(xmlName);
}
}

View file

@ -1,59 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.dmr.ModelNode;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class Util {
public static ModelNode createAddOperation(final PathAddress address) {
return createOperation(ModelDescriptionConstants.ADD, address);
}
public static ModelNode createAddOperation() {
return createEmptyOperation(ModelDescriptionConstants.ADD, null);
}
public static ModelNode createRemoveOperation(final PathAddress address) {
return createOperation(ModelDescriptionConstants.REMOVE, address);
}
public static ModelNode createOperation(final String operationName, final PathAddress address) {
return createEmptyOperation(operationName, address);
}
public static ModelNode createEmptyOperation(String operationName, final PathAddress address) {
ModelNode op = new ModelNode();
op.get(OP).set(operationName);
if (address != null) {
op.get(OP_ADDR).set(address.toModelNode());
} else {
// Just establish the standard structure; caller can fill in address later
op.get(OP_ADDR);
}
return op;
}
}

View file

@ -1,49 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7.logging;
import org.jboss.logging.BasicLogger;
import org.jboss.logging.LogMessage;
import org.jboss.logging.Logger;
import org.jboss.logging.Message;
import org.jboss.logging.MessageLogger;
import static org.jboss.logging.Logger.Level.DEBUG;
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");
@LogMessage(level = INFO)
@Message(value = "Keycloak SAML subsystem override for deployment %s")
void deploymentSecured(String deployment);
@LogMessage(level = DEBUG)
@Message(value = "Keycloak SAML has overriden and secured deployment %s")
void warSecured(String deployment);
}

View file

@ -1,34 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7.logging;
import org.jboss.logging.MessageBundle;
import org.jboss.logging.Messages;
/**
* 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 = "TLIP")
public interface KeycloakMessages {
/**
* The messages
*/
KeycloakMessages MESSAGES = Messages.getBundle(KeycloakMessages.class);
}

View file

@ -1,528 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7.xml;
import org.jboss.staxmapper.XMLExtendedStreamWriter;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.ArrayDeque;
import java.util.Iterator;
/**
* An XML stream writer which nicely formats the XML for configuration files.
*
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
*/
public final class FormattingXMLStreamWriter implements XMLExtendedStreamWriter, XMLStreamConstants {
private static final String NO_NAMESPACE = new String();
private final XMLStreamWriter delegate;
private final ArrayDeque<ArgRunnable> attrQueue = new ArrayDeque<ArgRunnable>();
private int level;
private int state = START_DOCUMENT;
private boolean indentEndElement = false;
private ArrayDeque<String> unspecifiedNamespaces = new ArrayDeque<String>();
public FormattingXMLStreamWriter(final XMLStreamWriter delegate) {
this.delegate = delegate;
unspecifiedNamespaces.push(NO_NAMESPACE);
}
private void nl() throws XMLStreamException {
delegate.writeCharacters("\n");
}
private void indent() throws XMLStreamException {
int level = this.level;
final XMLStreamWriter delegate = this.delegate;
for (int i = 0; i < level; i ++) {
delegate.writeCharacters(" ");
}
}
private interface ArgRunnable {
public void run(int arg) throws XMLStreamException;
}
@Override
public void setUnspecifiedElementNamespace(final String namespace) {
ArrayDeque<String> namespaces = this.unspecifiedNamespaces;
namespaces.pop();
namespaces.push(namespace == null ? NO_NAMESPACE : namespace);
}
private String nestUnspecifiedNamespace() {
ArrayDeque<String> namespaces = unspecifiedNamespaces;
String clone = namespaces.getFirst();
namespaces.push(clone);
return clone;
}
@Override
public void writeStartElement(final String localName) throws XMLStreamException {
ArrayDeque<String> namespaces = unspecifiedNamespaces;
String namespace = namespaces.getFirst();
if (namespace == null ? NO_NAMESPACE != null : ! namespace.equals(NO_NAMESPACE)) {
writeStartElement(namespace, localName);
return;
}
unspecifiedNamespaces.push(namespace);
// If this is a nested element flush the outer
runAttrQueue();
nl();
indent();
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
if (arg == 0) {
delegate.writeStartElement(localName);
} else {
delegate.writeEmptyElement(localName);
}
}
});
level++;
state = START_ELEMENT;
indentEndElement = false;
}
@Override
public void writeStartElement(final String namespaceURI, final String localName) throws XMLStreamException {
nestUnspecifiedNamespace();
// If this is a nested element flush the outer
runAttrQueue();
nl();
indent();
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
if (arg == 0) {
delegate.writeStartElement(namespaceURI, localName);
} else {
delegate.writeEmptyElement(namespaceURI, localName);
}
}
});
level++;
state = START_ELEMENT;
indentEndElement = false;
}
@Override
public void writeStartElement(final String prefix, final String localName, final String namespaceURI) throws XMLStreamException {
nestUnspecifiedNamespace();
// If this is a nested element flush the outer
runAttrQueue();
nl();
indent();
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
if (arg == 0) {
delegate.writeStartElement(prefix, localName, namespaceURI);
} else {
delegate.writeEmptyElement(prefix, localName, namespaceURI);
}
}
});
level++;
state = START_ELEMENT;
indentEndElement = false;
}
@Override
public void writeEmptyElement(final String namespaceURI, final String localName) throws XMLStreamException {
runAttrQueue();
nl();
indent();
delegate.writeEmptyElement(namespaceURI, localName);
state = END_ELEMENT;
}
@Override
public void writeEmptyElement(final String prefix, final String localName, final String namespaceURI) throws XMLStreamException {
runAttrQueue();
nl();
indent();
delegate.writeEmptyElement(prefix, localName, namespaceURI);
state = END_ELEMENT;
}
@Override
public void writeEmptyElement(final String localName) throws XMLStreamException {
String namespace = unspecifiedNamespaces.getFirst();
if (namespace == null ? NO_NAMESPACE != null : ! namespace.equals(NO_NAMESPACE)) {
writeEmptyElement(namespace, localName);
return;
}
runAttrQueue();
nl();
indent();
delegate.writeEmptyElement(localName);
state = END_ELEMENT;
}
@Override
public void writeEndElement() throws XMLStreamException {
level--;
if (state != START_ELEMENT) {
runAttrQueue();
if (state != CHARACTERS || indentEndElement) {
nl();
indent();
indentEndElement = false;
}
delegate.writeEndElement();
} else {
// Change the start element to an empty element
ArgRunnable start = attrQueue.poll();
if (start == null) {
delegate.writeEndElement();
} else {
start.run(1);
// Write everything else
runAttrQueue();
}
}
unspecifiedNamespaces.pop();
state = END_ELEMENT;
}
private void runAttrQueue() throws XMLStreamException {
ArgRunnable attr;
while ((attr = attrQueue.poll()) != null) {
attr.run(0);
}
}
@Override
public void writeEndDocument() throws XMLStreamException {
delegate.writeEndDocument();
state = END_DOCUMENT;
}
@Override
public void close() throws XMLStreamException {
delegate.close();
state = END_DOCUMENT;
}
@Override
public void flush() throws XMLStreamException {
delegate.flush();
}
@Override
public void writeAttribute(final String localName, final String value) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
try {
delegate.writeAttribute(localName, value);
} catch (XMLStreamException e) {
throw new UndeclaredThrowableException(e);
}
}
});
}
@Override
public void writeAttribute(final String prefix, final String namespaceURI, final String localName, final String value) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
delegate.writeAttribute(prefix, namespaceURI, localName, value);
}
});
}
@Override
public void writeAttribute(final String namespaceURI, final String localName, final String value) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
delegate.writeAttribute(namespaceURI, localName, value);
}
});
}
@Override
public void writeAttribute(final String localName, final String[] values) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
delegate.writeAttribute(localName, join(values));
}
});
}
@Override
public void writeAttribute(final String prefix, final String namespaceURI, final String localName, final String[] values) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
delegate.writeAttribute(prefix, namespaceURI, localName, join(values));
}
});
}
@Override
public void writeAttribute(final String namespaceURI, final String localName, final String[] values) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
delegate.writeAttribute(namespaceURI, localName, join(values));
}
});
}
@Override
public void writeAttribute(final String localName, final Iterable<String> values) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
delegate.writeAttribute(localName, join(values));
}
});
}
@Override
public void writeAttribute(final String prefix, final String namespaceURI, final String localName, final Iterable<String> values) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
delegate.writeAttribute(prefix, namespaceURI, localName, join(values));
}
});
}
@Override
public void writeAttribute(final String namespaceURI, final String localName, final Iterable<String> values) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
delegate.writeAttribute(namespaceURI, localName, join(values));
}
});
}
@Override
public void writeNamespace(final String prefix, final String namespaceURI) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
delegate.writeNamespace(prefix, namespaceURI);
}
});
}
@Override
public void writeDefaultNamespace(final String namespaceURI) throws XMLStreamException {
attrQueue.add(new ArgRunnable() {
public void run(int arg) throws XMLStreamException {
delegate.writeDefaultNamespace(namespaceURI);
}
});
}
@Override
public void writeComment(final String data) throws XMLStreamException {
runAttrQueue();
nl();
nl();
indent();
final StringBuilder b = new StringBuilder(data.length());
final Iterator<String> i = Spliterator.over(data, '\n');
if (! i.hasNext()) {
return;
} else {
final String first = i.next();
if (! i.hasNext()) {
delegate.writeComment(" " + first + " ");
state = COMMENT;
return;
} else {
b.append('\n');
for (int q = 0; q < level; q++) {
b.append(" ");
}
b.append(" ~ ");
b.append(first);
do {
b.append('\n');
for (int q = 0; q < level; q++) {
b.append(" ");
}
b.append(" ~ ");
b.append(i.next());
} while (i.hasNext());
}
b.append('\n');
for (int q = 0; q < level; q ++) {
b.append(" ");
}
b.append(" ");
delegate.writeComment(b.toString());
state = COMMENT;
}
}
@Override
public void writeProcessingInstruction(final String target) throws XMLStreamException {
runAttrQueue();
nl();
indent();
delegate.writeProcessingInstruction(target);
state = PROCESSING_INSTRUCTION;
}
@Override
public void writeProcessingInstruction(final String target, final String data) throws XMLStreamException {
runAttrQueue();
nl();
indent();
delegate.writeProcessingInstruction(target, data);
state = PROCESSING_INSTRUCTION;
}
@Override
public void writeCData(final String data) throws XMLStreamException {
runAttrQueue();
delegate.writeCData(data);
state = CDATA;
}
@Override
public void writeDTD(final String dtd) throws XMLStreamException {
nl();
indent();
delegate.writeDTD(dtd);
state = DTD;
}
@Override
public void writeEntityRef(final String name) throws XMLStreamException {
runAttrQueue();
delegate.writeEntityRef(name);
state = ENTITY_REFERENCE;
}
@Override
public void writeStartDocument() throws XMLStreamException {
delegate.writeStartDocument();
nl();
state = START_DOCUMENT;
}
@Override
public void writeStartDocument(final String version) throws XMLStreamException {
delegate.writeStartDocument(version);
nl();
state = START_DOCUMENT;
}
@Override
public void writeStartDocument(final String encoding, final String version) throws XMLStreamException {
delegate.writeStartDocument(encoding, version);
nl();
state = START_DOCUMENT;
}
@Override
public void writeCharacters(final String text) throws XMLStreamException {
runAttrQueue();
if (state != CHARACTERS) {
nl();
indent();
}
final Iterator<String> iterator = Spliterator.over(text, '\n');
while (iterator.hasNext()) {
final String t = iterator.next();
delegate.writeCharacters(t);
if (iterator.hasNext()) {
nl();
indent();
}
}
state = CHARACTERS;
indentEndElement = true;
}
@Override
public void writeCharacters(final char[] text, final int start, final int len) throws XMLStreamException {
runAttrQueue();
delegate.writeCharacters(text, start, len);
state = CHARACTERS;
}
@Override
public String getPrefix(final String uri) throws XMLStreamException {
return delegate.getPrefix(uri);
}
@Override
public void setPrefix(final String prefix, final String uri) throws XMLStreamException {
delegate.setPrefix(prefix, uri);
}
@Override
public void setDefaultNamespace(final String uri) throws XMLStreamException {
runAttrQueue();
delegate.setDefaultNamespace(uri);
}
@Override
public void setNamespaceContext(final NamespaceContext context) throws XMLStreamException {
delegate.setNamespaceContext(context);
}
@Override
public NamespaceContext getNamespaceContext() {
return delegate.getNamespaceContext();
}
@Override
public Object getProperty(final String name) throws IllegalArgumentException {
return delegate.getProperty(name);
}
private static String join(final String[] values) {
final StringBuilder b = new StringBuilder();
for (int i = 0, valuesLength = values.length; i < valuesLength; i++) {
final String s = values[i];
if (s != null) {
if (i > 0) {
b.append(' ');
}
b.append(s);
}
}
return b.toString();
}
private static String join(final Iterable<String> values) {
final StringBuilder b = new StringBuilder();
Iterator<String> iterator = values.iterator();
while (iterator.hasNext()) {
final String s = iterator.next();
if (s != null) {
b.append(s);
if (iterator.hasNext()) b.append(' ');
}
}
return b.toString();
}
}

View file

@ -1,61 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7.xml;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
*/
final class Spliterator implements Iterator<String> {
private final String subject;
private final char delimiter;
private int i;
Spliterator(final String subject, final char delimiter) {
this.subject = subject;
this.delimiter = delimiter;
i = 0;
}
static Spliterator over(String subject, char delimiter) {
return new Spliterator(subject, delimiter);
}
public boolean hasNext() {
return i != -1;
}
public String next() {
final int i = this.i;
if (i == -1) {
throw new NoSuchElementException();
}
int n = subject.indexOf(delimiter, i);
try {
return n == -1 ? subject.substring(i) : subject.substring(i, n);
} finally {
this.i = n == -1 ? -1 : n + 1;
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}

View file

@ -1,18 +0,0 @@
#
# Copyright 2016 Red Hat, Inc. and/or its affiliates
# and other contributors as indicated by the @author tags.
#
# 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.
#
org.keycloak.subsystem.saml.as7.KeycloakSamlExtension

View file

@ -1,105 +0,0 @@
#
# Copyright 2016 Red Hat, Inc. and/or its affiliates
# and other contributors as indicated by the @author tags.
#
# 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.
#
keycloak-saml.subsystem=Keycloak adapter subsystem
keycloak-saml.subsystem.add=Operation Adds Keycloak adapter subsystem
keycloak-saml.subsystem.remove=Operation removes Keycloak adapter subsystem
keycloak-saml.subsystem.secure-deployment=A deployment secured by Keycloak.
keycloak-saml.secure-deployment=A deployment secured by Keycloak
keycloak-saml.secure-deployment.add=Add a deployment to be secured by Keycloak
keycloak-saml.secure-deployment.remove=Remove a deployment to be secured by Keycloak
keycloak-saml.secure-deployment.SP=A security provider configuration for secure deployment
keycloak-saml.SP=A security provider configuration for secure deployment
keycloak-saml.SP.add=Add a security provider configuration to deployment secured by Keycloak SAML
keycloak-saml.SP.remove=Remove a security provider definition from deployment secured by Keycloak SAML
keycloak-saml.SP.sslPolicy=SSL Policy to use
keycloak-saml.SP.nameIDPolicyFormat=Name ID policy format URN
keycloak-saml.SP.logoutPage=URI to a logout page
keycloak-saml.SP.forceAuthentication=Redirected unauthenticated request to a login page
keycloak-saml.SP.keepDOMAssertion=Attribute to inject the DOM representation of the assertion into the SamlPrincipal (respecting the original syntax)
keycloak-saml.SP.isPassive=If user isn't logged in just return with an error. Used to check if a user is already logged in or not
keycloak-saml.SP.turnOffChangeSessionIdOnLogin=The session id is changed by default on a successful login. Change this to true if you want to turn this off
keycloak-saml.SP.autodetectBearerOnly=Set to true if the application serves both a web application and web services (e.g. SOAP or REST). It allows redirection of unauthenticated users of the web application to the Keycloak login page, but send an HTTP 401 status code to unauthenticated SOAP or REST clients instead
keycloak-saml.SP.RoleIdentifiers=Role identifiers
keycloak-saml.SP.PrincipalNameMapping-policy=Principal name mapping policy
keycloak-saml.SP.PrincipalNameMapping-attribute-name=Principal name mapping attribute name
keycloak-saml.SP.Key=A key definition
keycloak-saml.SP.IDP=Identity provider definition
keycloak-saml.SP.roleMappingsProviderId=The string that identifies the role mappings provider to be used within the SP
keycloak-saml.SP.roleMappingsProviderConfig=The configuration properties of the role mappings provider
keycloak-saml.Key=A key configuration for service provider or identity provider
keycloak-saml.Key.add=Add a key definition
keycloak-saml.Key.remove=Remove a key definition
keycloak-saml.Key.signing=Key can be used for signing
keycloak-saml.Key.encryption=Key can be used for encryption
keycloak-saml.Key.PrivateKeyPem=Private key string in pem format
keycloak-saml.Key.PublicKeyPem=Public key string in pem format
keycloak-saml.Key.CertificatePem=Certificate key string in pem format
keycloak-saml.Key.KeyStore=Key store definition
keycloak-saml.Key.KeyStore.file=Key store filesystem path
keycloak-saml.Key.KeyStore.resource=Key store resource URI
keycloak-saml.Key.KeyStore.password=Key store password
keycloak-saml.Key.KeyStore.type=Key store format
keycloak-saml.Key.KeyStore.alias=Key alias
keycloak-saml.Key.KeyStore.PrivateKey-alias=Private key alias
keycloak-saml.Key.KeyStore.PrivateKey-password=Private key password
keycloak-saml.Key.KeyStore.Certificate-alias=Certificate alias
keycloak-saml.IDP=An identity provider configuration
keycloak-saml.IDP.add=Add an identity provider
keycloak-saml.IDP.remove=Remove an identity provider
keycloak-saml.IDP.signaturesRequired=Require signatures for SingleSignOnService and SingleLogoutService
keycloak-saml.IDP.signatureAlgorithm=Signature algorithm
keycloak-saml.IDP.signatureCanonicalizationMethod=Signature canonicalization method
keycloak-saml.IDP.metadataUrl=The URL used to retrieve the IDP metadata from
keycloak-saml.IDP.SingleSignOnService=Single sign-on configuration
keycloak-saml.IDP.SingleSignOnService.signRequest=Sign SSO requests
keycloak-saml.IDP.SingleSignOnService.validateResponseSignature=Validate an SSO response signature
keycloak-saml.IDP.SingleSignOnService.validateAssertionSignature=Validate an SSO assertion signature
keycloak-saml.IDP.SingleSignOnService.requestBinding=HTTP method to use for requests
keycloak-saml.IDP.SingleSignOnService.responseBinding=HTTP method to use for responses
keycloak-saml.IDP.SingleSignOnService.bindingUrl=SSO endpoint URL
keycloak-saml.IDP.SingleSignOnService.assertionConsumerServiceUrl=Endpoint of Assertion Consumer Service at SP
keycloak-saml.IDP.SingleLogoutService=Single logout configuration
keycloak-saml.IDP.SingleLogoutService.validateRequestSignature=Validate a SingleLogoutService request signature
keycloak-saml.IDP.SingleLogoutService.validateResponseSignature=Validate a SingleLogoutService response signature
keycloak-saml.IDP.SingleLogoutService.signRequest=Sign SingleLogoutService requests
keycloak-saml.IDP.SingleLogoutService.signResponse=Sign SingleLogoutService responses
keycloak-saml.IDP.SingleLogoutService.requestBinding=HTTP method to use for request
keycloak-saml.IDP.SingleLogoutService.responseBinding=HTTP method to use for response
keycloak-saml.IDP.SingleLogoutService.postBindingUrl=Endpoint URL for posting
keycloak-saml.IDP.SingleLogoutService.redirectBindingUrl=Endpoint URL for redirects
keycloak-saml.IDP.Key=Key definition for identity provider
keycloak-saml.IDP.AllowedClockSkew=Allowed clock skew between the IDP and the SP
keycloak-saml.IDP.AllowedClockSkew.value=Allowed clock skew value between the IDP and the SP
keycloak-saml.IDP.AllowedClockSkew.unit=Time unit for the value of the clock skew. Values: MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS
keycloak-saml.IDP.HttpClient=Configuration of HTTP client used for automatic retrieval of certificates for signature validation
keycloak-saml.IDP.HttpClient.allowAnyHostname=Define if hostname validation should be disabled (true) or not (false)
keycloak-saml.IDP.HttpClient.clientKeystore=Path to the keystore that contains client certificates for two-way SSL
keycloak-saml.IDP.HttpClient.clientKeystorePassword=The keystore password
keycloak-saml.IDP.HttpClient.connectionPoolSize=The number of pooled connections
keycloak-saml.IDP.HttpClient.disableTrustManager=Define if SSL certificate validation should be disabled (true) or not (false)
keycloak-saml.IDP.HttpClient.proxyUrl=URL to the HTTP proxy, if applicable
keycloak-saml.IDP.HttpClient.truststore=Path to the truststore used to validate the IDP certificates
keycloak-saml.IDP.HttpClient.truststorePassword=The truststore password
keycloak-saml.IDP.HttpClient.socketTimeout=Timeout for socket waiting for data in milliseconds
keycloak-saml.IDP.HttpClient.connectionTimeout=Timeout for establishing the connection with the remote host in milliseconds
keycloak-saml.IDP.HttpClient.connectionTtl=The connection time to live in milliseconds

View file

@ -1,305 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:jboss:domain:keycloak-saml:1.1"
xmlns="urn:jboss:domain:keycloak-saml: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 SAML adapter subsystem, used to register deployments managed by Keycloak SAML adapter
]]>
</xs:documentation>
</xs:annotation>
<xs:all>
<xs:element name="secure-deployment" minOccurs="0" type="secure-deployment-type"/>
</xs:all>
</xs:complexType>
<xs:complexType name="secure-deployment-type">
<xs:all>
<xs:element name="SP" minOccurs="1" maxOccurs="1" type="sp-type"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The name of the realm.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="sp-type">
<xs:all>
<xs:element name="Keys" minOccurs="0" maxOccurs="1" type="keys-type"/>
<xs:element name="PrincipalNameMapping" minOccurs="0" maxOccurs="1" type="principal-name-mapping-type"/>
<xs:element name="RoleIdentifiers" minOccurs="0" maxOccurs="1" type="role-identifiers-type"/>
<xs:element name="IDP" minOccurs="1" maxOccurs="1" type="identity-provider-type"/>
</xs:all>
<xs:attribute name="entityID" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The entity ID for SAML service provider</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="sslPolicy" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The ssl policy</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="nameIDPolicyFormat" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Name ID policy format URN</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="logoutPage" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>URI to a logout page</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="forceAuthentication" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Redirected unauthenticated request to a login page</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="isPassive" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>If user isn't logged in just return with an error. Used to check if a user is already logged in or not</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="turnOffChangeSessionIdOnLogin" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>The session id is changed by default on a successful login. Change this to true if you want to turn this off</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="identity-provider-type">
<xs:all minOccurs="1" maxOccurs="1">
<xs:element name="SingleSignOnService" minOccurs="1" maxOccurs="1" type="single-signon-type"/>
<xs:element name="SingleLogoutService" minOccurs="0" maxOccurs="1" type="single-logout-type"/>
<xs:element name="Keys" minOccurs="0" maxOccurs="1" type="keys-type"/>
</xs:all>
<xs:attribute name="entityID" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The entity ID for SAML service provider</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signaturesRequired" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Require signatures for single-sign-on and single-logout</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signatureAlgorithm" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Algorithm used for signatures</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signatureCanonicalizationMethod" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Canonicalization method used for signatures</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="single-signon-type">
<xs:attribute name="signRequest" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Sign the SSO requests</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Validate the SSO response signature</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateAssertionSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Validate the SSO assertion signature</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="requestBinding" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>HTTP method to use for requests</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="responseBinding" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>HTTP method to use for response</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="bindingUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>SSO endpoint URL</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="assertionConsumerServiceUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Endpoint of Assertion Consumer Service at SP</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="single-logout-type">
<xs:attribute name="validateRequestSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Validate a single-logout request signature</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Validate a single-logout response signature</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signRequest" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Sign single-logout requests</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signResponse" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Sign single-logout responses</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="requestBinding" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>HTTP method to use for request</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="responseBinding" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>HTTP method to use for response</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="postBindingUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Endpoint URL for posting</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="redirectBindingUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Endpoint URL for redirects</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="keys-type">
<xs:sequence>
<xs:element name="Key" minOccurs="1" maxOccurs="2" type="key-type"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="key-type">
<xs:all>
<xs:element name="KeyStore" minOccurs="0" maxOccurs="1" type="keystore-type"/>
<xs:element name="PrivateKeyPem" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element name="PublicKeyPem" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element name="CertificatePem" minOccurs="0" maxOccurs="1" type="xs:string"/>
</xs:all>
<xs:attribute name="signing" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Key can be used for signing</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="encryption" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Key can be used for encryption</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="keystore-type">
<xs:sequence minOccurs="0" maxOccurs="1">
<xs:element name="PrivateKey" minOccurs="0" maxOccurs="1" type="privatekey-type"/>
<xs:element name="Certificate" minOccurs="0" maxOccurs="1" type="certificate-type"/>
</xs:sequence>
<xs:attribute name="file" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key store filesystem path</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="resource" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key store resource URI</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="password" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Key store password</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="type" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key store format</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="alias" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key alias</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="privatekey-type">
<xs:attribute name="alias" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Private key alias</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="password" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Private key password</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="certificate-type">
<xs:attribute name="alias" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Certificate alias</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="principal-name-mapping-type">
<xs:attribute name="policy" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Principal name mapping policy. Possible values: FROM_NAME_ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="attribute" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Name of the attribute to use for principal name mapping</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="role-identifiers-type">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="Attribute" minOccurs="0" maxOccurs="unbounded" type="attribute-type"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="attribute-type">
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Role attribute</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:schema>

View file

@ -1,368 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2019 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:jboss:domain:keycloak-saml:1.2"
xmlns="urn:jboss:domain:keycloak-saml:1.2"
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 SAML adapter subsystem, used to register deployments managed by Keycloak SAML adapter
]]>
</xs:documentation>
</xs:annotation>
<xs:all>
<xs:element name="secure-deployment" minOccurs="0" type="secure-deployment-type"/>
</xs:all>
</xs:complexType>
<xs:complexType name="secure-deployment-type">
<xs:all>
<xs:element name="SP" minOccurs="1" maxOccurs="1" type="sp-type"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The name of the realm.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="sp-type">
<xs:all>
<xs:element name="Keys" minOccurs="0" maxOccurs="1" type="keys-type"/>
<xs:element name="PrincipalNameMapping" minOccurs="0" maxOccurs="1" type="principal-name-mapping-type"/>
<xs:element name="RoleIdentifiers" minOccurs="0" maxOccurs="1" type="role-identifiers-type"/>
<xs:element name="RoleMappingsProvider" minOccurs="0" maxOccurs="1" type="role-mappings-provider-type"/>
<xs:element name="IDP" minOccurs="1" maxOccurs="1" type="identity-provider-type"/>
</xs:all>
<xs:attribute name="entityID" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The entity ID for SAML service provider</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="sslPolicy" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The ssl policy</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="nameIDPolicyFormat" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Name ID policy format URN</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="logoutPage" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>URI to a logout page</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="forceAuthentication" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Redirected unauthenticated request to a login page</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="keepDOMAssertion" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Attribute to inject the DOM representation of the assertion into the SamlPrincipal (respecting the original syntax). Default value is false</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="isPassive" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>If user isn't logged in just return with an error. Used to check if a user is already logged in or not</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="turnOffChangeSessionIdOnLogin" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>The session id is changed by default on a successful login. Change this to true if you want to turn this off</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="identity-provider-type">
<xs:all minOccurs="1" maxOccurs="1">
<xs:element name="SingleSignOnService" minOccurs="1" maxOccurs="1" type="single-signon-type"/>
<xs:element name="SingleLogoutService" minOccurs="0" maxOccurs="1" type="single-logout-type"/>
<xs:element name="Keys" minOccurs="0" maxOccurs="1" type="keys-type"/>
<xs:element name="AllowedClockSkew" type="allowed-clock-skew-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>This defines the allowed clock skew between IDP and SP in milliseconds. The default value is 0.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="entityID" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The entity ID for SAML service provider</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signaturesRequired" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Require signatures for single-sign-on and single-logout</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signatureAlgorithm" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Algorithm used for signatures</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signatureCanonicalizationMethod" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Canonicalization method used for signatures</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="single-signon-type">
<xs:attribute name="signRequest" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Sign the SSO requests</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Validate the SSO response signature</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateAssertionSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Validate the SSO assertion signature</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="requestBinding" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>HTTP method to use for requests</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="responseBinding" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>HTTP method to use for response</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="bindingUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>SSO endpoint URL</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="assertionConsumerServiceUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Endpoint of Assertion Consumer Service at SP</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="single-logout-type">
<xs:attribute name="validateRequestSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Validate a single-logout request signature</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Validate a single-logout response signature</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signRequest" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Sign single-logout requests</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signResponse" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Sign single-logout responses</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="requestBinding" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>HTTP method to use for request</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="responseBinding" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>HTTP method to use for response</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="postBindingUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Endpoint URL for posting</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="redirectBindingUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Endpoint URL for redirects</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="keys-type">
<xs:sequence>
<xs:element name="Key" minOccurs="1" maxOccurs="2" type="key-type"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="key-type">
<xs:all>
<xs:element name="KeyStore" minOccurs="0" maxOccurs="1" type="keystore-type"/>
<xs:element name="PrivateKeyPem" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element name="PublicKeyPem" minOccurs="0" maxOccurs="1" type="xs:string"/>
<xs:element name="CertificatePem" minOccurs="0" maxOccurs="1" type="xs:string"/>
</xs:all>
<xs:attribute name="signing" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Key can be used for signing</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="encryption" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Key can be used for encryption</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="keystore-type">
<xs:sequence minOccurs="0" maxOccurs="1">
<xs:element name="PrivateKey" minOccurs="0" maxOccurs="1" type="privatekey-type"/>
<xs:element name="Certificate" minOccurs="0" maxOccurs="1" type="certificate-type"/>
</xs:sequence>
<xs:attribute name="file" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key store filesystem path</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="resource" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key store resource URI</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="password" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Key store password</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="type" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key store format</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="alias" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key alias</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="privatekey-type">
<xs:attribute name="alias" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Private key alias</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="password" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Private key password</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="certificate-type">
<xs:attribute name="alias" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Certificate alias</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="principal-name-mapping-type">
<xs:attribute name="policy" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Principal name mapping policy. Possible values: FROM_NAME_ID</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="attribute" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Name of the attribute to use for principal name mapping</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="role-identifiers-type">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="Attribute" minOccurs="0" maxOccurs="unbounded" type="attribute-type"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="attribute-type">
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Role attribute</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="role-mappings-provider-type">
<xs:sequence>
<xs:element name="Property" type="property-type" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Specifies a configuration property for the provider.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The id of the role mappings provider that is to be used. Example: properties-based-provider.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="property-type">
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The name (key) of the configuration property.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="value" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The value of the configuration property.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="allowed-clock-skew-type">
<xs:annotation>
<xs:documentation>The value is the allowed clock skew between the IDP and the SP.</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:positiveInteger">
<xs:attribute name="unit" type="clock-skew-unit-type"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="clock-skew-unit-type">
<xs:annotation>
<xs:documentation>Time unit for the value of the clock skew.</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="MINUTES" />
<xs:enumeration value="SECONDS" />
<xs:enumeration value="MILLISECONDS" />
<xs:enumeration value="MICROSECONDS" />
<xs:enumeration value="NANOSECONDS" />
</xs:restriction>
</xs:simpleType>
</xs:schema>

View file

@ -1,570 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2020 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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.autodetect
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:jboss:domain:keycloak-saml:1.3"
xmlns="urn:jboss:domain:keycloak-saml:1.3"
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 SAML adapter subsystem, used to register deployments managed by Keycloak SAML adapter
]]>
</xs:documentation>
</xs:annotation>
<xs:all>
<xs:element name="secure-deployment" minOccurs="0" type="secure-deployment-type"/>
</xs:all>
</xs:complexType>
<xs:complexType name="secure-deployment-type">
<xs:all>
<xs:element name="SP" minOccurs="0" maxOccurs="1" type="sp-type"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The name of the deployment</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="sp-type">
<xs:all>
<xs:element name="Keys" type="keys-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>
List of service provider encryption and validation keys.
If the IDP requires that the client application (SP) sign all of its requests and/or if the IDP will encrypt assertions, you must define the keys used to do this. For client signed documents you must define both the private and public key or certificate that will be used to sign documents. For encryption, you only have to define the private key that will be used to decrypt.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="PrincipalNameMapping" type="principal-name-mapping-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>When creating a Java Principal object that you obtain from methods like HttpServletRequest.getUserPrincipal(), you can define what name that is returned by the Principal.getName() method.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="RoleIdentifiers" type="role-identifiers-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Defines what SAML attributes within the assertion received from the user should be used as role identifiers within the Java EE Security Context for the user.
By default Role attribute values are converted to Java EE roles. Some IDPs send roles via a member or memberOf attribute assertion. You can define one or more Attribute elements to specify which SAML attributes must be converted into roles.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="RoleMappingsProvider" type="role-mappings-provider-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Specifies the role mappings provider implementation that will be used to map the roles extracted from the SAML assertion into the final set of roles
that will be assigned to the principal. A provider is typically used to map roles retrieved from third party IDPs into roles that exist in the JEE application environment. It can also
assign extra roles to the assertion principal (for example, by connecting to an LDAP server to obtain more roles) or remove some of the roles that were set by the IDP.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="IDP" type="idp-type" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:documentation>Describes configuration of SAML identity provider for this service provider.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="entityID" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>This is the identifier for this client. The IDP needs this value to determine who the client is that is communicating with it.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="sslPolicy" type="ssl-policy-type" use="optional">
<xs:annotation>
<xs:documentation>SSL policy the adapter will enforce.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="nameIDPolicyFormat" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>SAML clients can request a specific NameID Subject format. Fill in this value if you want a specific format. It must be a standard SAML format identifier, i.e. urn:oasis:names:tc:SAML:2.0:nameid-format:transient. By default, no special format is requested.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="logoutPage" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>URL of the logout page.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="forceAuthentication" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>SAML clients can request that a user is re-authenticated even if they are already logged in at the IDP. Default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="keepDOMAssertion" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Attribute to inject the DOM representation of the assertion into the SamlPrincipal (respecting the original syntax). Default value is false</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="isPassive" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>SAML clients can request that a user is never asked to authenticate even if they are not logged in at the IDP. Set this to true if you want this. Do not use together with forceAuthentication as they are opposite. Default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="turnOffChangeSessionIdOnLogin" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>The session id is changed by default on a successful login on some platforms to plug a security attack vector. Change this to true to disable this. It is recommended you do not turn it off. Default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="autodetectBearerOnly" type="xs:boolean" use="optional" default="false">
<xs:annotation>
<xs:documentation>This should be set to true if your application serves both a web application and web services (e.g. SOAP or REST). It allows you to redirect unauthenticated users of the web application to the Keycloak login page, but send an HTTP 401 status code to unauthenticated SOAP or REST clients instead as they would not understand a redirect to the login page. Keycloak auto-detects SOAP or REST clients based on typical headers like X-Requested-With, SOAPAction or Accept. The default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="keys-type">
<xs:sequence>
<xs:element name="Key" type="key-type" minOccurs="1" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Describes a single key used for signing or encryption.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="key-type">
<xs:all>
<xs:element name="KeyStore" maxOccurs="1" minOccurs="0" type="key-store-type">
<xs:annotation>
<xs:documentation>Java keystore to load keys and certificates from.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="PrivateKeyPem" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Private key (PEM format)</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="PublicKeyPem" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Public key (PEM format)</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="CertificatePem" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Certificate key (PEM format)</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="signing" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Flag defining whether the key should be used for signing.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="encryption" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Flag defining whether the key should be used for encryption</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="key-store-type">
<xs:all>
<xs:element name="PrivateKey" maxOccurs="1" minOccurs="0" type="private-key-type">
<xs:annotation>
<xs:documentation>Private key declaration</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Certificate" type="certificate-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Certificate declaration</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="file" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>File path to the key store.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="resource" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>WAR resource path to the key store. This is a path used in method call to ServletContext.getResourceAsStream().</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="password" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The password of the key store.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="type" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key store format</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="alias" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key alias</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="private-key-type">
<xs:attribute name="alias" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Alias that points to the key or cert within the keystore.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="password" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Keystores require an additional password to access private keys. In the PrivateKey element you must define this password within a password attribute.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="certificate-type">
<xs:attribute name="alias" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Alias that points to the key or cert within the keystore.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="principal-name-mapping-type">
<xs:attribute name="policy" type="principal-name-mapping-policy-type" use="required">
<xs:annotation>
<xs:documentation>Policy used to populate value of Java Principal object obtained from methods like HttpServletRequest.getUserPrincipal().</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="attribute" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Name of the SAML assertion attribute to use within.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:simpleType name="principal-name-mapping-policy-type">
<xs:restriction base="xs:string">
<xs:enumeration value="FROM_NAME_ID">
<xs:annotation>
<xs:documentation>This policy just uses whatever the SAML subject value is. This is the default setting</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="FROM_ATTRIBUTE">
<xs:annotation>
<xs:documentation>This will pull the value from one of the attributes declared in the SAML assertion received from the server. You'll need to specify the name of the SAML assertion attribute to use within the attribute XML attribute.</xs:documentation>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ssl-policy-type">
<xs:restriction base="xs:string">
<xs:enumeration value="ALL">
<xs:annotation>
<xs:documentation>All requests must come in via HTTPS.</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="EXTERNAL">
<xs:annotation>
<xs:documentation>Only non-private IP addresses must come over the wire via HTTPS.</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="NONE">
<xs:annotation>
<xs:documentation>no requests are required to come over via HTTPS.</xs:documentation>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="signature-algorithm-type">
<xs:restriction base="xs:string">
<xs:enumeration value="RSA_SHA1"/>
<xs:enumeration value="RSA_SHA256"/>
<xs:enumeration value="RSA_SHA512"/>
<xs:enumeration value="DSA_SHA1"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="binding-type">
<xs:restriction base="xs:string">
<xs:enumeration value="POST"/>
<xs:enumeration value="REDIRECT"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="role-identifiers-type">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Attribute" maxOccurs="unbounded" minOccurs="0" type="attribute-type">
<xs:annotation>
<xs:documentation>Specifies SAML attribute to be converted into roles.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:complexType name="attribute-type">
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Specifies name of the SAML attribute to be converted into roles.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="role-mappings-provider-type">
<xs:sequence>
<xs:element name="Property" type="property-type" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Specifies a configuration property for the provider.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The id of the role mappings provider that is to be used. Example: properties-based-provider.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="property-type">
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The name (key) of the configuration property.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="value" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The value of the configuration property.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="idp-type">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="SingleSignOnService" maxOccurs="1" minOccurs="1" type="sign-on-type">
<xs:annotation>
<xs:documentation>Configuration of the login SAML endpoint of the IDP.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="SingleLogoutService" type="logout-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Configuration of the logout SAML endpoint of the IDP</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Keys" type="keys-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>The Keys sub element of IDP is only used to define the certificate or public key to use to verify documents signed by the IDP.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="HttpClient" type="http-client-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Configuration of HTTP client used for automatic obtaining of certificates containing public keys for IDP signature verification via SAML descriptor of the IDP.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="AllowedClockSkew" type="allowed-clock-skew-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>This defines the allowed clock skew between IDP and SP in milliseconds. The default value is 0.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="entityID" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>issuer ID of the IDP.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signaturesRequired" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>If set to true, the client adapter will sign every document it sends to the IDP. Also, the client will expect that the IDP will be signing any documents sent to it. This switch sets the default for all request and response types.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signatureAlgorithm" type="signature-algorithm-type" use="optional">
<xs:annotation>
<xs:documentation>Signature algorithm that the IDP expects signed documents to use. Defaults to RSA_SHA256</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signatureCanonicalizationMethod" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>This is the signature canonicalization method that the IDP expects signed documents to use. The default value is https://www.w3.org/2001/10/xml-exc-c14n# and should be good for most IDPs.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="encryption" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation></xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="metadataUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>The URL used to retrieve the IDP metadata, currently this is only used to pick up signing and encryption keys periodically which allow cycling of these keys on the IDP without manual changes on the SP side.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="sign-on-type">
<xs:attribute name="signRequest" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client sign authn requests? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client expect the IDP to sign the assertion response document sent back from an auhtn request? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateAssertionSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client expect the IDP to sign the individual assertions sent back from an auhtn request? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="requestBinding" type="binding-type" use="optional">
<xs:annotation>
<xs:documentation>SAML binding type used for communicating with the IDP. The default value is POST, but you can set it to REDIRECT as well.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="responseBinding" type="binding-type" use="optional">
<xs:annotation>
<xs:documentation>SAML allows the client to request what binding type it wants authn responses to use. This value maps to ProtocolBinding attribute in SAML AuthnRequest. The default is that the client will not request a specific binding type for responses.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="bindingUrl" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>This is the URL for the IDP login service that the client will send requests to.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="assertionConsumerServiceUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>URL of the assertion consumer service (ACS) where the IDP login service should send responses to. By default it is unset, relying on the IdP settings. When set, it must end in "/saml". This property is typically accompanied by the responseBinding attribute.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="logout-type">
<xs:attribute name="signRequest" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client sign authn requests? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signResponse" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client sign logout responses it sends to the IDP requests? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateRequestSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client expect signed logout request documents from the IDP? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client expect signed logout response documents from the IDP? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="requestBinding" type="binding-type" use="optional">
<xs:annotation>
<xs:documentation>This is the SAML binding type used for communicating SAML requests to the IDP. The default value is POST.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="responseBinding" type="binding-type" use="optional">
<xs:annotation>
<xs:documentation>This is the SAML binding type used for communicating SAML responses to the IDP. The default value is POST.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="postBindingUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>This is the URL for the IDP's logout service when using the POST binding. This setting is REQUIRED if using the POST binding.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="redirectBindingUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>This is the URL for the IDP's logout service when using the REDIRECT binding. This setting is REQUIRED if using the REDIRECT binding.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="http-client-type">
<xs:attribute name="allowAnyHostname" type="xs:boolean" use="optional" default="false">
<xs:annotation>
<xs:documentation>If the the IDP server requires HTTPS and this config option is set to true the IDP's certificate
is validated via the truststore, but host name validation is not done. This setting should only be used during
development and never in production as it will partly disable verification of SSL certificates.
This seting may be useful in test environments. The default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="clientKeystore" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>This is the file path to a keystore file. This keystore contains client certificate
for two-way SSL when the adapter makes HTTPS requests to the IDP server.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="clientKeystorePassword" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Password for the client keystore and for the client's key.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="connectionPoolSize" type="xs:int" use="optional" default="10">
<xs:annotation>
<xs:documentation>Defines number of pooled connections.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="disableTrustManager" type="xs:boolean" use="optional" default="false">
<xs:annotation>
<xs:documentation>If the the IDP server requires HTTPS and this config option is set to true you do not have to specify a truststore.
This setting should only be used during development and never in production as it will disable verification of SSL certificates.
The default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="proxyUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>URL to HTTP proxy to use for HTTP connections.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="truststore" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>The value is the file path to a keystore file. If you prefix the path with classpath:,
then the truststore will be obtained from the deployment's classpath instead. Used for outgoing
HTTPS communications to the IDP server. Client making HTTPS requests need
a way to verify the host of the server they are talking to. This is what the trustore does.
The keystore contains one or more trusted host certificates or certificate authorities.
You can create this truststore by extracting the public certificate of the IDP's SSL keystore.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="truststorePassword" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Password for the truststore keystore.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="allowed-clock-skew-type">
<xs:annotation>
<xs:documentation>The value is the allowed clock skew between the IDP and the SP.</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:positiveInteger">
<xs:attribute name="unit" type="clock-skew-unit-type"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="clock-skew-unit-type">
<xs:annotation>
<xs:documentation>Time unit for the value of the clock skew.</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="MINUTES" />
<xs:enumeration value="SECONDS" />
<xs:enumeration value="MILLISECONDS" />
<xs:enumeration value="MICROSECONDS" />
<xs:enumeration value="NANOSECONDS" />
</xs:restriction>
</xs:simpleType>
</xs:schema>

View file

@ -1,585 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2021 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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.autodetect
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:jboss:domain:keycloak-saml:1.4"
xmlns="urn:jboss:domain:keycloak-saml:1.4"
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 SAML adapter subsystem, used to register deployments managed by Keycloak SAML adapter
]]>
</xs:documentation>
</xs:annotation>
<xs:all>
<xs:element name="secure-deployment" minOccurs="0" type="secure-deployment-type"/>
</xs:all>
</xs:complexType>
<xs:complexType name="secure-deployment-type">
<xs:all>
<xs:element name="SP" minOccurs="0" maxOccurs="1" type="sp-type"/>
</xs:all>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The name of the deployment</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="sp-type">
<xs:all>
<xs:element name="Keys" type="keys-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>
List of service provider encryption and validation keys.
If the IDP requires that the client application (SP) sign all of its requests and/or if the IDP will encrypt assertions, you must define the keys used to do this. For client signed documents you must define both the private and public key or certificate that will be used to sign documents. For encryption, you only have to define the private key that will be used to decrypt.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="PrincipalNameMapping" type="principal-name-mapping-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>When creating a Java Principal object that you obtain from methods like HttpServletRequest.getUserPrincipal(), you can define what name that is returned by the Principal.getName() method.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="RoleIdentifiers" type="role-identifiers-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Defines what SAML attributes within the assertion received from the user should be used as role identifiers within the Java EE Security Context for the user.
By default Role attribute values are converted to Java EE roles. Some IDPs send roles via a member or memberOf attribute assertion. You can define one or more Attribute elements to specify which SAML attributes must be converted into roles.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="RoleMappingsProvider" type="role-mappings-provider-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Specifies the role mappings provider implementation that will be used to map the roles extracted from the SAML assertion into the final set of roles
that will be assigned to the principal. A provider is typically used to map roles retrieved from third party IDPs into roles that exist in the JEE application environment. It can also
assign extra roles to the assertion principal (for example, by connecting to an LDAP server to obtain more roles) or remove some of the roles that were set by the IDP.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="IDP" type="idp-type" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:documentation>Describes configuration of SAML identity provider for this service provider.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="entityID" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>This is the identifier for this client. The IDP needs this value to determine who the client is that is communicating with it.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="sslPolicy" type="ssl-policy-type" use="optional">
<xs:annotation>
<xs:documentation>SSL policy the adapter will enforce.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="nameIDPolicyFormat" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>SAML clients can request a specific NameID Subject format. Fill in this value if you want a specific format. It must be a standard SAML format identifier, i.e. urn:oasis:names:tc:SAML:2.0:nameid-format:transient. By default, no special format is requested.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="logoutPage" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>URL of the logout page.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="forceAuthentication" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>SAML clients can request that a user is re-authenticated even if they are already logged in at the IDP. Default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="keepDOMAssertion" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Attribute to inject the DOM representation of the assertion into the SamlPrincipal (respecting the original syntax). Default value is false</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="isPassive" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>SAML clients can request that a user is never asked to authenticate even if they are not logged in at the IDP. Set this to true if you want this. Do not use together with forceAuthentication as they are opposite. Default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="turnOffChangeSessionIdOnLogin" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>The session id is changed by default on a successful login on some platforms to plug a security attack vector. Change this to true to disable this. It is recommended you do not turn it off. Default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="autodetectBearerOnly" type="xs:boolean" use="optional" default="false">
<xs:annotation>
<xs:documentation>This should be set to true if your application serves both a web application and web services (e.g. SOAP or REST). It allows you to redirect unauthenticated users of the web application to the Keycloak login page, but send an HTTP 401 status code to unauthenticated SOAP or REST clients instead as they would not understand a redirect to the login page. Keycloak auto-detects SOAP or REST clients based on typical headers like X-Requested-With, SOAPAction or Accept. The default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="keys-type">
<xs:sequence>
<xs:element name="Key" type="key-type" minOccurs="1" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Describes a single key used for signing or encryption.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="key-type">
<xs:all>
<xs:element name="KeyStore" maxOccurs="1" minOccurs="0" type="key-store-type">
<xs:annotation>
<xs:documentation>Java keystore to load keys and certificates from.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="PrivateKeyPem" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Private key (PEM format)</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="PublicKeyPem" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Public key (PEM format)</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="CertificatePem" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Certificate key (PEM format)</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="signing" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Flag defining whether the key should be used for signing.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="encryption" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Flag defining whether the key should be used for encryption</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="key-store-type">
<xs:all>
<xs:element name="PrivateKey" maxOccurs="1" minOccurs="0" type="private-key-type">
<xs:annotation>
<xs:documentation>Private key declaration</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Certificate" type="certificate-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Certificate declaration</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="file" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>File path to the key store.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="resource" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>WAR resource path to the key store. This is a path used in method call to ServletContext.getResourceAsStream().</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="password" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The password of the key store.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="type" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key store format</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="alias" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Key alias</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="private-key-type">
<xs:attribute name="alias" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Alias that points to the key or cert within the keystore.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="password" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Keystores require an additional password to access private keys. In the PrivateKey element you must define this password within a password attribute.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="certificate-type">
<xs:attribute name="alias" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Alias that points to the key or cert within the keystore.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="principal-name-mapping-type">
<xs:attribute name="policy" type="principal-name-mapping-policy-type" use="required">
<xs:annotation>
<xs:documentation>Policy used to populate value of Java Principal object obtained from methods like HttpServletRequest.getUserPrincipal().</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="attribute" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Name of the SAML assertion attribute to use within.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:simpleType name="principal-name-mapping-policy-type">
<xs:restriction base="xs:string">
<xs:enumeration value="FROM_NAME_ID">
<xs:annotation>
<xs:documentation>This policy just uses whatever the SAML subject value is. This is the default setting</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="FROM_ATTRIBUTE">
<xs:annotation>
<xs:documentation>This will pull the value from one of the attributes declared in the SAML assertion received from the server. You'll need to specify the name of the SAML assertion attribute to use within the attribute XML attribute.</xs:documentation>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ssl-policy-type">
<xs:restriction base="xs:string">
<xs:enumeration value="ALL">
<xs:annotation>
<xs:documentation>All requests must come in via HTTPS.</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="EXTERNAL">
<xs:annotation>
<xs:documentation>Only non-private IP addresses must come over the wire via HTTPS.</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="NONE">
<xs:annotation>
<xs:documentation>no requests are required to come over via HTTPS.</xs:documentation>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="signature-algorithm-type">
<xs:restriction base="xs:string">
<xs:enumeration value="RSA_SHA1"/>
<xs:enumeration value="RSA_SHA256"/>
<xs:enumeration value="RSA_SHA512"/>
<xs:enumeration value="DSA_SHA1"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="binding-type">
<xs:restriction base="xs:string">
<xs:enumeration value="POST"/>
<xs:enumeration value="REDIRECT"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="role-identifiers-type">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Attribute" maxOccurs="unbounded" minOccurs="0" type="attribute-type">
<xs:annotation>
<xs:documentation>Specifies SAML attribute to be converted into roles.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:complexType name="attribute-type">
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Specifies name of the SAML attribute to be converted into roles.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="role-mappings-provider-type">
<xs:sequence>
<xs:element name="Property" type="property-type" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Specifies a configuration property for the provider.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The id of the role mappings provider that is to be used. Example: properties-based-provider.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="property-type">
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The name (key) of the configuration property.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="value" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>The value of the configuration property.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="idp-type">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="SingleSignOnService" maxOccurs="1" minOccurs="1" type="sign-on-type">
<xs:annotation>
<xs:documentation>Configuration of the login SAML endpoint of the IDP.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="SingleLogoutService" type="logout-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Configuration of the logout SAML endpoint of the IDP</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Keys" type="keys-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>The Keys sub element of IDP is only used to define the certificate or public key to use to verify documents signed by the IDP.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="HttpClient" type="http-client-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Configuration of HTTP client used for automatic obtaining of certificates containing public keys for IDP signature verification via SAML descriptor of the IDP.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="AllowedClockSkew" type="allowed-clock-skew-type" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>This defines the allowed clock skew between IDP and SP in milliseconds. The default value is 0.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="entityID" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>issuer ID of the IDP.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signaturesRequired" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>If set to true, the client adapter will sign every document it sends to the IDP. Also, the client will expect that the IDP will be signing any documents sent to it. This switch sets the default for all request and response types.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signatureAlgorithm" type="signature-algorithm-type" use="optional">
<xs:annotation>
<xs:documentation>Signature algorithm that the IDP expects signed documents to use. Defaults to RSA_SHA256</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signatureCanonicalizationMethod" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>This is the signature canonicalization method that the IDP expects signed documents to use. The default value is https://www.w3.org/2001/10/xml-exc-c14n# and should be good for most IDPs.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="encryption" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation></xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="metadataUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>The URL used to retrieve the IDP metadata, currently this is only used to pick up signing and encryption keys periodically which allow cycling of these keys on the IDP without manual changes on the SP side.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="sign-on-type">
<xs:attribute name="signRequest" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client sign authn requests? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client expect the IDP to sign the assertion response document sent back from an auhtn request? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateAssertionSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client expect the IDP to sign the individual assertions sent back from an auhtn request? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="requestBinding" type="binding-type" use="optional">
<xs:annotation>
<xs:documentation>SAML binding type used for communicating with the IDP. The default value is POST, but you can set it to REDIRECT as well.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="responseBinding" type="binding-type" use="optional">
<xs:annotation>
<xs:documentation>SAML allows the client to request what binding type it wants authn responses to use. This value maps to ProtocolBinding attribute in SAML AuthnRequest. The default is that the client will not request a specific binding type for responses.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="bindingUrl" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>This is the URL for the IDP login service that the client will send requests to.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="assertionConsumerServiceUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>URL of the assertion consumer service (ACS) where the IDP login service should send responses to. By default it is unset, relying on the IdP settings. When set, it must end in "/saml". This property is typically accompanied by the responseBinding attribute.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="logout-type">
<xs:attribute name="signRequest" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client sign authn requests? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="signResponse" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client sign logout responses it sends to the IDP requests? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateRequestSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client expect signed logout request documents from the IDP? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="validateResponseSignature" type="xs:boolean" use="optional">
<xs:annotation>
<xs:documentation>Should the client expect signed logout response documents from the IDP? Defaults to whatever the IDP signaturesRequired element value is.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="requestBinding" type="binding-type" use="optional">
<xs:annotation>
<xs:documentation>This is the SAML binding type used for communicating SAML requests to the IDP. The default value is POST.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="responseBinding" type="binding-type" use="optional">
<xs:annotation>
<xs:documentation>This is the SAML binding type used for communicating SAML responses to the IDP. The default value is POST.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="postBindingUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>This is the URL for the IDP's logout service when using the POST binding. This setting is REQUIRED if using the POST binding.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="redirectBindingUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>This is the URL for the IDP's logout service when using the REDIRECT binding. This setting is REQUIRED if using the REDIRECT binding.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="http-client-type">
<xs:attribute name="allowAnyHostname" type="xs:boolean" use="optional" default="false">
<xs:annotation>
<xs:documentation>If the the IDP server requires HTTPS and this config option is set to true the IDP's certificate
is validated via the truststore, but host name validation is not done. This setting should only be used during
development and never in production as it will partly disable verification of SSL certificates.
This seting may be useful in test environments. The default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="clientKeystore" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>This is the file path to a keystore file. This keystore contains client certificate
for two-way SSL when the adapter makes HTTPS requests to the IDP server.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="clientKeystorePassword" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Password for the client keystore and for the client's key.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="connectionPoolSize" type="xs:int" use="optional" default="10">
<xs:annotation>
<xs:documentation>Defines number of pooled connections.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="disableTrustManager" type="xs:boolean" use="optional" default="false">
<xs:annotation>
<xs:documentation>If the the IDP server requires HTTPS and this config option is set to true you do not have to specify a truststore.
This setting should only be used during development and never in production as it will disable verification of SSL certificates.
The default value is false.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="proxyUrl" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>URL to HTTP proxy to use for HTTP connections.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="truststore" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>The value is the file path to a keystore file. If you prefix the path with classpath:,
then the truststore will be obtained from the deployment's classpath instead. Used for outgoing
HTTPS communications to the IDP server. Client making HTTPS requests need
a way to verify the host of the server they are talking to. This is what the trustore does.
The keystore contains one or more trusted host certificates or certificate authorities.
You can create this truststore by extracting the public certificate of the IDP's SSL keystore.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="truststorePassword" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Password for the truststore keystore.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="socketTimeout" type="xs:long" default="-1">
<xs:annotation>
<xs:documentation>Defines timeout for socket waiting for data in milliseconds.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="connectionTimeout" type="xs:long" default="-1">
<xs:annotation>
<xs:documentation>Defines timeout for establishing the connection with the remote host in milliseconds.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="connectionTtl" type="xs:long" default="-1">
<xs:annotation>
<xs:documentation>Defines the connection time to live in milliseconds.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="allowed-clock-skew-type">
<xs:annotation>
<xs:documentation>The value is the allowed clock skew between the IDP and the SP.</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:positiveInteger">
<xs:attribute name="unit" type="clock-skew-unit-type"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="clock-skew-unit-type">
<xs:annotation>
<xs:documentation>Time unit for the value of the clock skew.</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="MINUTES" />
<xs:enumeration value="SECONDS" />
<xs:enumeration value="MILLISECONDS" />
<xs:enumeration value="MICROSECONDS" />
<xs:enumeration value="NANOSECONDS" />
</xs:restriction>
</xs:simpleType>
</xs:schema>

View file

@ -1,198 +0,0 @@
/*
* Copyright 2019 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import org.jboss.as.subsystem.test.AbstractSubsystemBaseTest;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.jboss.as.controller.ExpressionResolver;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.as.model.test.ModelTestUtils;
import org.jboss.as.subsystem.test.KernelServices;
import org.jboss.dmr.ModelNode;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Test case for AllowedClockSkew subsystem configuration.
*
* @author rmartinc
*/
public class SubsystemParsingAllowedClockSkewTestCase extends AbstractSubsystemBaseTest {
private String subsystemXml = null;
@Rule
public final ExpectedException exception = ExpectedException.none();
public SubsystemParsingAllowedClockSkewTestCase() {
super(KeycloakSamlExtension.SUBSYSTEM_NAME, new KeycloakSamlExtension());
}
@Override
protected String getSubsystemXml() throws IOException {
return subsystemXml;
}
private void setSubsystemXml(String value, String unit) throws IOException {
try {
String template = readResource("keycloak-saml-1.4.xml");
if (value != null) {
// assign the AllowedClockSkew element using DOM
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(template)));
// create the skew element
Element allowedClockSkew = doc.createElement(Constants.XML.ALLOWED_CLOCK_SKEW);
if (unit != null) {
allowedClockSkew.setAttribute(Constants.XML.ALLOWED_CLOCK_SKEW_UNIT, unit);
}
allowedClockSkew.setTextContent(value);
// locate the IDP and insert the node
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodeList = (NodeList) xPath.compile("/subsystem/secure-deployment[1]/SP/IDP").evaluate(doc, XPathConstants.NODESET);
nodeList.item(0).appendChild(allowedClockSkew);
// transform again to XML
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(doc), new StreamResult(writer));
subsystemXml = writer.getBuffer().toString();
} else {
subsystemXml = template;
}
} catch (DOMException | ParserConfigurationException | SAXException | TransformerException | XPathExpressionException e) {
throw new IOException(e);
}
}
private PathAddress getIdpPath() {
return PathAddress.EMPTY_ADDRESS
.append(PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, KeycloakSamlExtension.SUBSYSTEM_NAME))
.append(PathElement.pathElement(Constants.Model.SECURE_DEPLOYMENT, "my-app.war"))
.append(PathElement.pathElement(Constants.Model.SERVICE_PROVIDER, "http://localhost:8080/sales-post-enc/"))
.append(PathElement.pathElement(Constants.Model.IDENTITY_PROVIDER, "idp"));
}
private void testSubsystem(String value, String unit, int realValue, String realUnit) throws Exception {
setSubsystemXml(value, unit);
// perform the common test
KernelServices s = super.standardSubsystemTest(null, true);
// get the values for the AllowedClockSkew parameters
ModelNode idp = ModelTestUtils.getSubModel(s.readWholeModel(), getIdpPath());
ModelNode allowedClockSkew = idp.get(Constants.Model.ALLOWED_CLOCK_SKEW);
if (value != null) {
Assert.assertTrue(allowedClockSkew.isDefined());
ModelNode allowedClockSkewValue = allowedClockSkew.get(Constants.Model.ALLOWED_CLOCK_SKEW_VALUE);
ModelNode allowedClockSkewUnit = allowedClockSkew.get(Constants.Model.ALLOWED_CLOCK_SKEW_UNIT);
allowedClockSkewValue = ExpressionResolver.TEST_RESOLVER.resolveExpressions(allowedClockSkewValue);
allowedClockSkewUnit = ExpressionResolver.TEST_RESOLVER.resolveExpressions(allowedClockSkewUnit);
Assert.assertEquals(realValue, allowedClockSkewValue.asInt());
if (unit != null) {
Assert.assertEquals(realUnit, allowedClockSkewUnit.asString());
} else {
Assert.assertFalse(allowedClockSkewUnit.isDefined());
}
} else {
Assert.assertFalse(allowedClockSkew.isDefined());
}
}
private void testSubsystem(String value, String unit) throws Exception {
testSubsystem(value, unit, value == null? -1 : Integer.parseInt(value.trim()), unit);
}
@Test
@Override
public void testSubsystem() throws Exception {
testSubsystem(null, null);
}
@Test
public void testSubsystemAllowedClockSkewWithUnit() throws Exception {
testSubsystem("3500", "MILLISECONDS");
}
@Test
public void testSubsystemAllowedClockSkewWithoutUnit() throws Exception {
testSubsystem("1", null);
}
@Test
public void testSubsystemAllowedClockSkewWithSpaces() throws Exception {
testSubsystem("\n 20 \n ", null);
}
@Test
public void testErrorOnNonInteger() throws Exception {
exception.expect(NumberFormatException.class);
//exception.expectMessage("WFLYCTL0097");
testSubsystem("invalid-value", null, -1, null);
}
@Test
public void testErrorOnNonPositiveInteger() throws Exception {
exception.expect(XMLStreamException.class);
exception.expectMessage("JBAS014708");
testSubsystem("0", null);
}
@Test
public void testErrorNoValidUnit() throws Exception {
exception.expect(XMLStreamException.class);
exception.expectMessage("JBAS014839");
testSubsystem("30", "invalid-unit");
}
@Test
public void testExpression() throws Exception {
System.setProperty("test.prop.SKEW_TIME", "30");
System.setProperty("test.prop.SKEW_UNIT", "MILLISECONDS");
try {
testSubsystem("${test.prop.SKEW_TIME}", "${test.prop.SKEW_UNIT}", 30, "MILLISECONDS");
} finally {
System.clearProperty("test.prop.SKEW_TIME");
System.clearProperty("test.prop.SKEW_UNIT");
}
}
}

View file

@ -1,171 +0,0 @@
/*
* Copyright 2019 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.saml.as7;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.jboss.as.subsystem.test.AbstractSubsystemBaseTest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* 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.
*
*/
public class SubsystemParsingTestCase extends AbstractSubsystemBaseTest {
private String subsystemXml = null;
private String subsystemTemplate = null;
private Document document = null;
@Rule
public final ExpectedException exception = ExpectedException.none();
public SubsystemParsingTestCase() {
super(KeycloakSamlExtension.SUBSYSTEM_NAME, new KeycloakSamlExtension());
}
@Override
protected String getSubsystemXml() throws IOException {
return this.subsystemXml;
}
@Before
public void initialize() throws IOException {
this.subsystemTemplate = readResource("keycloak-saml-1.4.xml");
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
this.document = builder.parse(new InputSource(new StringReader(this.subsystemTemplate)));
} catch (ParserConfigurationException | SAXException e) {
throw new IOException(e);
}
}
private void buildSubsystemXml(final Element element, final String expression) throws IOException {
if (element != null) {
try {
// locate the element and insert the node
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(this.document, XPathConstants.NODESET);
nodeList.item(0).appendChild(element);
// transform again to XML
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(this.document), new StreamResult(writer));
this.subsystemXml = writer.getBuffer().toString();
} catch(TransformerException | XPathExpressionException e) {
throw new IOException(e);
}
} else {
this.subsystemXml = this.subsystemTemplate;
}
}
@Override
public void testSubsystem() throws Exception {
this.buildSubsystemXml(null, null);
super.testSubsystem();
}
@Test
public void testDuplicateServiceProviders() throws Exception {
// create a simple service provider element.
Element spElement = this.document.createElement(Constants.XML.SERVICE_PROVIDER);
spElement.setAttribute(Constants.XML.ENTITY_ID, "duplicate-sp");
this.buildSubsystemXml(spElement, "/subsystem/secure-deployment[1]");
this.exception.expect(XMLStreamException.class);
this.exception.expectMessage("JBAS014789: Unexpected element");
super.testSubsystem();
}
@Test
public void testDuplicateIdentityProviders() throws Exception {
// create a duplicate identity provider element.
Element idpElement = this.document.createElement(Constants.XML.IDENTITY_PROVIDER);
idpElement.setAttribute(Constants.XML.ENTITY_ID, "test-idp");
Element singleSignOn = this.document.createElement(Constants.XML.SINGLE_SIGN_ON);
singleSignOn.setAttribute(Constants.XML.BINDING_URL, "https://localhost:7887");
Element singleLogout = this.document.createElement(Constants.XML.SINGLE_LOGOUT);
singleLogout.setAttribute(Constants.XML.POST_BINDING_URL, "httpsL//localhost:8998");
idpElement.appendChild(singleSignOn);
idpElement.appendChild(singleLogout);
this.buildSubsystemXml(idpElement, "/subsystem/secure-deployment[1]/SP");
this.exception.expect(XMLStreamException.class);
this.exception.expectMessage("JBAS014789: Unexpected element");
super.testSubsystem();
}
@Test
public void testDuplicateKeysInSP() throws Exception {
Element keysElement = this.document.createElement(Constants.XML.KEYS);
Element keyElement = this.document.createElement(Constants.XML.KEY);
keyElement.setAttribute(Constants.XML.ENCRYPTION, "false");
keyElement.setAttribute(Constants.XML.SIGNING, "false");
keysElement.appendChild(keyElement);
this.buildSubsystemXml(keysElement, "/subsystem/secure-deployment[1]/SP");
this.exception.expect(XMLStreamException.class);
this.exception.expectMessage("JBAS014789: Unexpected element");
super.testSubsystem();
}
@Test
public void testDuplicateKeysInIDP() throws Exception {
Element keysElement = this.document.createElement(Constants.XML.KEYS);
Element keyElement = this.document.createElement(Constants.XML.KEY);
keyElement.setAttribute(Constants.XML.ENCRYPTION, "false");
keyElement.setAttribute(Constants.XML.SIGNING, "false");
keysElement.appendChild(keyElement);
this.buildSubsystemXml(keysElement, "/subsystem/secure-deployment[1]/SP/IDP");
this.exception.expect(XMLStreamException.class);
this.exception.expectMessage("JBAS014789: Unexpected element");
super.testSubsystem();
}
}

View file

@ -1,93 +0,0 @@
<!--
~ Copyright 2020 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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.
-->
<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.4">
<secure-deployment name="my-app.war">
<SP entityID="http://localhost:8080/sales-post-enc/"
sslPolicy="EXTERNAL"
nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
logoutPage="/logout.jsp"
keepDOMAssertion="false"
forceAuthentication="false"
isPassive="true"
turnOffChangeSessionIdOnLogin="true"
autodetectBearerOnly="false">
<Keys>
<Key encryption="true" signing="true">
<PrivateKeyPem>my_key.pem</PrivateKeyPem>
<PublicKeyPem>my_key.pub</PublicKeyPem>
<CertificatePem>cert.cer</CertificatePem>
<KeyStore resource="/WEB-INF/keystore.jks" password="store123" file="test" alias="test" type="jks">
<PrivateKey alias="http://localhost:8080/sales-post-enc/" password="test123"/>
<Certificate alias="http://localhost:8080/sales-post-enc/"/>
</KeyStore>
</Key>
</Keys>
<PrincipalNameMapping policy="FROM_NAME_ID" attribute="test"/>
<RoleIdentifiers>
<Attribute name="Role"/>
<Attribute name="Role2"/>
</RoleIdentifiers>
<RoleMappingsProvider id="properties-based-role-mapper">
<Property name="properties.file.location" value="test-roles.properties"/>
<Property name="another.property" value="another.value"/>
</RoleMappingsProvider>
<IDP entityID="idp"
signaturesRequired="true"
signatureAlgorithm="DSA_SHA1"
signatureCanonicalizationMethod="test"
metadataUrl="http://localhost:8080/metadata">
<SingleSignOnService signRequest="true"
validateResponseSignature="true"
validateAssertionSignature="true"
requestBinding="POST"
responseBinding="POST"
bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"
assertionConsumerServiceUrl="acsUrl"/>
<SingleLogoutService
validateRequestSignature="true"
validateResponseSignature="true"
signRequest="true"
signResponse="true"
requestBinding="POST"
responseBinding="POST"
postBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"
redirectBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
<Keys>
<Key signing="true">
<KeyStore resource="/WEB-INF/keystore.jks" password="store123">
<Certificate alias="saml-demo"/>
</KeyStore>
</Key>
</Keys>
<HttpClient allowAnyHostname="false"
clientKeystore="/tmp/keystore.jks"
clientKeystorePassword="testpwd1!@"
connectionPoolSize="20"
disableTrustManager="false"
proxyUrl="http://localhost:9090/proxy"
truststore="/tmp/truststore.jks"
truststorePassword="trustpwd#*"
socketTimeout="6000"
connectionTtl="500"
connectionTimeout="1000"
/>
</IDP>
</SP>
</secure-deployment>
</subsystem>

View file

@ -52,15 +52,5 @@
<module>jetty</module>
</modules>
</profile>
<profile>
<id>AS7</id>
<activation>
<jdk>[,9)</jdk>
</activation>
<modules>
<module>as7-eap6</module>
</modules>
</profile>
</profiles>
</project>

View file

@ -1,45 +0,0 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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.
-->
<assembly>
<id>war-dist</id>
<formats>
<format>zip</format>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}/unpacked/modules</directory>
<includes>
<include>com/fasterxml/jackson/**</include>
<include>org/bouncycastle/**</include>
<include>org/keycloak/keycloak-*/**</include>
</includes>
<outputDirectory>modules</outputDirectory>
</fileSet>
</fileSets>
<files>
<file>
<source>../../shared-cli/adapter-install.cli</source>
<outputDirectory>bin</outputDirectory>
</file>
</files>
</assembly>

View file

@ -1,96 +0,0 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>keycloak-parent</artifactId>
<groupId>org.keycloak</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../../../../pom.xml</relativePath>
</parent>
<artifactId>keycloak-as7-adapter-dist</artifactId>
<packaging>pom</packaging>
<name>Keycloak AS7 Adapter Distro</name>
<description/>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-adapter</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-modules</artifactId>
<type>zip</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-modules</artifactId>
<type>zip</type>
<outputDirectory>${project.build.directory}/unpacked</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<outputDirectory>
target
</outputDirectory>
<workDirectory>
target/assembly/work
</workDirectory>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View file

@ -1,43 +0,0 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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.
-->
<assembly>
<id>dist</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>src/main/resources/licenses/${product.slot}</directory>
<outputDirectory>licenses</outputDirectory>
<excludes>
<exclude>licenses.xml</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/licenses</directory>
<outputDirectory>licenses</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}/modules</directory>
<outputDirectory>modules</outputDirectory>
</fileSet>
</fileSets>
</assembly>

View file

@ -1,104 +0,0 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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 name="module-repository" basedir="." default="all">
<import file="lib.xml"/>
<property name="output.dir" value="target"/>
<target name="all">
<antcall target="modules">
<param name="mavenized.modules" value="false"/>
<param name="output.dir" value="target"/>
</antcall>
</target>
<target name="modules">
<!-- jackson2 -->
<module-def name="com.fasterxml.jackson.core.jackson-annotations">
<maven-resource group="com.fasterxml.jackson.core" artifact="jackson-annotations"/>
</module-def>
<module-def name="com.fasterxml.jackson.core.jackson-core">
<maven-resource group="com.fasterxml.jackson.core" artifact="jackson-core"/>
</module-def>
<module-def name="com.fasterxml.jackson.core.jackson-databind">
<maven-resource group="com.fasterxml.jackson.core" artifact="jackson-databind"/>
</module-def>
<module-def name="com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider">
<maven-resource group="com.fasterxml.jackson.jaxrs" artifact="jackson-jaxrs-json-provider"/>
<maven-resource group="com.fasterxml.jackson.jaxrs" artifact="jackson-jaxrs-base"/>
<maven-resource group="com.fasterxml.jackson.module" artifact="jackson-module-jaxb-annotations"/>
</module-def>
<!-- server min dependencies -->
<module-def name="org.keycloak.keycloak-common">
<maven-resource group="org.keycloak" artifact="keycloak-common"/>
</module-def>
<module-def name="org.keycloak.keycloak-core">
<maven-resource group="org.keycloak" artifact="keycloak-core"/>
</module-def>
<module-def name="org.bouncycastle">
<maven-resource group="org.bouncycastle" artifact="bcprov-jdk15on"/>
<maven-resource group="org.bouncycastle" artifact="bcpkix-jdk15on"/>
</module-def>
<!-- subsystems -->
<module-def name="org.keycloak.keycloak-adapter-spi">
<maven-resource group="org.keycloak" artifact="keycloak-adapter-spi"/>
<maven-resource group="org.keycloak" artifact="keycloak-tomcat-adapter-spi"/>
<maven-resource group="org.keycloak" artifact="keycloak-as7-adapter-spi"/>
</module-def>
<module-def name="org.keycloak.keycloak-adapter-core">
<maven-resource group="org.keycloak" artifact="keycloak-adapter-core"/>
</module-def>
<module-def name="org.keycloak.keycloak-jboss-adapter-core">
<maven-resource group="org.keycloak" artifact="keycloak-jboss-adapter-core"/>
</module-def>
<module-def name="org.keycloak.keycloak-as7-adapter">
<maven-resource group="org.keycloak" artifact="keycloak-as7-adapter"/>
<maven-resource group="org.keycloak" artifact="keycloak-tomcat-core-adapter"/>
</module-def>
<module-def name="org.keycloak.keycloak-as7-subsystem">
<maven-resource group="org.keycloak" artifact="keycloak-as7-subsystem"/>
</module-def>
<!-- Authorization -->
<module-def name="org.keycloak.keycloak-authz-client">
<maven-resource group="org.keycloak" artifact="keycloak-authz-client"/>
</module-def>
</target>
<target name="clean-target">
<delete dir="${output.dir}"/>
</target>
<target name="clean" depends="clean-target">
<delete file="maven-ant-tasks.jar"/>
</target>
</project>

View file

@ -1,277 +0,0 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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 name="module-repository-lib">
<property name="src.dir" value="src"/>
<property name="module.repo.src.dir" value="${src.dir}/main/resources/modules"/>
<property name="module.xml" value="module.xml"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<taskdef name="jandex" classname="org.jboss.jandex.JandexAntTask" />
<macrodef name="module-def">
<attribute name="name"/>
<attribute name="slot" default="main"/>
<element name="resources" implicit="yes" optional="yes"/>
<sequential>
<echo message="Initializing module -> @{name}"/>
<property name="module.repo.output.dir" value="${output.dir}/modules"/>
<!-- Figure out the correct module path -->
<define-module-dir name="@{name}" slot="@{slot}"/>
<!-- Make the module output director -->
<mkdir dir="${module.repo.output.dir}/${current.module.path}"/>
<!-- Copy the module.xml and other stuff to the output director -->
<copy todir="${module.repo.output.dir}/${current.module.path}" overwrite="true">
<fileset dir="${module.repo.src.dir}/${current.module.path}">
<include name="**"/>
</fileset>
</copy>
<!-- Process the resource -->
<resources/>
<!-- Add keycloak version property to module xml -->
<replace file="${module.repo.output.dir}/${current.module.path}/${module.xml}"
token="$${project.version}"
value="${project.version}"/>
<!-- Some final cleanup -->
<replace file="${module.repo.output.dir}/${current.module.path}/${module.xml}">
<replacetoken>
<![CDATA[
<!-- Insert resources here -->]]></replacetoken>
<replacevalue>
</replacevalue>
</replace>
</sequential>
</macrodef>
<macrodef name="bundle-def">
<attribute name="name"/>
<attribute name="slot" default="main"/>
<element name="resources" implicit="yes" optional="yes"/>
<sequential>
<echo message="Initializing bundle -> @{name}"/>
<property name="bundle.repo.output.dir" value="${output.dir}/bundles/system/layers/base"/>
<!-- Figure out the correct bundle path -->
<define-bundle-dir name="@{name}" slot="@{slot}" />
<!-- Make the bundle output director -->
<mkdir dir="${bundle.repo.output.dir}/${current.bundle.path}"/>
<!-- Process the resource -->
<resources/>
</sequential>
</macrodef>
<macrodef name="maven-bundle" >
<attribute name="group"/>
<attribute name="artifact"/>
<sequential>
<!-- Copy the jar to the bundle dir -->
<property name="bundle.repo.output.dir" value="${output.dir}/bundles/system/layers/base"/>
<copy todir="${bundle.repo.output.dir}/${current.bundle.path}" failonerror="true">
<fileset file="${@{group}:@{artifact}:jar}"/>
<mapper type="flatten" />
</copy>
</sequential>
</macrodef>
<scriptdef name="define-module-dir" language="javascript" manager="bsf">
<attribute name="name"/>
<attribute name="slot"/>
<![CDATA[
name = attributes.get("name");
name = name.replace(".", "/");
project.setProperty("current.module.path", name + "/" + attributes.get("slot"));
]]>
</scriptdef>
<scriptdef name="define-bundle-dir" language="javascript" manager="bsf">
<attribute name="name"/>
<attribute name="slot"/>
<![CDATA[
name = attributes.get("name");
name = name.replace(".", "/");
project.setProperty("current.bundle.path", name + "/" + attributes.get("slot"));
]]>
</scriptdef>
<!--
Get the version from the parent directory of the jar. If the parent directory is 'target' this
means that the jar is contained in AS build so extract the version from the file name
-->
<scriptdef name="define-maven-artifact" language="javascript" manager="bsf">
<attribute name="group"/>
<attribute name="artifact"/>
<attribute name="classifier"/>
<attribute name="element"/>
<attribute name="path"/>
<![CDATA[
importClass(Packages.java.io.File);
group = attributes.get("group");
artifact = attributes.get("artifact");
classifier = attributes.get("classifier");
element = attributes.get("element");
path = attributes.get("path");
if(path.indexOf('${') != -1) {
throw "Module resource root not found, make sure it is listed in build/pom.xml" + path;
}
fp = new File(path);
version = fp.getParentFile().getName();
if (version.equals("target")) {
version = fp.getName();
version = version.substring(artifact.length() + 1);
suffix = ".jar";
if (classifier) {
suffix = "-" + classifier + suffix;
}
version = version.replace(suffix, "");
}
root = "<" + element + " name=\"" + group + ":" + artifact + ":" + version;
if (classifier) {
root = root + ":" + classifier;
}
root = root + "\"/>";
project.setProperty("current.maven.root", root);
]]>
</scriptdef>
<macrodef name="maven-resource" >
<attribute name="group"/>
<attribute name="artifact"/>
<attribute name="jandex" default="false" />
<sequential>
<if>
<equals arg1="${mavenized.modules}" arg2="true"/>
<then>
<define-maven-artifact group="@{group}" artifact="@{artifact}" element="artifact" path="${@{group}:@{artifact}:jar}"/>
<replace file="${module.repo.output.dir}/${current.module.path}/${module.xml}">
<replacefilter token="&lt;!-- Insert resources here --&gt;" value="${current.maven.root}&#10; &lt;!-- Insert resources here --&gt;"/>
</replace>
</then>
<else>
<!-- Copy the jar to the module dir -->
<copy todir="${module.repo.output.dir}/${current.module.path}" failonerror="true">
<fileset file="${@{group}:@{artifact}:jar}"/>
<mapper type="flatten" />
</copy>
<basename file="${@{group}:@{artifact}:jar}" property="resourcename.@{group}.@{artifact}"/>
<!-- Generate the Jandex Index -->
<jandex run="@{jandex}" newJar="true" >
<fileset dir="${module.repo.output.dir}/${current.module.path}" />
</jandex>
<!-- Update the resource entry in module.xml -->
<define-resource-root path="${resourcename.@{group}.@{artifact}}" jandex="@{jandex}"/>
<replace file="${module.repo.output.dir}/${current.module.path}/${module.xml}">
<replacefilter token="&lt;!-- Insert resources here --&gt;" value="${current.resource.root}&#10; &lt;!-- Insert resources here --&gt;"/>
</replace>
</else>
</if>
</sequential>
</macrodef>
<macrodef name="maven-resource-with-classifier" >
<attribute name="group"/>
<attribute name="artifact"/>
<attribute name="classifier"/>
<attribute name="jandex" default="false" />
<sequential>
<if>
<equals arg1="${mavenized.modules}" arg2="true"/>
<then>
<define-maven-artifact group="@{group}" artifact="@{artifact}" element="artifact" classifier="@{classifier}" path="${@{group}:@{artifact}:jar:@{classifier}}"/>
<replace file="${module.repo.output.dir}/${current.module.path}/${module.xml}">
<replacefilter token="&lt;!-- Insert resources here --&gt;" value="${current.maven.root}&#10; &lt;!-- Insert resources here --&gt;"/>
</replace>
</then>
<else>
<!-- Copy the jar to the module dir -->
<copy todir="${module.repo.output.dir}/${current.module.path}" failonerror="true">
<fileset file="${@{group}:@{artifact}:jar:@{classifier}}"/>
<!-- http://jira.codehaus.org/browse/MANTRUN-159 -->
<mapper type="flatten" />
</copy>
<basename file="${@{group}:@{artifact}:jar:@{classifier}}" property="resourcename.@{group}.@{artifact}.@{classifier}"/>
<!-- Update the resource entry in module.xml -->
<define-resource-root path="${resourcename.@{group}.@{artifact}.@{classifier}}"/>
<replace file="${module.repo.output.dir}/${current.module.path}/${module.xml}">
<replacefilter token="&lt;!-- Insert resources here --&gt;" value="${current.resource.root}&#10; &lt;!-- Insert resources here --&gt;"/>
</replace>
</else>
</if>
</sequential>
</macrodef>
<macrodef name="extract-native-jar" >
<attribute name="group"/>
<attribute name="artifact"/>
<sequential>
<if>
<equals arg1="${mavenized.modules}" arg2="true"/>
<then>
<define-maven-artifact group="@{group}" artifact="@{artifact}" element="native-artifact" path="${@{group}:@{artifact}:jar}"/>
<replace file="${module.repo.output.dir}/${current.module.path}/${module.xml}">
<replacefilter token="&lt;!-- Insert resources here --&gt;" value="${current.maven.root}&#10; &lt;!-- Insert resources here --&gt;"/>
</replace>
</then>
<else>
<unzip src="${@{group}:@{artifact}:jar}" dest="${module.repo.output.dir}/${current.module.path}">
<patternset>
<include name="lib/**"/>
</patternset>
</unzip>
</else>
</if>
</sequential>
</macrodef>
<scriptdef name="define-resource-root" language="javascript" manager="bsf">
<attribute name="path"/>
<attribute name="jandex"/>
<![CDATA[
path = attributes.get("path");
root = "<resource-root path=\"" + path + "\"/>";
if(path.indexOf('${') != -1) {
throw "Module resource root not found, make sure it is listed in build/pom.xml" + path;
}
if(attributes.get("jandex") == "true" ) {
root = root + "\n\t<resource-root path=\"" + path.replace(".jar","-jandex.jar") + "\"/>";
}
project.setProperty("current.resource.root", root);
]]>
</scriptdef>
</project>

View file

@ -1,339 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ 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>
<artifactId>keycloak-as7-eap6-adapter-dist-pom</artifactId>
<groupId>org.keycloak</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>keycloak-as7-modules</artifactId>
<name>Keycloak AS7 / JBoss EAP 6 Modules</name>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-common</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-spi</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-adapter-spi</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-tomcat-adapter-spi</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-adapter-core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-jboss-adapter-core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-adapter</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-tomcat-core-adapter</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-as7-subsystem</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Authorization -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-client</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<id>build-dist</id>
<goals>
<goal>run</goal>
</goals>
<phase>compile</phase>
<configuration>
<target>
<ant antfile="build.xml" inheritRefs="true">
<target name="all"/>
</ant>
</target>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jandex</artifactId>
<version>1.0.3.Final</version>
</dependency>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>1.0b3</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-apache-bsf</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>org.apache.bsf</groupId>
<artifactId>bsf-api</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>rhino</groupId>
<artifactId>js</artifactId>
<version>1.7R2</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assemble</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<outputDirectory>
target
</outputDirectory>
<workDirectory>
target/assembly/work
</workDirectory>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/modules/org/keycloak/keycloak-adapter-subsystem</outputDirectory>
<resources>
<resource>
<directory>src/main/resources/modules/org/keycloak/keycloak-adapter-subsystem</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-distribution-licenses-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View file

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View file

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View file

@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View file

@ -1,8 +0,0 @@
This copy of Jackson JSON processor databind module is licensed under the
Apache (Software) License, version 2.0 ("the License").
See the License for details about distribution rights, and the
specific rights regarding derivate works.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0

View file

@ -1,8 +0,0 @@
This copy of Jackson JSON processor databind module is licensed under the
Apache (Software) License, version 2.0 ("the License").
See the License for details about distribution rights, and the
specific rights regarding derivate works.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0

View file

@ -1,8 +0,0 @@
This copy of Jackson JSON processor databind module is licensed under the
Apache (Software) License, version 2.0 ("the License").
See the License for details about distribution rights, and the
specific rights regarding derivate works.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0

View file

@ -1,93 +0,0 @@
<?xml version="1.0"?>
<licenseSummary>
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.68</version>
<licenses>
<license>
<name>MIT License</name>
<url>https://raw.githubusercontent.com/bcgit/bc-java/r1rv68/LICENSE.html</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
<licenses>
<license>
<name>MIT License</name>
<url>https://raw.githubusercontent.com/bcgit/bc-java/r1rv68/LICENSE.html</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.12.1</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-annotations/jackson-annotations-2.12.1/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.1</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-core/jackson-core-2.12.1/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-databind/jackson-databind-2.12.1/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>2.12.1</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.12.1/json/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.12.1</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.12.1/json/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.12.1</version>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://raw.githubusercontent.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-providers-2.12.1/json/src/main/resources/META-INF/LICENSE</url>
</license>
</licenses>
</dependency>
</dependencies>
</licenseSummary>

View file

@ -1,22 +0,0 @@
<html>
<body bgcolor=#ffffff>
Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
<p>
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</body>
</html>

View file

@ -1,22 +0,0 @@
<html>
<body bgcolor=#ffffff>
Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
<p>
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more