package org.atricore.idbus.applications.server.ui.claims;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.atricore.idbus.capabilities.sso.main.binding.SsoHttpArtifactBinding;
import org.atricore.idbus.capabilities.sso.support.auth.AuthnCtxClass;
import org.atricore.idbus.capabilities.sso.support.binding.SSOBinding;
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.*;
import org.atricore.idbus.kernel.main.mediation.camel.component.binding.AbstractMediationHttpBinding;
import org.atricore.idbus.kernel.main.mediation.claim.*;
import org.atricore.idbus.kernel.main.mediation.endpoint.IdentityMediationEndpoint;
import org.atricore.idbus.kernel.main.util.UUIDGenerator;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author <a href=mailto:sgonzalez@atricore.org>Sebastian Gonzalez Oyuela</a>
*/
public class OpenIDClaimsController extends SimpleFormController {
private static final Log logger = LogFactory.getLog(OpenIDClaimsController.class);
private UUIDGenerator idGenerator = new UUIDGenerator();
private MessageQueueManager artifactQueueManager;
private IdentityMediationUnitRegistry idauRegistry;
@Override
protected Object formBackingObject(HttpServletRequest hreq) throws Exception {
String artifactId = hreq.getParameter(SsoHttpArtifactBinding.SSO_ARTIFACT_ID);
CollectOpenIDClaims collectClaims = new CollectOpenIDClaims();
if (logger.isDebugEnabled())
logger.debug("Creating form backing object for artifact " + artifactId);
// Lookup for ClaimsRequest!
CredentialClaimsRequest credentialClaimsRequest = (CredentialClaimsRequest) artifactQueueManager.pullMessage(new ArtifactImpl(artifactId));
if (credentialClaimsRequest != null) {
if (logger.isDebugEnabled())
logger.debug("Received claims request " + credentialClaimsRequest.getId() +
" from " + credentialClaimsRequest.getIssuerChannel() +
" at " + credentialClaimsRequest.getIssuerEndpoint());
if (credentialClaimsRequest.getLastErrorId() != null) {
if (logger.isDebugEnabled())
logger.debug("Received last error ID : " +
credentialClaimsRequest.getLastErrorId() +
" ("+ credentialClaimsRequest.getLastErrorMsg()+")");
hreq.setAttribute("statusMessageKey", "claims.text.invalidCredentials");
}
collectClaims.setCredentialClaimsRequest(credentialClaimsRequest);
} else {
logger.debug("No claims request received!");
}
return collectClaims;
}
@Override
protected ModelAndView onSubmit(HttpServletRequest hreq,
HttpServletResponse hres,
Object o,
BindException error) throws Exception {
CollectOpenIDClaims cmd = (CollectOpenIDClaims) o;
if (logger.isDebugEnabled())
logger.debug("Received CMD" + cmd);
CredentialClaimsRequest requestCredential = cmd.getCredentialClaimsRequest();
if (logger.isDebugEnabled())
logger.debug("Collecting OpenID claim for request " +
(requestCredential != null ? requestCredential.getId() : "NULL"));
ClaimSet claims = new ClaimSetImpl();
claims.addClaim(new CredentialClaimImpl("openid", cmd.getOpenid()));
claims.addClaim(new CredentialClaimImpl("rememberMe", cmd.isRememberMe()));
CredentialClaimsResponse responseCredential = new CredentialClaimsResponseImpl(idGenerator.generateId(),
null,
requestCredential.getId(),
claims,
requestCredential.getRelayState());
EndpointDescriptor claimsEndpoint = resolveClaimsEndpoint(requestCredential);
if (claimsEndpoint == null) {
logger.error("No claims endpoint found!");
// TODO : Create error and redirect to error view using 'IDBusErrArt'
}
// We want the binding factory to use a binding component to build this URL, if possible
Channel claimsChannel = requestCredential.getClaimsChannel();
claimsChannel = getNonSerializedChannel(claimsChannel);
String claimsEndpointUrl = null;
if (claimsChannel != null) {
MediationBindingFactory f = claimsChannel.getIdentityMediator().getBindingFactory();
MediationBinding b = f.createBinding(SSOBinding.SSO_ARTIFACT.getValue(), requestCredential.getClaimsChannel());
claimsEndpointUrl = claimsEndpoint.getResponseLocation();
if (claimsEndpointUrl == null)
claimsEndpointUrl = claimsEndpoint.getLocation();
if (b instanceof AbstractMediationHttpBinding) {
AbstractMediationHttpBinding httpBinding = (AbstractMediationHttpBinding) b;
claimsEndpointUrl = ((AbstractMediationHttpBinding) b).buildHttpTargetLocation(hreq, claimsEndpoint, true);
} else {
logger.warn("Cannot delegate URL construction to binding, non-http binding found " + b);
claimsEndpointUrl = claimsEndpoint.getResponseLocation() != null ?
claimsEndpoint.getResponseLocation() : claimsEndpoint.getLocation();
}
} else {
logger.warn("Cannot delegate URL construction to binding, valid definition of channel " +
requestCredential.getClaimsChannel().getName() + " not foud ...");
claimsEndpointUrl = claimsEndpoint.getResponseLocation() != null ?
claimsEndpoint.getResponseLocation() : claimsEndpoint.getLocation();
}
if (logger.isDebugEnabled())
logger.debug("Using claims endpoint URL ["+claimsEndpointUrl+"]");
Artifact a = getArtifactQueueManager().pushMessage(responseCredential);
claimsEndpointUrl += "?SSOArt=" + a.getContent();
if (logger.isDebugEnabled())
logger.debug("Returning claims to " + claimsEndpointUrl);
return new ModelAndView(new RedirectView(claimsEndpointUrl));
}
public void setArtifactQueueManager(MessageQueueManager artifactQueueManager) {
this.artifactQueueManager = artifactQueueManager;
}
public MessageQueueManager getArtifactQueueManager() {
return artifactQueueManager;
}
public IdentityMediationUnitRegistry getIdauRegistry() {
return idauRegistry;
}
public void setIdauRegistry(IdentityMediationUnitRegistry idauRegistry) {
this.idauRegistry = idauRegistry;
}
protected EndpointDescriptor resolveClaimsEndpoint(CredentialClaimsRequest requestCredential) throws IdentityMediationException {
for (IdentityMediationEndpoint endpoint : requestCredential.getClaimsChannel().getEndpoints()) {
// Look for unspecified claim endpoint using Artifacc binding
if (AuthnCtxClass.OPENID_AUTHN_CTX.getValue().equals(endpoint.getType()) &&
SSOBinding.SSO_ARTIFACT.getValue().equals(endpoint.getBinding())) {
if (logger.isDebugEnabled())
logger.debug("Resolved claims endpoint " + endpoint);
return new EndpointDescriptorImpl(endpoint.getName(),
endpoint.getType(),
endpoint.getBinding(),
requestCredential.getClaimsChannel().getLocation() + endpoint.getLocation(),
endpoint.getResponseLocation() != null ?
requestCredential.getClaimsChannel().getLocation() + endpoint.getResponseLocation() : null);
}
}
return null;
}
protected Channel getNonSerializedChannel(Channel serChannel) {
for (IdentityMediationUnit idu : idauRegistry.getIdentityMediationUnits()) {
for (Channel c : idu.getChannels()) {
if (c.getName().equals(serChannel.getName()))
return c;
}
}
return null;
}
}