/* * 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.emitter; import oasis.names.tc.saml._2_0.assertion.AssertionType; import oasis.names.tc.saml._2_0.assertion.ObjectFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.atricore.idbus.capabilities.sso.main.common.plans.SSOPlanningConstants; import org.atricore.idbus.capabilities.sso.support.SAMLR2Constants; import org.atricore.idbus.capabilities.sso.support.core.encryption.SamlR2Encrypter; import org.atricore.idbus.capabilities.sso.support.core.signature.SamlR2Signer; import org.atricore.idbus.capabilities.sts.main.AbstractSecurityTokenEmitter; import org.atricore.idbus.capabilities.sts.main.SecurityTokenEmissionException; import org.atricore.idbus.capabilities.sts.main.SecurityTokenProcessingContext; import org.atricore.idbus.capabilities.sts.main.WSTConstants; import org.atricore.idbus.kernel.main.authn.SecurityToken; import org.atricore.idbus.kernel.main.authn.SecurityTokenImpl; import org.atricore.idbus.kernel.planning.IdentityArtifact; import org.atricore.idbus.kernel.planning.IdentityArtifactImpl; import org.atricore.idbus.kernel.planning.IdentityPlanExecutionExchange; import javax.security.auth.Subject; import javax.xml.namespace.QName; /** * <p> * This emitter and bound componetnts like plans and bpm ations, must respond to SAML 2.0 WebSSO Login profile and * WS-Trust 1.3 SAML 2.0 Token Profile: * </p> * <ul> * <li><strong>SAML 2.0 Core, Assertions (section 2.3)</strong></li> * <li><strong>SAML 2.0 Core, Authentication Request Protocol (section 3.4)</strong></li> * <li><strong>SAML 2.0 Profiles, Web Browser SSO Profile (section 4.1)</strong></li> * <li><strong>WS-Trust 1.3 Interoperability Profile: SAML 2.0 Token Profile, SAML 2 Token Creation (section 2.3)</strong></li> * </ul> * * @org.apache.xbean.XBean element="token-emitter" * * @author <a href="mailto:gbrigand@josso.org">Gianluca Brigandi</a> * @version $Id: SamlR2SecurityTokenEmitter.java 1335 2009-06-24 16:34:38Z sgonzalez $ */ public class SamlR2SecurityTokenEmitter extends AbstractSecurityTokenEmitter implements SSOPlanningConstants { private static final Log logger = LogFactory.getLog(SamlR2SecurityTokenEmitter.class); private SamlR2Signer signer; private SamlR2Encrypter encrypter; @Override public boolean isTargetedEmitter(SecurityTokenProcessingContext context, Object requestToken, String tokenType) { // We can emit for any context with a valid subject when Token Type is SAMLR2! return context.getProperty(WSTConstants.SUBJECT_PROP) != null && WSTConstants.WST_SAMLR2_TOKEN_TYPE.equals(tokenType); } /** * This creates an identity artifact containing an empty samlv2 assertion. * @param requestToken * @param tokenType * @return */ protected IdentityArtifact createOutArtifact(Object requestToken, String tokenType) { ObjectFactory samlObjectFactory; samlObjectFactory = new ObjectFactory(); AssertionType assertion = samlObjectFactory.createAssertionType(); return new IdentityArtifactImpl(new QName(SAMLR2Constants.SAML_ASSERTION_NS, "Assertion"), assertion); } @Override protected IdentityPlanExecutionExchange createIdentityPlanExecutionExchange(SecurityTokenProcessingContext context) { IdentityPlanExecutionExchange ex = super.createIdentityPlanExecutionExchange(context); // Signing and Encryption tools ex.setTransientProperty(VAR_SAMLR2_SIGNER, signer); ex.setTransientProperty(VAR_SAMLR2_ENCRYPTER, encrypter); // Publish emission context ex.setTransientProperty(WSTConstants.VAR_EMISSION_CTX, context); SamlR2SecurityTokenEmissionContext ctx = (SamlR2SecurityTokenEmissionContext) ex.getProperty(WSTConstants.RST_CTX); if (ctx != null) { logger.debug("Setting SamlR2 Context information"); ex.setTransientProperty(VAR_SAMLR2_EMITTER_CXT, ctx); ex.setProperty(VAR_SAMLR2_AUTHN_REQUEST, ctx.getRequest()); ex.setProperty(VAR_SUBJECT, ctx.getSubject()); ex.setProperty(WSTConstants.VAR_EMISSION_CTX, context); ex.setProperty(VAR_IDENTITY_PLAN_NAME, ctx.getIdentityPlanName()); ex.setProperty(VAR_COT_MEMBER, ctx.getMember()); ex.setProperty(VAR_RESPONSE_MODE, ctx.getAuthnState().getResponseMode()); ex.setProperty(VAR_DESTINATION_ENDPOINT_DESCRIPTOR, ctx.getSpAcs()); } else { logger.debug("No SamlR2 Emitter context found"); } return ex; } @Override public SecurityToken emit(SecurityTokenProcessingContext context, Object requestToken, String tokenType) throws SecurityTokenEmissionException { // Lookup identityplan sent by SAML Producers SamlR2SecurityTokenEmissionContext samlr2EmissionCtx = (SamlR2SecurityTokenEmissionContext) context.getProperty(WSTConstants.RST_CTX); String identityPlanName = (String) samlr2EmissionCtx.getIdentityPlanName(); identityPlan.set(getIdentityPlanRegistry().lookup(identityPlanName)); // Emit, now that the plan is in place SecurityToken st = super.emit(context, requestToken, tokenType); if (samlr2EmissionCtx != null) { // Propagate authenticated subject to samlr2 security token emitter context samlr2EmissionCtx.setSubject((Subject) context.getProperty(WSTConstants.SUBJECT_PROP)); logger.debug("Propagating Subject " + samlr2EmissionCtx.getSubject() + " to Security Token Emission Context"); // Propagate generated assertion to context. AssertionType assertion = (AssertionType) st.getContent(); samlr2EmissionCtx.setAssertion(assertion); if (logger.isDebugEnabled()) logger.debug("Propagating Assertion " + assertion.getID() + " to Security Token Emission Context"); } return st; } public SamlR2Signer getSigner() { return signer; } public void setSigner(SamlR2Signer signer) { this.signer = signer; } public SamlR2Encrypter getEncrypter() { return encrypter; } public void setEncrypter(SamlR2Encrypter encrypter) { this.encrypter = encrypter; } @Override protected SecurityToken doMakeToken(String uuid, Object content) { return new SecurityTokenImpl(uuid, WSTConstants.WST_SAMLR2_TOKEN_TYPE, content); } }