/*
* Atricore IDBus
*
* Copyright (c) 2009, Atricore Inc.
*
* 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.atricore.idbus.capabilities.sso.main.idp;
import org.apache.camel.builder.RouteBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.atricore.idbus.capabilities.sso.main.SSOException;
import org.atricore.idbus.capabilities.sso.main.common.AbstractSSOMediator;
import org.atricore.idbus.capabilities.sso.support.binding.SSOBinding;
import org.atricore.idbus.kernel.main.federation.metadata.EndpointDescriptor;
import org.atricore.idbus.kernel.main.mediation.IdentityMediationException;
import org.atricore.idbus.kernel.main.mediation.channel.SPChannel;
import org.atricore.idbus.kernel.main.mediation.endpoint.IdentityMediationEndpoint;
import java.util.Collection;
/**
* Saml v2.0 SP Mediator realizing IDP SSO Role for Single SignOn profiles.
*
* @org.apache.xbean.XBean element="idp-mediator"
*
* @author <a href="mailto:sgonzalez@atricore.org">Sebastian Gonzalez Oyuela</a>
* @version $Id: SSOIDPMediator.java 1359 2009-07-19 16:57:57Z sgonzalez $
*/
public class SSOIDPMediator extends AbstractSSOMediator {
private static final Log logger = LogFactory.getLog( SSOIDPMediator.class );
private String preferredSpAlias;
private String preferredIdpAlias;
private String preferredNameIdPolicy;
private SSOBinding preferredIdpSSOBinding = SSOBinding.SAMLR2_ARTIFACT;
private SSOBinding preferredIdpSLOBinding = SSOBinding.SAMLR2_ARTIFACT;
private String claimEndpointSelection;
@Override
protected RouteBuilder createIdPRoutes(final SPChannel spChannel) throws Exception {
// Create routes based on endpoints!
return new RouteBuilder() {
@Override
public void configure () throws Exception {
// --------------------------------------------------
// Process configured endpoints for this channel
// --------------------------------------------------
Collection<IdentityMediationEndpoint> endpoints = spChannel.getEndpoints();
if (endpoints == null)
throw new IdentityMediationException("No endpoints defined for spChannel : " + spChannel.getName());
for (IdentityMediationEndpoint endpoint : endpoints) {
SSOBinding binding = SSOBinding.asEnum(endpoint.getBinding());
EndpointDescriptor ed = resolveEndpoint(spChannel, endpoint);
switch (binding) {
// http endpoints
case SAMLR2_ARTIFACT:
case SAMLR11_ARTIFACT:
case SAMLR2_POST:
case SAMLR2_REDIRECT:
case SSO_ARTIFACT:
case SSO_REDIRECT:
case SSO_IDP_INITIATED_SSO_HTTP_SAML2:
case SSO_IDP_INITIATED_SSO_HTTP_SAML11:
// HTTP Bindings are handled with Camel
// FROM idbus-http TO samlr2-binding (through direct component)
from("idbus-http:" + ed.getLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName());
// FROM samlr-bind TO sso-idp
from("idbus-bind:camel://direct:" + ed.getName() +
"?binding=" + ed.getBinding() +
"&channelRef=" + spChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("sso-idp:" + ed.getType() +
"?channelRef=" + spChannel.getName() +
"&endpointRef=" + endpoint.getName());
if (ed.getResponseLocation() != null) {
// FROM idbus-http TO samlr2-binding (through direct component)
from("idbus-http:" + ed.getResponseLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-response");
// FROM samlr-bind TO sso-sp
from("idbus-bind:camel://direct:" + ed.getName() + "-response" +
"?binding=" + ed.getBinding() +
"&channelRef=" + spChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("sso-idp:" + ed.getType() +
"?channelRef=" + spChannel.getName() +
"&endpointRef=" + endpoint.getName() +
"&response=true");
}
break;
case SAMLR11_SOAP:
// ----------------------------------------------------------
// SOAP Incomming messages:
// ==> idbus-http ==> cxf ==> idbus-bind ==> sso-idp
// ----------------------------------------------------------
// FROM idbus-http TO cxf (through direct component)
from("idbus-http:" + ed.getLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-cxf");
// FROM cxf TO idbus-bind (through direct component)
from("cxf:camel://direct:"+ed.getName()+"-cxf" +
"?serviceClass=org.atricore.idbus.capabilities.sso.main.binding.services.SamlR11ServiceImpl" +
"&serviceName={urn:oasis:names:tc:SAML:1.0:wsdl}SAMLService" +
"&portName={urn:oasis:names:tc:SAML:1.0:wsdl}soap" +
"&dataFormat=POJO").
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName());
// FROM samlr-bind TO sso-idp
from("idbus-bind:camel://direct:" + ed.getName() +
"?binding=" + ed.getBinding() +
"&channelRef=" + spChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("sso-idp:" + ed.getType() +
"?channelRef=" + spChannel.getName() +
"&endpointRef=" + endpoint.getName());
if (ed.getResponseLocation() != null) {
// FROM idbus-http TO samlr2-binding (through direct component)
from("idbus-http:" + ed.getResponseLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-cxf-response");
// Receive HTTP requests and handle them as SOAP messages.
from("cxf:camel://direct:"+ed.getName()+"-cxf-response" +
"?serviceClass=org.atricore.idbus.capabilities.sso.main.binding.services.SamlR11ServiceImpl" +
"&serviceName={urn:oasis:names:tc:SAML:1.0:wsdl}SAMLService" +
"&portName={urn:oasis:names:tc:SAML:1.0:wsdl}soap" +
"&dataFormat=POJO").
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-response");
// FROM SAMLR1 SSOBinding TO sso-idp
from("idbus-bind:camel://" + ed.getName() + "-response" +
"?binding=" + ed.getBinding() +
"&channelRef=" + spChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("sso-idp:" + ed.getType() +
"?channelRef=" + spChannel.getName() +
"&endpointRef=" + endpoint.getName() +
"&response=true");
}
break;
case SAMLR2_SOAP:
// ----------------------------------------------------------
// SOAP Incomming messages:
// ==> idbus-http ==> cxf ==> idbus-bind ==> sso-idp
// ----------------------------------------------------------
// FROM idbus-http TO cxf (through direct component)
from("idbus-http:" + ed.getLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-cxf");
// FROM cxf TO idbus-bind (through direct component)
from("cxf:camel://direct:"+ed.getName()+"-cxf" +
"?serviceClass=org.atricore.idbus.capabilities.sso.main.binding.services.SamlR2ServiceImpl" +
"&serviceName={urn:oasis:names:tc:SAML:2.0:wsdl}SAMLService" +
"&portName={urn:oasis:names:tc:SAML:2.0:wsdl}soap" +
"&dataFormat=POJO").
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName());
// FROM samlr-bind TO sso-idp
from("idbus-bind:camel://direct:" + ed.getName() +
"?binding=" + ed.getBinding() +
"&channelRef=" + spChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("sso-idp:" + ed.getType() +
"?channelRef=" + spChannel.getName() +
"&endpointRef=" + endpoint.getName());
if (ed.getResponseLocation() != null) {
// FROM idbus-http TO samlr2-binding (through direct component)
from("idbus-http:" + ed.getResponseLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-cxf-response");
// Receive HTTP requests and handle them as SOAP messages.
from("cxf:camel://direct:"+ed.getName()+"-cxf-response" +
"?serviceClass=org.atricore.idbus.capabilities.sso.main.binding.services.SamlR2ServiceImpl" +
"&serviceName={urn:oasis:names:tc:SAML:2.0:wsdl}SAMLService" +
"&portName={urn:oasis:names:tc:SAML:2.0:wsdl}soap" +
"&dataFormat=POJO").
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-response");
// FROM SAMLR2 SSOBinding TO sso-idp
from("idbus-bind:camel://" + ed.getName() + "-response" +
"?binding=" + ed.getBinding() +
"&channelRef=" + spChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("sso-idp:" + ed.getType() +
"?channelRef=" + spChannel.getName() +
"&endpointRef=" + endpoint.getName() +
"&response=true");
}
break;
case SAMLR2_PAOS:
throw new SSOException("Unsupported SSOBinding " + binding.getValue());
case SAMLR2_LOCAL:
from("direct:" + ed.getLocation()).
to("direct:" + ed.getName() + "-local");
from("idbus-bind:camel://direct:" + ed.getName() + "-local" +
"?binding=" + ed.getBinding() +
"&channelRef=" + spChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("sso-idp:" + ed.getType() +
"?channelRef=" + spChannel.getName() +
"&endpointRef=" + endpoint.getName());
break;
case SSO_SOAP:
// ----------------------------------------------------------
// SOAP Incomming messages:
// ==> idbus-http ==> cxf ==> idbus-bind ==> sso-idp
// ----------------------------------------------------------
// FROM idbus-http TO cxf (through direct component)
from("idbus-http:" + ed.getLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-cxf");
// FROM cxf TO idbus-bind (through direct component)
from("cxf:camel://direct:"+ed.getName()+"-cxf" +
"?serviceClass=org.atricore.idbus.capabilities.sso.main.binding.services.SSOServiceImpl" +
"&serviceName={urn:org:atricore:idbus:common:sso:1.0:wsdl}SSOService" +
"&portName={urn:org:atricore:idbus:common:sso:1.0:wsdl}soap" +
"&dataFormat=POJO").
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName());
// FROM samlr-bind TO sso-idp
from("idbus-bind:camel://direct:" + ed.getName() +
"?binding=" + ed.getBinding() +
"&channelRef=" + spChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("sso-idp:" + ed.getType() +
"?channelRef=" + spChannel.getName() +
"&endpointRef=" + endpoint.getName());
if (ed.getResponseLocation() != null) {
// FROM idbus-http TO samlr2-binding (through direct component)
from("idbus-http:" + ed.getResponseLocation()).
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-cxf-response");
// Receive HTTP requests and handle them as SOAP messages.
from("cxf:camel://direct:"+ed.getName()+"-cxf-response" +
"?serviceClass=org.atricore.idbus.capabilities.sso.main.binding.services.SSOServiceImpl" +
"&serviceName={urn:org:atricore:idbus:common:sso:1.0:wsdl}SAMLService" +
"&portName={urn:org:atricore:idbus:common:sso:1.0:wsdl}soap" +
"&dataFormat=POJO").
process(new LoggerProcessor(getLogger())).
to("direct:" + ed.getName() + "-response");
// FROM SAMLR2 SSOBinding TO sso-idp
from("idbus-bind:camel://" + ed.getName() + "-response" +
"?binding=" + ed.getBinding() +
"&channelRef=" + spChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("sso-idp:" + ed.getType() +
"?channelRef=" + spChannel.getName() +
"&endpointRef=" + endpoint.getName() +
"&response=true");
}
break;
case SSO_LOCAL:
from("direct:" + ed.getLocation()).
to("direct:" + ed.getName() + "-local");
from("idbus-bind:camel://direct:" + ed.getName() + "-local" +
"?binding=" + ed.getBinding() +
"&channelRef=" + spChannel.getName()).
process(new LoggerProcessor(getLogger())).
to("sso-idp:" + ed.getType() +
"?channelRef=" + spChannel.getName() +
"&endpointRef=" + endpoint.getName());
break;
default:
throw new SSOException("Unsupported SSOBinding " + binding.getValue());
}
}
}
};
}
public String getPreferredSpAlias() {
return preferredSpAlias;
}
public void setPreferredSpAlias(String preferredSpAlias) {
this.preferredSpAlias = preferredSpAlias;
}
public String getPreferredNameIdPolicy() {
return preferredNameIdPolicy;
}
public void setPreferredNameIdPolicy(String preferredNameIdPolicy) {
this.preferredNameIdPolicy = preferredNameIdPolicy;
}
public String getPreferredIdpAlias() {
return preferredIdpAlias;
}
public void setPreferredIdpAlias(String preferredIdpAlias) {
this.preferredIdpAlias = preferredIdpAlias;
}
public String getPreferredIdpSSOBinding() {
return this.preferredIdpSSOBinding.getValue();
}
public void setPreferredIdpSSOBinding(String binding) {
this.preferredIdpSSOBinding = SSOBinding.asEnum(binding);
}
public SSOBinding getPreferredIdpSSOBindingValue() {
return preferredIdpSSOBinding;
}
public String getPreferredIdpSLOBinding() {
return this.preferredIdpSLOBinding.getValue();
}
public void setPreferredIdpSLOBinding(String binding) {
this.preferredIdpSLOBinding = SSOBinding.asEnum(binding);
}
public SSOBinding getPreferredIdpSLOBindingValue() {
return preferredIdpSLOBinding;
}
public String getClaimEndpointSelection() {
return claimEndpointSelection;
}
public void setClaimEndpointSelection(String claimEndpointSelection) {
this.claimEndpointSelection = claimEndpointSelection;
}
}