/* * 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.claims.producers; 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.claims.SSOClaimsMediator; import org.atricore.idbus.capabilities.sso.main.claims.SSOCredentialClaimsRequest; import org.atricore.idbus.capabilities.sso.main.claims.SSOCredentialClaimsResponse; import org.atricore.idbus.capabilities.sso.main.common.plans.SSOPlanningConstants; import org.atricore.idbus.capabilities.sso.main.common.producers.SSOProducer; import org.atricore.idbus.capabilities.sso.support.SAMLR2Constants; import org.atricore.idbus.capabilities.sso.support.SAMLR2MessagingConstants; import org.atricore.idbus.capabilities.sso.support.auth.AuthnCtxClass; import org.atricore.idbus.capabilities.sso.support.binding.SSOBinding; import org.atricore.idbus.kernel.main.authn.Constants; import org.atricore.idbus.kernel.main.federation.metadata.EndpointDescriptor; import org.atricore.idbus.kernel.main.federation.metadata.EndpointDescriptorImpl; import org.atricore.idbus.kernel.main.mediation.Channel; import org.atricore.idbus.kernel.main.mediation.MediationMessageImpl; import org.atricore.idbus.kernel.main.mediation.camel.AbstractCamelEndpoint; import org.atricore.idbus.kernel.main.mediation.camel.component.binding.CamelMediationExchange; import org.atricore.idbus.kernel.main.mediation.camel.component.binding.CamelMediationMessage; import org.atricore.idbus.kernel.main.mediation.claim.*; import org.atricore.idbus.kernel.main.mediation.endpoint.IdentityMediationEndpoint; import org.oasis_open.docs.wss._2004._01.oasis_200401_wss_wssecurity_secext_1_0.AttributedString; import org.oasis_open.docs.wss._2004._01.oasis_200401_wss_wssecurity_secext_1_0.UsernameTokenType; import javax.xml.namespace.QName; import java.io.IOException; /** * @author <a href="mailto:sgonzalez@atricore.org">Sebastian Gonzalez Oyuela</a> * @version $Id$ */ public class UsernamePasswordClaimsProducer extends SSOProducer implements SAMLR2Constants, SAMLR2MessagingConstants, SSOPlanningConstants { private static final Log logger = LogFactory.getLog( UsernamePasswordClaimsProducer.class ); public UsernamePasswordClaimsProducer( AbstractCamelEndpoint<CamelMediationExchange> endpoint ) throws Exception { super( endpoint ); } @Override protected void doProcess ( CamelMediationExchange exchange) throws Exception { if (logger.isDebugEnabled()) logger.debug("Collecting Password claims"); CamelMediationMessage in = (CamelMediationMessage) exchange.getIn(); // ------------------------------------------------------------------------- // Collect claims // ------------------------------------------------------------------------- if (logger.isDebugEnabled()) logger.debug("Starting to collect password claims"); SSOCredentialClaimsRequest claimsRequest = (SSOCredentialClaimsRequest) in.getMessage().getContent(); if (logger.isDebugEnabled()) logger.debug("Storing claims request as local variable, id:" + claimsRequest.getId()); in.getMessage().getState().setLocalVariable("urn:org:atricore:idbus:credential-claims-request", claimsRequest); doProcessClaimsRequest(exchange, claimsRequest); } @Override protected void doProcessResponse(CamelMediationExchange exchange) throws Exception { // ------------------------------------------------------------------------- // Process collected claims // ------------------------------------------------------------------------- if (logger.isDebugEnabled()) logger.debug("Received username/password claims"); CamelMediationMessage in = (CamelMediationMessage) exchange.getIn(); CredentialClaimsResponse credentialClaimsResponse = (CredentialClaimsResponse) in.getMessage().getContent(); CredentialClaimsRequest credentialClaimsRequest = (CredentialClaimsRequest) in.getMessage().getState().getLocalVariable("urn:org:atricore:idbus:credential-claims-request"); if (credentialClaimsRequest == null) throw new IllegalStateException("Claims request not found!"); if (logger.isDebugEnabled()) logger.debug("Recovered claims request from local variable, id:" + credentialClaimsRequest.getId()); doProcessReceivedClaims(exchange, credentialClaimsRequest, credentialClaimsResponse.getClaimSet()); } protected void doProcessClaimsRequest(CamelMediationExchange exchange, CredentialClaimsRequest credentialClaimsRequest) throws IOException { SSOClaimsMediator mediator = (SSOClaimsMediator)channel.getIdentityMediator(); CamelMediationMessage in = (CamelMediationMessage) exchange.getIn(); EndpointDescriptor ed = new EndpointDescriptorImpl( "BasicAuthnLoginForm", "BasicAuthnLoginForm", SSOBinding.SSO_ARTIFACT.getValue(), mediator.getBasicAuthnUILocation(), null); CamelMediationMessage out = (CamelMediationMessage) exchange.getOut(); out.setMessage( new MediationMessageImpl(credentialClaimsRequest.getId(), credentialClaimsRequest, "ClaimsRequest", null, ed, in.getMessage().getState()) ); exchange.setOut(out); } protected void doProcessReceivedClaims(CamelMediationExchange exchange, CredentialClaimsRequest credentialClaimsRequest, ClaimSet receivedClaims) throws Exception { CamelMediationMessage in = (CamelMediationMessage) exchange.getIn(); SSOClaimsMediator mediator = ((SSOClaimsMediator) channel.getIdentityMediator()); // This is the binding we're using to send the response SSOBinding binding = SSOBinding.SSO_ARTIFACT; Channel issuer = credentialClaimsRequest.getIssuerChannel(); IdentityMediationEndpoint claimsProcessingEndpoint = null; // Look for an endpoint to send the response for (IdentityMediationEndpoint endpoint : issuer.getEndpoints()) { if (endpoint.getType().equals(credentialClaimsRequest.getIssuerEndpoint().getType()) && endpoint.getBinding().equals(binding.getValue())) { claimsProcessingEndpoint = endpoint; break; } } if (claimsProcessingEndpoint == null) { throw new SSOException("No endpoint supporting " + binding + " of type " + credentialClaimsRequest.getIssuerEndpoint().getType() + " found in channel " + credentialClaimsRequest.getIssuerChannel().getName()); } EndpointDescriptor ed = mediator.resolveEndpoint(credentialClaimsRequest.getIssuerChannel(), claimsProcessingEndpoint); String password = null; String username = null; boolean rememberMe = false; // Addapt received simple claims to SAMLR Required token for (Claim c : receivedClaims.getClaims()) { if (c instanceof CredentialClaim) { CredentialClaim credentialClaim = (CredentialClaim) c; if (credentialClaim.getQualifier().equalsIgnoreCase("username")) username = (String) c.getValue(); if (credentialClaim.getQualifier().equalsIgnoreCase("password")) password = (String) c.getValue(); } else if (c instanceof UserClaim) { UserClaim userClaim = (UserClaim) c; if (userClaim.getName().equalsIgnoreCase("rememberMe")) rememberMe = (Boolean) userClaim.getValue(); } } AuthnCtxClass authnCtxClass = null; if (mediator.getBasicAuthnCtxClass() != null) { if (logger.isDebugEnabled()) logger.debug("Using configured Basic Authentication Context class: " + mediator.getBasicAuthnCtxClass()); authnCtxClass = AuthnCtxClass.asEnum(mediator.getBasicAuthnCtxClass()); } else { if (logger.isDebugEnabled()) logger.debug("Using default Basic Authentication Context class: " + AuthnCtxClass.PASSWORD_AUTHN_CTX); authnCtxClass = AuthnCtxClass.PASSWORD_AUTHN_CTX; } // Build a SAMLR2 Compatible Security token UsernameTokenType usernameToken = new UsernameTokenType (); AttributedString usernameString = new AttributedString(); usernameString.setValue( username ); usernameToken.setUsername( usernameString ); usernameToken.getOtherAttributes().put(new QName(Constants.PASSWORD_NS), password ); usernameToken.getOtherAttributes().put(new QName(authnCtxClass.getValue()), "TRUE"); usernameToken.getOtherAttributes().put(new QName(Constants.REMEMBERME_NS), rememberMe ? "TRUE" : "FALSE"); CredentialClaim credentialClaim = new CredentialClaimImpl(authnCtxClass.getValue(), usernameToken); ClaimSet claims = new ClaimSetImpl(); claims.addClaim(credentialClaim); SSOCredentialClaimsResponse claimsResponse = new SSOCredentialClaimsResponse(credentialClaimsRequest.getId() /* TODO : Generate new ID !*/, channel, credentialClaimsRequest.getId(), claims, credentialClaimsRequest.getRelayState()); CamelMediationMessage out = (CamelMediationMessage) exchange.getOut(); out.setMessage(new MediationMessageImpl(claimsResponse.getId(), claimsResponse, "ClaimsResponse", null, ed, in.getMessage().getState())); exchange.setOut(out); } }