适用于多个IDP的Spring SAML扩展程序

时间:2014-09-24 07:16:49

标签: spring saml federated-identity spring-saml

我们计划在我们的应用程序中使用spring saml扩展作为SP。 但是我们的应用要求是我们需要与超过1个IDP进行通信 任何人都可以提供给我/导演我使用多个IDP的例子

我也想知道spring saml扩展支持什么样的IDPS,如OPenAM / Ping federate / ADFs2.0等...

谢谢, --Vikas

3 个答案:

答案 0 :(得分:3)

您需要有一个类来维护每个Idp的元数据列表 - 比如说将这些元数据放在某些列表中,这些列表将通过静态方法在应用程序之间共享。我有类似下面的东西 注意 - 我不是因为我正在复制所有课程,所以可能会遇到一些你应该能够自己解决的小问题,

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();


        }

}

在用户请求获取其公司元数据的元数据后,为每个IdP获取entityId的MetaData - 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;

    }

在你的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>

让我知道任何疑虑。

答案 1 :(得分:0)

您可以在Spring SAML manual

中找到问题的所有答案

作为产品一部分的示例应用程序已包含metadata for two IDPs,请以此为例。

关于国内流离失所者的声明载于第1.2章:

  

在身份提供商模式下支持SAML 2.0的所有产品(例如ADFS   2.0,Shibboleth,OpenAM / OpenSSO,Efecte Identity或Ping Federate)可以与扩展名一起使用。

答案 2 :(得分:0)

我最近为Spring SAML扩展配置了两个IDP。在这里,我们应该遵循一个基本规则。对于我们要添加的每个IDP,我们必须配置一个IDP提供程序以及一个SP提供程序。我们应该在MetadataManager bean中配置提供程序,例如CachingMetadataManager。以下是一些代码片段,可让我了解我要说的内容:

public void addProvider(String providerMetadataUrl, String idpEntityId, String spEntityId, String alias) {
    addIDPMetadata(providerMetadataUrl, idpEntityId, alias);
    addSPMetadata(spEntityId, alias);
}

public void addIDPMetadata(String providerMetadataUrl, String idpEntityId, String alias) {
    try {           
        if (metadata.getIDPEntityNames().contains(idpEntityId)) {
            return;
        }
        metadata.addMetadataProvider(extendedMetadataProvider(providerMetadataUrl, alias));
    } catch (MetadataProviderException e1) {
        log.error("Error initializing metadata", e1);
    }
}

public void addSPMetadata(String spEntityId, String alias) {
    try {
        if (metadata.getSPEntityNames().contains(spEntityId)) {
            return;
        }           
        MetadataGenerator generator = new MetadataGenerator();
        generator.setEntityId(spEntityId);
        generator.setEntityBaseURL(baseURL);
        generator.setExtendedMetadata(extendedMetadata(alias));
        generator.setIncludeDiscoveryExtension(true);
        generator.setKeyManager(keyManager);

        EntityDescriptor descriptor = generator.generateMetadata();
        ExtendedMetadata extendedMetadata = generator.generateExtendedMetadata();
        MetadataMemoryProvider memoryProvider = new MetadataMemoryProvider(descriptor);
        memoryProvider.initialize();
        MetadataProvider metadataProvider = new ExtendedMetadataDelegate(memoryProvider, extendedMetadata);
        metadata.addMetadataProvider(metadataProvider);
        metadata.setHostedSPName(descriptor.getEntityID());
        metadata.refreshMetadata();
    } catch (MetadataProviderException e1) {
        log.error("Error initializing metadata", e1);
    }
}

public ExtendedMetadataDelegate extendedMetadataProvider(String providerMetadataUrl, String alias)
        throws MetadataProviderException {
    HTTPMetadataProvider provider = new HTTPMetadataProvider(this.bgTaskTimer, httpClient, providerMetadataUrl);
    provider.setParserPool(parserPool);
    ExtendedMetadataDelegate delegate = new ExtendedMetadataDelegate(provider, extendedMetadata(alias));
    delegate.setMetadataTrustCheck(true);
    delegate.setMetadataRequireSignature(false);
    return delegate;
}

private ExtendedMetadata extendedMetadata(String alias) {
    ExtendedMetadata exmeta = new ExtendedMetadata();
    exmeta.setIdpDiscoveryEnabled(true);
    exmeta.setSignMetadata(false);
    exmeta.setEcpEnabled(true);
    if (alias != null && alias.length() > 0) {
        exmeta.setAlias(alias);
    }

    return exmeta;
}