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>
*/
public class UsernamePasscodeClaimsProducer extends SSOProducer
implements SAMLR2Constants, SAMLR2MessagingConstants, SSOPlanningConstants {
private static final Log logger = LogFactory.getLog(UsernamePasscodeClaimsProducer.class);
public UsernamePasscodeClaimsProducer( AbstractCamelEndpoint<CamelMediationExchange> endpoint ) throws Exception {
super( endpoint );
}
@Override
protected void doProcess ( CamelMediationExchange exchange) throws Exception {
if (logger.isDebugEnabled())
logger.debug("Collecting Passcode claims");
CamelMediationMessage in = (CamelMediationMessage) exchange.getIn();
// -------------------------------------------------------------------------
// Collect claims
// -------------------------------------------------------------------------
if (logger.isDebugEnabled())
logger.debug("Starting to collect passcode 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/passcode 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.getTwoFactorAuthnUILocation(),
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 passcode = null;
String username = null;
// Addapt received simple claims to SAMLR Required token
for (Claim c : receivedClaims.getClaims()) {
CredentialClaim credentialClaim = (CredentialClaim) c;
if (credentialClaim.getQualifier().equalsIgnoreCase("username"))
username = (String) c.getValue();
if (credentialClaim.getQualifier().equalsIgnoreCase("passcode"))
passcode = (String) c.getValue();
}
// 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.PASSCODE_NS), passcode);
usernameToken.getOtherAttributes().put(new QName(AuthnCtxClass.TIME_SYNC_TOKEN_AUTHN_CTX.getValue()), "TRUE");
CredentialClaim credentialClaim = new CredentialClaimImpl(AuthnCtxClass.TIME_SYNC_TOKEN_AUTHN_CTX.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);
}
}