/*
* JBoss, Home of Professional Open Source.
* Copyright 2009, Red Hat Middleware LLC, 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.jboss.identity.federation.bindings.jboss.wstrust;
import java.security.KeyPair;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;
import org.jboss.identity.federation.core.config.KeyProviderType;
import org.jboss.identity.federation.core.config.PropertyType;
import org.jboss.identity.federation.core.config.STSType;
import org.jboss.identity.federation.core.config.ServiceProviderType;
import org.jboss.identity.federation.core.config.ServiceProvidersType;
import org.jboss.identity.federation.core.config.TokenProviderType;
import org.jboss.identity.federation.core.config.TokenProvidersType;
import org.jboss.identity.federation.core.wstrust.STSConfiguration;
import org.jboss.identity.federation.core.wstrust.SecurityTokenProvider;
import org.jboss.identity.federation.core.wstrust.WSTrustRequestHandler;
import org.jboss.identity.federation.core.wstrust.WSTrustServiceFactory;
import org.jboss.identity.federation.web.interfaces.TrustKeyManager;
/**
* <p>
* Standard JBoss STS configuration implementation.
* </p>
*
* @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
*/
public class JBossSTSConfiguration implements STSConfiguration
{
// the delegate contains all the information extracted from the jboss-sts.xml configuration file.
private final STSType delegate;
private final Map<String, SecurityTokenProvider> tokenProviders = new HashMap<String, SecurityTokenProvider>();
private final Map<String, ServiceProviderType> spMetadata = new HashMap<String, ServiceProviderType>();
private TrustKeyManager trustManager;
private WSTrustRequestHandler handler;
/**
* <p>
* Creates an instance of {@code JBossSTSConfiguration} with default configuration values.
* </p>
*/
public JBossSTSConfiguration()
{
this.delegate = new STSType();
this.delegate.setRequestHandler("org.jboss.identity.federation.core.wstrust.StandardRequestHandler");
// TODO: add default token provider classes.
}
/**
* <p>
* Creates an instance of {@code JBossSTSConfiguration} with the specified configuration.
* </p>
*
* @param config a reference to the object that holds the configuration of the STS.
*/
public JBossSTSConfiguration(STSType config)
{
this.delegate = config;
// set the default request handler if one hasn't been specified.
if (this.delegate.getRequestHandler() == null)
this.delegate.setRequestHandler("org.jboss.identity.federation.core.wstrust.StandardRequestHandler");
// build the token-provider and service-metadata maps.
TokenProvidersType providers = this.delegate.getTokenProviders();
if (providers != null)
{
WSTrustServiceFactory serviceFactory = WSTrustServiceFactory.getInstance();
for (TokenProviderType provider : providers.getTokenProvider())
{
// create and initialize the token provider.
SecurityTokenProvider tokenProvider = serviceFactory.createTokenProvider(provider.getProviderClass());
Map<String, String> properties = new HashMap<String, String>();
for(PropertyType propertyType : provider.getProperty())
properties.put(propertyType.getName(), propertyType.getValue());
tokenProvider.initialize(properties);
// token providers can be keyed by the token type and by token element + namespace.
this.tokenProviders.put(provider.getTokenType(), tokenProvider);
String tokenElementAndNS = provider.getTokenElement() + "$" + provider.getTokenElementNS();
this.tokenProviders.put(tokenElementAndNS, tokenProvider);
}
}
ServiceProvidersType serviceProviders = this.delegate.getServiceProviders();
if (serviceProviders != null)
{
for (ServiceProviderType provider : serviceProviders.getServiceProvider())
this.spMetadata.put(provider.getEndpoint(), provider);
}
// setup the key store.
KeyProviderType keyProviderType = config.getKeyProvider();
if (keyProviderType != null)
{
String keyManagerClassName = keyProviderType.getClassName();
try
{
this.trustManager = (TrustKeyManager) SecurityActions.instantiateClass(keyManagerClassName);
this.trustManager.setAuthProperties(keyProviderType.getAuth());
this.trustManager.setValidatingAlias(keyProviderType.getValidatingAlias());
}
catch (Exception e)
{
throw new RuntimeException("Unable to construct the key manager:", e);
}
}
}
/*
* (non-Javadoc)
*
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#getSTSName()
*/
public String getSTSName()
{
return this.delegate.getSTSName();
}
/*
* (non-Javadoc)
*
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#getEncryptIssuedToken()
*/
public boolean encryptIssuedToken()
{
return this.delegate.isEncryptToken();
}
/*
* (non-Javadoc)
*
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#signIssuedToken()
*/
public boolean signIssuedToken()
{
return this.delegate.isSignToken();
}
/*
* (non-Javadoc)
*
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#getIssuedTokenTimeout()
*/
public long getIssuedTokenTimeout()
{
// return the timeout value in milliseconds.
return this.delegate.getTokenTimeout() * 1000;
}
/*
* (non-Javadoc)
*
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#getRequestHandlerClass()
*/
public WSTrustRequestHandler getRequestHandler()
{
if (this.handler == null)
this.handler = WSTrustServiceFactory.getInstance().createRequestHandler(this.delegate.getRequestHandler(),
this);
return this.handler;
}
/*
* (non-Javadoc)
*
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#getProviderForService(java.lang.String)
*/
public SecurityTokenProvider getProviderForService(String serviceName)
{
ServiceProviderType provider = this.spMetadata.get(serviceName);
if (provider != null)
{
return this.tokenProviders.get(provider.getTokenType());
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#getProviderForTokenType(java.lang.String)
*/
public SecurityTokenProvider getProviderForTokenType(String tokenType)
{
return this.tokenProviders.get(tokenType);
}
/*
* (non-Javadoc)
*
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#getProviderForTokenElementNS(java.lang.String, java.lang.String)
*/
public SecurityTokenProvider getProviderForTokenElementNS(String tokenLocalName, String tokenNamespace)
{
return this.tokenProviders.get(tokenLocalName + "$" + tokenNamespace);
}
/*
* (non-Javadoc)
*
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#getTokenTypeForService(java.lang.String)
*/
public String getTokenTypeForService(String serviceName)
{
ServiceProviderType provider = this.spMetadata.get(serviceName);
if (provider != null)
return provider.getTokenType();
return null;
}
/*
* (non-Javadoc)
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#getServiceProviderPublicKey(java.lang.String)
*/
public PublicKey getServiceProviderPublicKey(String serviceName)
{
PublicKey key = null;
if (this.trustManager != null)
{
try
{
// try using the truststore alias from the service provider metadata.
ServiceProviderType provider = this.spMetadata.get(serviceName);
if(provider != null && provider.getTruststoreAlias() != null)
{
key = this.trustManager.getPublicKey(provider.getTruststoreAlias());
}
// if there was no truststore alias or no PKC under that alias, use the KeyProvider mapping.
if(key == null)
{
key = this.trustManager.getValidatingKey(serviceName);
}
}
catch (Exception e)
{
throw new RuntimeException("Error obtaining public key for service " + serviceName, e);
}
}
return key;
}
/*
* (non-Javadoc)
* @see org.jboss.identity.federation.core.wstrust.STSConfiguration#getSTSKeyPair()
*/
public KeyPair getSTSKeyPair()
{
KeyPair keyPair = null;
if (this.trustManager != null)
{
try
{
keyPair = this.trustManager.getSigningKeyPair();
}
catch (Exception e)
{
throw new RuntimeException("Error obtaining signing key pair:", e);
}
}
return keyPair;
}
}