package org.atricore.idbus.capabilities.sso.main.select.selectors; import org.apache.commons.codec.binary.Base64; 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.select.SSOEntitySelectorMediator; import org.atricore.idbus.capabilities.sso.main.select.internal.EntitySelectionState; import org.atricore.idbus.capabilities.sso.main.select.spi.AbstractEntitySelector; import org.atricore.idbus.capabilities.sso.main.select.spi.EntitySelectionContext; 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.CircleOfTrustManager; import org.atricore.idbus.kernel.main.federation.metadata.CircleOfTrustMemberDescriptor; 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.FederationChannel; import org.atricore.idbus.kernel.main.mediation.claim.ClaimChannel; import org.atricore.idbus.kernel.main.mediation.claim.UserClaim; import org.atricore.idbus.kernel.main.mediation.endpoint.IdentityMediationEndpoint; import org.atricore.idbus.kernel.main.mediation.provider.FederatedProvider; import org.atricore.idbus.kernel.main.mediation.provider.IdentityProvider; import org.atricore.idbus.kernel.main.mediation.select.SelectorChannel; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Selects an IdP based on user input (UserClaims). It will also keep track of the selected IdP using a mediation state * local variable (This is a browser session based state variable) * * @author: sgonzalez@atriocore.com * @date: 6/12/13 */ public class UserSelectedIdPEntitySelector extends AbstractEntitySelector { private static final Log logger = LogFactory.getLog(RequestedIdPEntitySelector.class); @Override public boolean canHandle(EntitySelectionContext ctx) { return true; } public CircleOfTrustMemberDescriptor selectCotMember(EntitySelectionContext ctx, SelectorChannel channel) throws SSOException { CircleOfTrustMemberDescriptor idp = (CircleOfTrustMemberDescriptor) ctx.getMediationState().getLocalVariable("urn:org:atricore:idbus:capabilities:sso:select:usr:cotMember"); if (idp != null) { if (logger.isDebugEnabled()) { logger.debug("Using previously selected COT member : " + idp); return idp; } } // Try previous COT member { String idpAliasValue = ctx.getSelectionState().getPreviousCotMember(); if (idpAliasValue != null) { if (logger.isDebugEnabled()) logger.debug("Using IdP alias " + idpAliasValue); // Support both encoded and decoded IDP alias values idp = ctx.getCotManager().lookupMemberByAlias(idpAliasValue); if (idp == null) { String decodedIdpAlias = new String(Base64.decodeBase64(idpAliasValue.getBytes())); idp = ctx.getCotManager().lookupMemberByAlias(decodedIdpAlias); } } } // Try with selected IDP alias first { UserClaim idpAlias = ctx.getUserClaim(SELECTED_IDP_ALIAS_ATTR); if (idpAlias != null) { String idpAliasValue = (String) idpAlias.getValue(); if (logger.isDebugEnabled()) logger.debug("Using IdP alias " + idpAlias.getValue()); // Support both encoded and decoded IDP alias values idp = ctx.getCotManager().lookupMemberByAlias(idpAliasValue); if (idp == null) { String decodedIdpAlias = new String(Base64.decodeBase64(idpAliasValue.getBytes())); idp = ctx.getCotManager().lookupMemberByAlias(decodedIdpAlias); } } } // Now try with selected IDP ID { UserClaim idpId = (UserClaim) ctx.getUserClaim(SELECTED_IDP_ID_ATTR); if (idpId != null && idp == null) { String idpIdName = (String) idpId.getValue(); if (logger.isDebugEnabled()) logger.debug("Using IdP ID " + idpId); idp = ctx.getCotManager().lookupMemberById(idpIdName); if (idp == null) { String decodedIdpId = new String(Base64.decodeBase64(idpIdName.getBytes())); idp = ctx.getCotManager().lookupMemberById(decodedIdpId); } } } UserClaim rememberSelection = ctx.getUserClaim(REMEMBER_IDP_ATTR); if (rememberSelection != null && idp != null) { if (logger.isDebugEnabled()) logger.debug("Storing selected COT member " + idp.getAlias()); ctx.getMediationState().setLocalVariable("urn:org:atricore:idbus:capabilities:sso:select:usr:cotMember", idp); } else { if (logger.isDebugEnabled()) logger.debug("Clearing selected COT member (if any)"); ctx.getMediationState().removeLocalVariable("urn:org:atricore:idbus:capabilities:sso:select:usr:cotMember"); } return idp; } @Override public List<EndpointDescriptor> getUserClaimsEndpoints(EntitySelectionContext ctx, SelectorChannel channel) { if (ctx.getMediationState().getLocalVariable("urn:org:atricore:idbus:capabilities:sso:select:usr:cotMember") != null) return Collections.EMPTY_LIST; CircleOfTrustManager cotMgr = channel.getProvider().getCotManager(); String applianceName = channel.getProvider().getUnitContainer().getName(); SSOEntitySelectorMediator mediator = (SSOEntitySelectorMediator) channel.getIdentityMediator(); List<EndpointDescriptor> endpoints = new ArrayList<EndpointDescriptor>(); // We need to build a URL like: http://<host>:<port>/IDBUS-UI/<appliance>/SSO/IDPS String location = mediator.getDashboardUrl() + "/IDPS"; EndpointDescriptor ed = new EndpointDescriptorImpl( "SelectUserClaimsEndpoint", "UserClaimsRequest", SSOBinding.SSO_ARTIFACT.toString(), location, null); endpoints.add(ed); if (endpoints.size() > 0) return endpoints; return null; } }