Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring SAML extension for multiple IDP'S

we are planning to use spring saml extension as SP into our application. But the requirement with our application is we need to communicate with more than 1 IDP's Could any one please provide me/direct me to the example where it uses multiple IDP's

I also would like to know spring saml extension supports what kind of IDPS like OPenAM/Ping federate/ADFs2.0 etc...

Thanks, --Vikas

like image 700
Vikas Shivashankara Avatar asked Sep 24 '14 07:09

Vikas Shivashankara


1 Answers

You need to have a class to maintain a list of metadatas of each Idp's - say you putting those metadatas in some list which will be shared across application by static method. I have something like below NOTE- I am not copying all class as it is that I am having, so might came across minor issues which you should be able to resolve on your own,

public class SSOMetadataProvider {
  public static List<MetadataProvider> metadataList() throws MetadataProviderException, XMLParserException, IOException, Exception {            
            logger.info("Starting : Loading Metadata Data for all SSO enabled companies...");
            List<MetadataProvider> metadataList = new ArrayList<MetadataProvider>();
            org.opensaml.xml.parse.StaticBasicParserPool parserPool = new org.opensaml.xml.parse.StaticBasicParserPool();
            parserPool.initialize();

            //Get XML from DB -> convertIntoInputStream -> pass below as const argument
            InputStreamMetadataProvider inputStreamMetadata = null;
            try {
        //Getting list from DB
                List companyList = someServiceClass.getAllSSOEnabledCompanyDTO();

                if(companyList!=null){
                    for (Object obj : companyList) {
                        CompanyDTO companyDTO = (CompanyDTO) obj;
                        if (companyDTO != null && companyDTO.getCompanyid() > 0 && companyDTO.getSsoSettingsDTO()!=null && !StringUtil.isNullOrEmpty(companyDTO.getSsoSettingsDTO().getSsoMetadataXml())) {
                            logger.info("Loading Metadata for Company : "+companyDTO.getCompanyname()+" , companyId : "+companyDTO.getCompanyid());

                            inputStreamMetadata = new InputStreamMetadataProvider(companyDTO.getSsoSettingsDTO().getSsoMetadataXml());
                            inputStreamMetadata.setParserPool(parserPool);
                            inputStreamMetadata.initialize();


                            //ExtendedMetadataDelegateWrapper extMetadaDel = new ExtendedMetadataDelegateWrapper(inputStreamMetadata , new org.springframework.security.saml.metadata.ExtendedMetadata());

                            SSOMetadataDelegate extMetadaDel = new SSOMetadataDelegate(inputStreamMetadata , new org.springframework.security.saml.metadata.ExtendedMetadata()) ;

                            extMetadaDel.initialize();
                            extMetadaDel.setTrustFiltersInitialized(true);
                            metadataList.add(extMetadaDel);

                            logger.info("Loading Metadata bla bla");


                        }
                    }
                }

            } catch (MetadataProviderException | IOException | XMLParserException  mpe){

                logger.warn(mpe);
                throw mpe;
            }
            catch (Exception e) {
                logger.warn(e);
            }

            logger.info("Finished : Loading Metadata Data for all SSO enabled companies...");

            return metadataList;
        }

InputStreamMetadataProvider.java

 public class InputStreamMetadataProvider extends AbstractReloadingMetadataProvider implements Serializable
    {
    public InputStreamMetadataProvider(String metadata) throws MetadataProviderException 
        {
            super();
            //metadataInputStream = metadata;
            metadataInputStream = SSOUtil.getIdpAsStream(metadata);

        }
@Override
    protected byte[] fetchMetadata() throws MetadataProviderException
    {
        byte[] metadataBytes = metadataInputStream ;

        if(metadataBytes.length>0)  
                return metadataBytes;
        else 
            return null;
    }
public byte[] getMetadataInputStream() {
    return metadataInputStream;
}
}

SSOUtil.java

public class SSOUtil {

    public static byte[] getIdpAsStream(String metadatXml) {


            return metadatXml.getBytes();


        }

}

After user request to fetch metadata for their company's metadata, get MetaData for entityId for each IdPs - SSOCachingMetadataManager.java

public class SSOCachingMetadataManager extends CachingMetadataManager{

 @Override
    public ExtendedMetadata getExtendedMetadata(String entityID) throws MetadataProviderException {
        ExtendedMetadata extendedMetadata = null;

        try {


            //UAT Defect Fix - org.springframework.security.saml.metadata.ExtendedMetadataDelegate cannot be cast to biz.bsite.direct.spring.app.sso.ExtendedMetadataDelegate
            //List<MetadataProvider> metadataList =  (List<MetadataProvider>) GenericCache.getInstance().getCachedObject("ssoMetadataList", List.class.getClassLoader());

            List<MetadataProvider> metadataList = SSOMetadataProvider.metadataList();

            log.info("Retrieved Metadata List from Cassendra Cache size is :"+ (metadataList!=null ? metadataList.size(): 0) );

            org.opensaml.xml.parse.StaticBasicParserPool parserPool = new org.opensaml.xml.parse.StaticBasicParserPool();
            parserPool.initialize();

            if(metadataList!=null){



                //metadataList.addAll(getAvailableProviders());
                //metadataList.addAll(getProviders());

                //To remove duplicate entries from list, if any
                Set<MetadataProvider> hs = new HashSet<MetadataProvider> ();
                hs.addAll(metadataList);

                metadataList.clear();
                metadataList.addAll(hs);
                //setAllProviders(metadataList);
                //setTrustFilterInitializedToTrue();
                //refreshMetadata();

            }


            if(metadataList!=null && metadataList.size()>0) {

                for(MetadataProvider metadataProvider :  metadataList){


                        log.info("metadataProvider instance of ExtendedMetadataDelegate: Looking for entityId"+entityID);

                        SSOMetadataDelegate ssoMetadataDelegate = null;                     
                        ExtendedMetadataDelegateWrapper extMetadaDel = null;

//                      extMetadaDel.getDelegate()
                        if(metadataProvider instanceof SSOMetadataDelegate)
                            {ssoMetadataDelegate = (SSOMetadataDelegate) metadataProvider;

                                ((InputStreamMetadataProvider)ssoMetadataDelegate.getDelegate()).setParserPool(parserPool);
                                ((InputStreamMetadataProvider)ssoMetadataDelegate.getDelegate()).initialize();
                                ssoMetadataDelegate.initialize();

                                ssoMetadataDelegate.setTrustFiltersInitialized(true);

                                if(!isMetadataAlreadyExist(ssoMetadataDelegate))
                                    addMetadataProvider(ssoMetadataDelegate);   

                                extMetadaDel = new ExtendedMetadataDelegateWrapper(ssoMetadataDelegate.getDelegate() , new org.springframework.security.saml.metadata.ExtendedMetadata());
                            }
                        else 
                            extMetadaDel = new ExtendedMetadataDelegateWrapper(metadataProvider, new org.springframework.security.saml.metadata.ExtendedMetadata());


                        extMetadaDel.initialize();
                        extMetadaDel.setTrustFiltersInitialized(true);

                        extMetadaDel.initialize();

                        refreshMetadata();

                        extendedMetadata = extMetadaDel.getExtendedMetadata(entityID);

                }
        }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if(extendedMetadata!=null)
            return extendedMetadata;  
        else{
            return super.getExtendedMetadata(entityID);                          
        }
    }



    private boolean isMetadataAlreadyExist(SSOMetadataDelegate ssoMetadataDelegate) {

        boolean isExist = false;
            for(ExtendedMetadataDelegate item :  getAvailableProviders()){

                    if (item.getDelegate() != null && item.getDelegate() instanceof SSOMetadataDelegate) {  

                        SSOMetadataDelegate that = (SSOMetadataDelegate) item.getDelegate();
                        try {

                            log.info("This Entity ID: "+ssoMetadataDelegate.getMetadata()!=null ?  ((EntityDescriptorImpl)ssoMetadataDelegate.getMetadata()).getEntityID() : "nullEntity"+

                                    "That Entity ID: "+that.getMetadata()!=null ?  ((EntityDescriptorImpl)that.getMetadata()).getEntityID() : "nullEntity");

                            EntityDescriptorImpl e = (EntityDescriptorImpl) that.getMetadata();

                        isExist = this.getMetadata()!=null ?  ((EntityDescriptorImpl)ssoMetadataDelegate.getMetadata()).getEntityID().equals(e.getEntityID()) : false;

                            if(isExist)
                                return isExist;
                        } catch (MetadataProviderException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }

              }

            }
            return isExist;

    }

Add entry in ur Spring bean xml

<bean id="metadata" class="pkg.path.SSOCachingMetadataManager">
        <constructor-arg name="providers" value="#{ssoMetadataProvider.metadataList()}">
        </constructor-arg>
        <property name="RefreshCheckInterval" value="-1"/>
        <property name="RefreshRequired" value="false"/>
</bean>

Let me know incase of any concerns.

like image 162
Yogesh Jadhav Avatar answered Oct 13 '22 01:10

Yogesh Jadhav