Skip to content

Commit

Permalink
Generalize SingleSignOnDefinition to accommodate application security…
Browse files Browse the repository at this point in the history
… domain-based sso.
  • Loading branch information
pferraro committed Jan 23, 2017
1 parent ef973cf commit 8e9da74
Show file tree
Hide file tree
Showing 17 changed files with 173 additions and 112 deletions.
22 changes: 0 additions & 22 deletions feature-pack/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2200,17 +2200,6 @@
</exclusions>
</dependency>

<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-clustering-common</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-clustering-ee-infinispan</artifactId>
Expand Down Expand Up @@ -2357,17 +2346,6 @@
</exclusions>
</dependency>

<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-clustering-service</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-clustering-singleton-api</artifactId>
Expand Down
22 changes: 22 additions & 0 deletions servlet-feature-pack/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,28 @@
</exclusions>
</dependency>

<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-clustering-common</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-clustering-service</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-ee</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
<module name="javax.websocket.api"/>
<module name="org.jboss.jandex"/>
<module name="org.jboss.staxmapper"/>
<module name="org.jboss.as.clustering.common"/>
<module name="org.wildfly.clustering.service"/>
<module name="org.wildfly.clustering.web.api" optional="true"/>
<module name="org.wildfly.clustering.web.undertow" services="import" optional="true"/>
<module name="org.wildfly.extension.request-controller" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ class HostDefinition extends PersistentResourceDefinition {
LocationDefinition.INSTANCE,
AccessLogDefinition.INSTANCE,
FilterRefDefinition.INSTANCE,
SingleSignOnDefinition.INSTANCE

new HostSingleSignOnDefinition()
));

private HostDefinition() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2017, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.wildfly.extension.undertow;

import org.jboss.as.clustering.controller.ResourceDescriptor;
import org.jboss.as.clustering.controller.SimpleResourceRegistration;
import org.jboss.as.controller.registry.ManagementResourceRegistration;

/**
* @author Paul Ferraro
*/
public class HostSingleSignOnDefinition extends SingleSignOnDefinition {

@Override
public void registerOperations(ManagementResourceRegistration registration) {
ResourceDescriptor descriptor = new ResourceDescriptor(this.getResourceDescriptionResolver())
.addAttributes(SingleSignOnDefinition.Attribute.class)
;
new SimpleResourceRegistration(descriptor, new HostSingleSignOnServiceHandler()).register(registration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@

package org.wildfly.extension.undertow;

import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
import static org.wildfly.extension.undertow.SingleSignOnDefinition.Attribute.*;

import org.jboss.as.clustering.controller.ResourceServiceHandler;
import org.jboss.as.clustering.dmr.ModelNodes;

import io.undertow.security.impl.InMemorySingleSignOnManager;
import io.undertow.security.impl.SingleSignOnManager;

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.PathAddress;
Expand All @@ -44,34 +45,28 @@

/**
* @author <a href="mailto:tomaz.cerar@redhat.com">Tomaz Cerar</a> (c) 2014 Red Hat Inc.
* @author Paul Ferraro
*/
class SingleSignOnAdd extends AbstractAddStepHandler {
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
for (AttributeDefinition def : SingleSignOnDefinition.ATTRIBUTES) {
def.validateAndSet(operation, model);
}
}
class HostSingleSignOnServiceHandler implements ResourceServiceHandler {

@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
final PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR));
final PathAddress hostAddress = address.subAddress(0, address.size() - 1);
final PathAddress serverAddress = hostAddress.subAddress(0, hostAddress.size() - 1);
public void installServices(OperationContext context, ModelNode model) throws OperationFailedException {
PathAddress address = context.getCurrentAddress();
PathAddress hostAddress = address.getParent();
PathAddress serverAddress = hostAddress.getParent();
String hostName = hostAddress.getLastElement().getValue();
String serverName = serverAddress.getLastElement().getValue();

String domain = ModelNodes.optionalString(DOMAIN.resolveModelAttribute(context, model)).orElse(null);
String path = PATH.resolveModelAttribute(context, model).asString();
boolean secure = SECURE.resolveModelAttribute(context, model).asBoolean();
boolean httpOnly = HTTP_ONLY.resolveModelAttribute(context, model).asBoolean();
String cookieName = COOKIE_NAME.resolveModelAttribute(context, model).asString();

final ModelNode domainModelNode = SingleSignOnDefinition.DOMAIN.resolveModelAttribute(context, model);
final ModelNode pathNode = SingleSignOnDefinition.PATH.resolveModelAttribute(context, model);
final String domain = domainModelNode.isDefined() ? domainModelNode.asString() : null;
final String path = pathNode.isDefined() ? pathNode.asString() : null;
final boolean secure = SingleSignOnDefinition.SECURE.resolveModelAttribute(context, model).asBoolean();
final boolean httpOnly = SingleSignOnDefinition.HTTP_ONLY.resolveModelAttribute(context, model).asBoolean();
final String cookieName = SingleSignOnDefinition.COOKIE_NAME.resolveModelAttribute(context, model).asString();
final String serverName = serverAddress.getLastElement().getValue();
final String hostName = hostAddress.getLastElement().getValue();
final ServiceName serviceName = UndertowService.ssoServiceName(serverName, hostName);
final ServiceName virtualHostServiceName = UndertowService.virtualHostName(serverName, hostName);
ServiceName serviceName = UndertowService.ssoServiceName(serverName, hostName);
ServiceName virtualHostServiceName = UndertowService.virtualHostName(serverName, hostName);

final ServiceTarget target = context.getServiceTarget();
ServiceTarget target = context.getServiceTarget();

ServiceName managerServiceName = serviceName.append("manager");
if (DistributableHostSingleSignOnManagerBuilder.INSTANCE.isPresent()) {
Expand All @@ -81,11 +76,25 @@ protected void performRuntime(OperationContext context, ModelNode operation, Mod
target.addService(managerServiceName, new ValueService<>(new ImmediateValue<>(new InMemorySingleSignOnManager()))).setInitialMode(ServiceController.Mode.ON_DEMAND).install();
}

final SingleSignOnService service = new SingleSignOnService(domain, path, httpOnly, secure, cookieName);
SingleSignOnService service = new SingleSignOnService(domain, path, httpOnly, secure, cookieName);
target.addService(serviceName, service)
.addDependency(virtualHostServiceName, Host.class, service.getHost())
.addDependency(managerServiceName, SingleSignOnManager.class, service.getSingleSignOnSessionManager())
.setInitialMode(ServiceController.Mode.ACTIVE)
.install();
}
}

@Override
public void removeServices(OperationContext context, ModelNode model) throws OperationFailedException {
PathAddress address = context.getCurrentAddress();
PathAddress hostAddress = address.getParent();
PathAddress serverAddress = hostAddress.getParent();
String hostName = hostAddress.getLastElement().getValue();
String serverName = serverAddress.getLastElement().getValue();

ServiceName serviceName = UndertowService.ssoServiceName(serverName, hostName);

context.removeService(serviceName);
context.removeService(serviceName.append("manager"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,11 @@

package org.wildfly.extension.undertow;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Collections;

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.PersistentResourceDefinition;
import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
Expand All @@ -42,48 +39,37 @@
*/
class SingleSignOnDefinition extends PersistentResourceDefinition {

static final SimpleAttributeDefinition DOMAIN = new SimpleAttributeDefinitionBuilder(Constants.DOMAIN, ModelType.STRING, true)
.setAllowNull(true)
.setAllowExpression(true)
.setRestartAllServices()
.build();
static final SimpleAttributeDefinition PATH = new SimpleAttributeDefinitionBuilder("path", ModelType.STRING, true)
.setAllowNull(true)
.setAllowExpression(true)
.setDefaultValue(new ModelNode("/"))
.setRestartAllServices()
.build();
static final SimpleAttributeDefinition HTTP_ONLY = new SimpleAttributeDefinitionBuilder("http-only", ModelType.BOOLEAN, true)
.setAllowNull(true)
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.setRestartAllServices()
.build();
enum Attribute implements org.jboss.as.clustering.controller.Attribute {
DOMAIN(Constants.DOMAIN, ModelType.STRING, null),
PATH("path", ModelType.STRING, new ModelNode("/")),
HTTP_ONLY("http-only", ModelType.BOOLEAN, new ModelNode(false)),
SECURE("secure", ModelType.BOOLEAN, new ModelNode(false)),
COOKIE_NAME("cookie-name", ModelType.STRING, new ModelNode("JSESSIONIDSSO")),
;
private final AttributeDefinition definition;

static final SimpleAttributeDefinition SECURE = new SimpleAttributeDefinitionBuilder("secure", ModelType.BOOLEAN, true)
.setAllowNull(true)
.setAllowExpression(true)
.setDefaultValue(new ModelNode(false))
.setRestartAllServices()
.build();
Attribute(String name, ModelType type, ModelNode defaultValue) {
this.definition = new SimpleAttributeDefinitionBuilder(name, type)
.setRequired(false)
.setAllowExpression(true)
.setDefaultValue(defaultValue)
.setRestartAllServices()
.build();
}

static final SimpleAttributeDefinition COOKIE_NAME = new SimpleAttributeDefinitionBuilder("cookie-name", ModelType.STRING, true)
.setAllowNull(true)
.setAllowExpression(true)
.setDefaultValue(new ModelNode("JSESSIONIDSSO"))
.setRestartAllServices()
.build();

static final List<AttributeDefinition> ATTRIBUTES = Arrays.<AttributeDefinition>asList(DOMAIN, PATH, HTTP_ONLY, SECURE, COOKIE_NAME);

static final SingleSignOnDefinition INSTANCE = new SingleSignOnDefinition();
@Override
public AttributeDefinition getDefinition() {
return this.definition;
}
}

private SingleSignOnDefinition() {
super(UndertowExtension.PATH_SSO, UndertowExtension.getResolver(Constants.SINGLE_SIGN_ON), new SingleSignOnAdd(), ReloadRequiredRemoveStepHandler.INSTANCE);
SingleSignOnDefinition() {
super(new Parameters(UndertowExtension.PATH_SSO, UndertowExtension.getResolver(Constants.SINGLE_SIGN_ON)));
}

@Override
public Collection<AttributeDefinition> getAttributes() {
return ATTRIBUTES;
// Attributes will be registered by the parent implementation
return Collections.emptyList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,11 @@ public class UndertowSubsystemParser_1_0 extends PersistentResourceXMLParser{
builder(FilterRefDefinition.INSTANCE)
.addAttributes(FilterRefDefinition.PREDICATE)
).addChild(
builder(SingleSignOnDefinition.INSTANCE)
.addAttributes(SingleSignOnDefinition.DOMAIN, SingleSignOnDefinition.PATH, SingleSignOnDefinition.HTTP_ONLY, SingleSignOnDefinition.SECURE)
builder(UndertowExtension.PATH_SSO)
.addAttribute(SingleSignOnDefinition.Attribute.DOMAIN.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.PATH.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.HTTP_ONLY.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.SECURE.getDefinition())
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,12 @@ public class UndertowSubsystemParser_1_1 extends PersistentResourceXMLParser {
builder(FilterRefDefinition.INSTANCE)
.addAttributes(FilterRefDefinition.PREDICATE)
).addChild(
builder(SingleSignOnDefinition.INSTANCE)
.addAttributes(SingleSignOnDefinition.DOMAIN, SingleSignOnDefinition.PATH, SingleSignOnDefinition.HTTP_ONLY, SingleSignOnDefinition.SECURE, SingleSignOnDefinition.COOKIE_NAME)
builder(UndertowExtension.PATH_SSO)
.addAttribute(SingleSignOnDefinition.Attribute.DOMAIN.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.PATH.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.HTTP_ONLY.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.SECURE.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.COOKIE_NAME.getDefinition())
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,12 @@ public class UndertowSubsystemParser_1_2 extends PersistentResourceXMLParser {
builder(FilterRefDefinition.INSTANCE)
.addAttributes(FilterRefDefinition.PREDICATE, FilterRefDefinition.PRIORITY)
).addChild(
builder(SingleSignOnDefinition.INSTANCE)
.addAttributes(SingleSignOnDefinition.DOMAIN, SingleSignOnDefinition.PATH, SingleSignOnDefinition.HTTP_ONLY, SingleSignOnDefinition.SECURE, SingleSignOnDefinition.COOKIE_NAME)
builder(UndertowExtension.PATH_SSO)
.addAttribute(SingleSignOnDefinition.Attribute.DOMAIN.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.PATH.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.HTTP_ONLY.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.SECURE.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.COOKIE_NAME.getDefinition())
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,12 @@ public class UndertowSubsystemParser_2_0 extends PersistentResourceXMLParser {
builder(FilterRefDefinition.INSTANCE)
.addAttributes(FilterRefDefinition.PREDICATE, FilterRefDefinition.PRIORITY)
).addChild(
builder(SingleSignOnDefinition.INSTANCE)
.addAttributes(SingleSignOnDefinition.DOMAIN, SingleSignOnDefinition.PATH, SingleSignOnDefinition.HTTP_ONLY, SingleSignOnDefinition.SECURE, SingleSignOnDefinition.COOKIE_NAME)
builder(UndertowExtension.PATH_SSO)
.addAttribute(SingleSignOnDefinition.Attribute.DOMAIN.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.PATH.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.HTTP_ONLY.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.SECURE.getDefinition())
.addAttribute(SingleSignOnDefinition.Attribute.COOKIE_NAME.getDefinition())
)
)
)
Expand Down

0 comments on commit 8e9da74

Please sign in to comment.