-
1. Re: Externalize IDP and SP Configurations
firstlion Jan 11, 2012 2:44 AM (in response to pcraveiro)Hi,
The following works fine for me: In the standalone.xml - configFile add the following under system-properties:
<property name="idp.url" value="http://localhost:8080/idp/"/>
<property name="zponf.url" value="http://localhost:8080/zponf/priv/anmelden.jsf"/>
<property name="trusted.domain" value="localhost"/>
Of course, you have to edit it for your needs. In IDP-picketlink-idfed.xml:
<PicketLinkIDP xmlns="urn:picketlink:identity-federation:config:1.0" >
<IdentityURL>${idp.url::http://localhost:8080/idp/}</IdentityURL>
<Trust>
<Domains>${trusted.domain::localhost}</Domains>
</Trust>
</PicketLinkIDP>
And in SP-picketlink-idfed.xml:
<PicketLinkSP xmlns="urn:picketlink:identity-federation:config:1.0" ServerEnvironment="jboss">
<IdentityURL>${idp.url::http://localhost:8080/idp/}</IdentityURL>
<ServiceURL>${zponf.url::http://localhost:8080/zponf/priv/anmelden.jsf}</ServiceURL>
</PicketLinkSP>
So, the idfed.xml-files aren't used anymore (there are online the default-values defined). The real values to use, you can define and edit in the standalone.xml-file. If you don't use the standalone-mode of JBoss or you use another server, there is a similar way, i think.
I hope, it helps you,
Martin
-
2. Re: Externalize IDP and SP Configurations
pcraveiro Jan 11, 2012 11:45 AM (in response to firstlion)Hi Martin,
Thanks for your reply.
Actually I'm already using system properties for some configurations. But in my case, I also using signatures. When using signatures the configurations related with the KeyProvider are hard to externalize using system properties. Here is a example of my picketlink-idfed.xml file:
<PicketLinkSP xmlns="urn:picketlink:identity-federation:config:1.0">
<IdentityURL>${idp-sig.url::http://localhost:8080/idp/}</IdentityURL>
<ServiceURL>http://${jboss.bind.address}:8080/sp-example/</ServiceURL>
<KeyProvider
ClassName="org.picketlink.identity.federation.core.impl.KeyStoreKeyManager">
<Auth Key="KeyStoreURL" Value="${jboss.server.home.dir}/customer_deploy/configurations/jbid_test_keystore.jks" />
<Auth Key="KeyStorePass" Value="###### />
<Auth Key="SigningKeyPass" Value="###### />
<Auth Key="SigningKeyAlias" Value="${jboss.bind.address}" />
<ValidatingAlias Key="192.168.1.1" Value="192.168.1.1" />
<ValidatingAlias Key="192.168.1.2" Value="192.168.1.2" />
...
</KeyProvider>
</PicketLinkSP>
I think it's a good and common feature to allow read this file from any directory in the filesystem. That way, SPs and IDPs don't need to worry about enviroment (dev, prod, test) differences.
To workaround this I'm working in a custom implementation of SAMLConfigurationProvider.
Best regards,
Pedro Igor
-
3. Re: Externalize IDP and SP Configurations
pcraveiro Jan 12, 2012 1:33 PM (in response to pcraveiro)Hi,
Here is a Custom SAMLConfigurationProvider that allows to externalize and also to avoid some SP configurations duplication using a picketlink-idfed.xml file as template.
public class ExternalSAMLConfigurationProvider implements SAMLConfigurationProvider
{
private static final String DEFAULT_IDP_CONFIG_FILE = System.getProperty("jboss.server.home.dir") + "/picketlink/picketlink-idfed-idp.xml";
private static final String DEFAULT_CONFIG_PROTOCOL = "file://";
/* (non-Javadoc)
* @see org.picketlink.identity.federation.web.util.SAMLConfigurationProvider#getIDPConfiguration()
*/
@Override
public IDPType getIDPConfiguration() throws ProcessingException
{
try
{
return ConfigurationUtil.getIDPConfiguration(getConfiguration(getIDPConfigurationFilePath()));
}
catch (Exception e)
{
throw new ProcessingException("Could not load IDP configuration: " + getIDPConfigurationFilePath(), e);
}
}
/* (non-Javadoc)
* @see org.picketlink.identity.federation.web.util.SAMLConfigurationProvider#getSPConfiguration()
*/
@Override
public SPType getSPConfiguration() throws ProcessingException
{
String serviceProviderId = loadServiceProviderId();
try
{
SPType spConfiguration = ConfigurationUtil.getSPConfiguration(getConfiguration(getSPConfigurationFilePath(serviceProviderId)));
// the keyprovider configuration is overrided by the ones defined in the template file
spConfiguration.setKeyProvider(getSPTemplateConfig().getKeyProvider());
return spConfiguration;
}
catch (Exception e)
{
throw new ProcessingException("Could not load SP configuration: " + getIDPConfigurationFilePath(), e);
}
}
/**
* Loads a picketlink-idfed.xml file to be used as a template for the SP configuration. This avoid to duplicate some configurations like the ones related with the KeyProvider.
*/
private SPType getSPTemplateConfig() throws ParsingException, FileNotFoundException
{
return ConfigurationUtil.getSPConfiguration(new FileInputStream(System.getProperty("jboss.server.home.dir") + "/picketlink/picketlink-idfed-keyprovider-config.xml"));
}
/**
* Loads a identifier to be used to locate the specific picketlink-idfed.xml file for a SP.
*/
private String loadServiceProviderId()
{
Properties serviceProviderProperties = new Properties();
try
{
serviceProviderProperties.load(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("picketlink.properties"));
return serviceProviderProperties.getProperty("picketlink.sso.sp.id");
}
catch (Exception e)
{
throw new IllegalStateException("Nao foi possivel ler o arquivo de propriedades do Picketlink.", e);
}
finally
{
serviceProviderProperties = null;
}
}
/**
* Returns the SP configuration file path.
*/
private String getSPConfigurationFilePath(String serviceProviderId)
{
String spConfigDir = System.getProperty("picketlink.config.sp.file.dir", System.getProperty("jboss.server.home.dir") + "/picketlink");
return DEFAULT_CONFIG_PROTOCOL + spConfigDir + "/picketlink-idfed-" + serviceProviderId + ".xml";
}
/**
* Returns the IDP configuration file path.
*/
private String getIDPConfigurationFilePath()
{
return DEFAULT_CONFIG_PROTOCOL + System.getProperty("picketlink.config.idp.file", DEFAULT_IDP_CONFIG_FILE);
}
/**
* Loads a file
*/
protected InputStream getConfiguration(String fileName) throws ConfigurationException
{
URL configurationFileURL = null;
try
{
if (configurationFileURL == null)
{
configurationFileURL = Thread.currentThread().getContextClassLoader().getResource(fileName);
}
if (configurationFileURL == null)
{
configurationFileURL = new URL(fileName);
}
return configurationFileURL.openStream();
}
catch (Exception e)
{
throw new ConfigurationException("The file could not be loaded: " + fileName, e);
}
}
}
-
4. Re: Externalize IDP and SP Configurations
pcraveiro Jan 18, 2012 7:53 AM (in response to pcraveiro)Hi,
After using my custom configProvider I realized that Picketlink first checks the existence for a picketlink-idfed.xml file inside the application, by default in WEB-INF/picketlink-idfed.xml. Here is a snippet from the BaseFormAuthenticator class:
protected void processConfiguration()
{
ServletContext servletContext = context.getServletContext();
InputStream is = servletContext.getResourceAsStream(configFile);
if (is == null)
throw new RuntimeException(ErrorCodes.SERVICE_PROVIDER_CONF_FILE_MISSING + configFile);
try
{
if (configProvider != null)
{
spConfiguration = configProvider.getSPConfiguration();
}
else
{
spConfiguration = ConfigurationUtil.getSPConfiguration(is);
}
if (StringUtil.isNotNull(spConfiguration.getIdpMetadataFile()))
{
processIDPMetadataFile(spConfiguration.getIdpMetadataFile());
}
else
{
this.identityURL = spConfiguration.getIdentityURL();
}
this.serviceURL = spConfiguration.getServiceURL();
this.canonicalizationMethod = spConfiguration.getCanonicalizationMethod();
log.info("BaseFormAuthenticator:: Setting the CanonicalizationMethod on XMLSignatureUtil::"
+ canonicalizationMethod);
XMLSignatureUtil.setCanonicalizationMethodType(canonicalizationMethod);
if (trace)
log.trace("Identity Provider URL=" + this.identityURL);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
The motivation behind my custom configProvider is to remove the picketlink-idfed.xml from the applications and if this file is not present in the default location a exception is throwed
I think the right thing to do here is to throw the exception only when no custom configProvider is specified. Something like this:
protected void processConfiguration()
{
try
{
if (configProvider != null)
{
spConfiguration = configProvider.getSPConfiguration();
}
else
{
ServletContext servletContext = context.getServletContext();
InputStream is = servletContext.getResourceAsStream(configFile);
if (is == null)
throw new RuntimeException(ErrorCodes.SERVICE_PROVIDER_CONF_FILE_MISSING + configFile);
spConfiguration = ConfigurationUtil.getSPConfiguration(is);
}
...
}
What do you think ?
Thanks,
Pedro Igor