// find eligible local IDPs for the tenant private List<String> getEligibleLocalIdpList(AuthnRequestState t) { Validate.notNull(t); IdmAccessor accessor = t.getIdmAccessor(); List<String> localIDPs = new ArrayList<String>( Arrays.asList(accessor.getIdpEntityId(), accessor.getDefaultIdpEntityId())); List<String> eligibleLocalIDPs = new ArrayList<>(); IDPList idpList = t.getAuthnRequest().getScoping() == null ? null : t.getAuthnRequest().getScoping().getIDPList(); if (idpList != null && idpList.getIDPEntrys() != null) { for (IDPEntry entry : idpList.getIDPEntrys()) { if (entry != null && localIDPs.contains(entry.getProviderID())) { eligibleLocalIDPs.add(entry.getProviderID()); } } if (eligibleLocalIDPs.isEmpty()) { log.debug("samlp:Scoping:IDPList does not contain VMWare local Identity Store."); } } else { eligibleLocalIDPs = localIDPs; } return eligibleLocalIDPs; }
/** * Builds an IdP List out of the idpEntityNames * * @param idpEntityNames The IdPs Entity IDs to include in the IdP List, no list is created when * null * @param serviceURI The binding service for an IdP for a specific binding. Should be null if * there is more than one IdP in the list or if the destination IdP is not known in advance. * @return an IdP List or null when idpEntityNames is null */ protected IDPList buildIDPList(Set<String> idpEntityNames, SingleSignOnService serviceURI) { if (idpEntityNames == null) { return null; } SAMLObjectBuilder<IDPEntry> idpEntryBuilder = (SAMLObjectBuilder<IDPEntry>) builderFactory.getBuilder(IDPEntry.DEFAULT_ELEMENT_NAME); SAMLObjectBuilder<IDPList> idpListBuilder = (SAMLObjectBuilder<IDPList>) builderFactory.getBuilder(IDPList.DEFAULT_ELEMENT_NAME); IDPList idpList = idpListBuilder.buildObject(); for (String entityID : idpEntityNames) { IDPEntry idpEntry = idpEntryBuilder.buildObject(); idpEntry.setProviderID(entityID); idpList.getIDPEntrys().add(idpEntry); // The service URI would be null if the SP does not know in advance // to which IdP the request is sent to. if (serviceURI != null) { idpEntry.setLoc(serviceURI.getLocation()); } } return idpList; }
// check if the provided IDPList contains a trusted external IDP // return the list of valid ones private List<String> findValidExternalIdpListWithinScoping( List<IDPEntry> requestIdpList, IdmAccessor accessor) { Validate.notNull(requestIdpList); Validate.notNull(accessor); List<String> retVal = new ArrayList<>(); Collection<IDPConfig> extIdps = accessor.getExternalIdps(); if (extIdps == null || extIdps.isEmpty()) { log.debug("No external IDP registered! "); } else { for (IDPEntry entry : requestIdpList) { if (entry != null) { IDPConfig foundConfig = accessor.getExternalIdpConfigForTenant(accessor.getTenant(), entry.getProviderID()); if (foundConfig != null) { retVal.add(entry.getProviderID()); } } } } log.debug("check if IDPList contain a trusted external IDP, result: {}", !retVal.isEmpty()); return retVal; }
/** * Return a SOAP Envelope Body that contains the Response the IdP sent, if there is one. * * <p>Returns null if the IdP returned no response at all. Nothing. * * @return */ private Body getResponseBody( ExchangeContent spContent, IDPEntry idpEntry, PaosClient paosClient, ClientOptions options) { String spAssertionConsumerURL = ""; ExchangeContent idpContent = null; Envelope idpEnvelope = null; URL idpURL = null; // Extract idplist from authnrequest and check if the SP supports // the one that was chosen. If not, complain. idpURL = determineIdP(spContent.getResponseParts().getHeader(), idpEntry); spAssertionConsumerURL = ExtractField.extractAssertionConsumerURL(spContent.getResponseParts().getHeader()); // If no matching idp was found from the list the SP sent... if (idpURL == null) { logger.info("The SP did not indicate support for the chosen IdP."); idpURL = getURL(idpEntry.getLoc()); // Get an assertion from the IdP // and let the SP trust an // unknown IdP. } // Create the envelope with the AuthnRequest that will be sent to the // IdP idpEnvelope = EnvelopeCreator.createIdpEnvelope(spContent.getResponseParts()); // Get the Assertion from the IdP (send AuthnRequest to IdP) idpContent = getAssertion(paosClient, idpEnvelope, idpURL, options); // If the IdP sent back anything at all as a response: if (idpContent != null) { // Check assertionConsumerURL. If it does not match, send a SOAP // fault to the SP/endpoint if (consumerUrlsMatch(idpContent, spAssertionConsumerURL)) { return idpContent.getResponseParts().getBody(); } else { logger.debug("AssertionConsumerURLs from AuthnRequest and Response did not match."); logger.debug("Returning a SOAP fault message to the endpoint."); return EnvelopeCreator.createSoapFaultBody("AssertionConsumerURLs did not match."); } } // else the paosclient has complained about this. return null; }
/** * Extracts the forced IDP list from the session. * * @param session The authentication session. * @return The forced IDPs. * @throws OAException If organization storage exist check can't be performed. */ @SuppressWarnings("unchecked") private List<String> getForcedIDPs(ISession session) throws OAException { List<String> retval = new Vector<String>(); IUser oUser = session.getUser(); if (oUser instanceof SAMLRemoteUser) { SAMLRemoteUser remoteUser = (SAMLRemoteUser) oUser; String sRemoteIdP = remoteUser.getOrganization(); if (sRemoteIdP != null && _organizationStorage.exists(sRemoteIdP)) { StringBuffer sbDebug = new StringBuffer(); sbDebug.append("There is a Remote SAML User available in session with ID '"); sbDebug.append(session.getId()); sbDebug.append("' that is known at remote IdP '"); sbDebug.append(sRemoteIdP); sbDebug.append("' so this IdP will be forced"); _logger.debug(sbDebug.toString()); retval.add(sRemoteIdP); return retval; } } ISessionAttributes atts = session.getAttributes(); String sGetComplete = (String) atts.get(ProxyAttributes.class, ProxyAttributes.IDPLIST_GETCOMPLETE); if (sGetComplete != null) { _logger.debug( "Using proxy attribute: " + ProxyAttributes.IDPLIST_GETCOMPLETE + ": " + sGetComplete); // getcomplete IDPList idpList = null; try { if (_mRemoteIDPLists.containsKey(sGetComplete)) { idpList = _mRemoteIDPLists.get(sGetComplete).getList(); } else { RemoteIDPListEntry entry = new RemoteIDPListEntry(sGetComplete, 1000); idpList = entry.getList(); // DD Add the RemoteIDPListEntry to a map for caching purposes; The getEntry() retrieves // the list from the url. _mRemoteIDPLists.put(sGetComplete, entry); } if (idpList != null) { for (IDPEntry entry : idpList.getIDPEntrys()) { retval.add(entry.getProviderID()); } } } catch (ResourceException e) { _logger.warn("Failed retrieval of IDPList from GetComplete URL: " + sGetComplete, e); } } List<SAML2IDPEntry> idpList = (List<SAML2IDPEntry>) atts.get(ProxyAttributes.class, ProxyAttributes.IDPLIST); if (idpList != null) { if (_logger.isDebugEnabled()) { StringBuffer sbMessage = new StringBuffer("Using proxy attribute "); sbMessage.append(ProxyAttributes.IDPLIST); sbMessage.append(": ").append(idpList); _logger.debug(sbMessage); } for (SAML2IDPEntry entry : idpList) { // DD We currently ignore the proxied SAML2IDPEntry.getName() (friendlyname) and // SAML2IDPEntry.getLoc() String sID = entry.getProviderID(); if (sID != null) { if (!retval.contains(sID)) retval.add(sID); } } } Collection cForcedOrganizations = (Collection) atts.get( com.alfaariss.oa.util.session.ProxyAttributes.class, com.alfaariss.oa.util.session.ProxyAttributes.FORCED_ORGANIZATIONS); if (cForcedOrganizations != null) { if (_logger.isDebugEnabled()) { StringBuffer sbMessage = new StringBuffer("Using proxy attribute "); sbMessage.append(com.alfaariss.oa.util.session.ProxyAttributes.FORCED_ORGANIZATIONS); sbMessage.append(": ").append(cForcedOrganizations); _logger.debug(sbMessage); } for (Object oForceOrganization : cForcedOrganizations) { String sForceOrganization = (String) oForceOrganization; if (!retval.contains(sForceOrganization)) retval.add(sForceOrganization); } } return retval; }
/** * Read the list of supported IDPs that the SP sent and determine if the chosen IdP is supported. * Request = opensaml ECP request header. * * @param header * @return */ public URL determineIdP(Header header, IDPEntry idpEntry) { IDPList idpList = null; List<XMLObject> list = header.getUnknownXMLObjects(); for (XMLObject xmlObject : list) { if (xmlObject.getElementQName().equals(Request.DEFAULT_ELEMENT_NAME)) { idpList = ((Request) xmlObject).getIDPList(); } } // If the list from the SP contains the same entry that // was chosen by the client... if (idpList != null) { for (IDPEntry spIdpEntry : idpList.getIDPEntrys()) { if (spIdpEntry.getName() != null && spIdpEntry.getLoc() != null && idpEntry.getProviderID() != null) if (spIdpEntry.getName().equals(idpEntry.getName())) if (spIdpEntry.getLoc().equals(idpEntry.getLoc())) if (spIdpEntry.getProviderID().equals(idpEntry.getProviderID())) return getURL(spIdpEntry.getLoc()); } } return null; }