5

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

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

谢谢,--维卡斯

4

3 回答 3

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 的元数据 - 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>

如果有任何疑虑,请告诉我。

于 2017-06-29T04:05:09.677 回答
2

我最近为 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;
}
于 2018-08-17T11:19:11.150 回答
0

您可以在Spring SAML 手册中找到问题的所有答案。

作为产品一部分包含的示例应用程序已经包含两个 IDP 的元数据,以它为例。

关于国内流离失所者的声明包含在第 1.2 章中:

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

于 2014-09-24T08:47:54.983 回答