복붙노트

[SPRING] 다중 IDP를위한 스프링 SAML 확장

SPRING

다중 IDP를위한 스프링 SAML 확장

우리는 응용 프로그램에 SP로 saml 확장을 사용할 계획입니다. 그러나 우리 신청서의 요구 사항은 1 개 이상의 IDP와 의사 소통을해야한다는 것입니다. 어느 한 사람이 나에게 IDP를 여러 개 사용하는 예를 들어 주시거나 직접 지시 해 주실 수 있습니까?

나는 또한 Spring saml extension이 OPENAM / Ping federate / ADFs2.0 등과 같은 어떤 종류의 IDPS를 지원하는지 알고 싶습니다.

감사, - 비 카스

해결법

  1. ==============================

    1.당신의 질문에 대한 모든 대답은 Spring SAML 매뉴얼에서 찾을 수 있습니다.

    당신의 질문에 대한 모든 대답은 Spring SAML 매뉴얼에서 찾을 수 있습니다.

    제품의 일부로 포함 된 샘플 애플리케이션에는 두 개의 IDP에 대한 메타 데이터가 이미 포함되어 있으며이를 예제로 사용합니다.

    IDP에 관한 진술은 1.2 장에 포함되어있다.

  2. ==============================

    2.각 Idp의 메타 데이터 목록을 유지 관리하는 클래스가 있어야합니다. 즉, 정적 인 방법으로 응용 프로그램간에 공유되는 일부 메타 데이터를 일부 목록에 추가한다고 가정 해보십시오. 나는 아래와 같은 것을 가지고있다. 참고 - 나는 모든 수업을 그대로 복사하고 있기 때문에, 스스로 해결할 수있는 사소한 문제가 발생할 수도 있습니다.

    각 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;
    
        }
    

    통해 UR 봄 콩 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>
    

    걱정거리가 있으면 알려주세요.

  3. ==============================

    3.나는 최근 Spring SAML 확장을위한 두 개의 IDP를 구성했다. 여기서 우리는 하나의 기본 규칙을 따라야합니다. 추가하려는 각 IDP에 대해 하나의 IDP 공급자와 하나의 SP 공급자를 구성해야합니다. 예를 들어 CachingMetadataManager와 같은 MetadataManager Bean에서 공급자를 구성해야합니다. 다음은 내가 말하고자하는 아이디어를 얻는 몇 가지 코드 단편입니다.

    나는 최근 Spring SAML 확장을위한 두 개의 IDP를 구성했다. 여기서 우리는 하나의 기본 규칙을 따라야합니다. 추가하려는 각 IDP에 대해 하나의 IDP 공급자와 하나의 SP 공급자를 구성해야합니다. 예를 들어 CachingMetadataManager와 같은 MetadataManager Bean에서 공급자를 구성해야합니다. 다음은 내가 말하고자하는 아이디어를 얻는 몇 가지 코드 단편입니다.

    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;
    }
    
  4. from https://stackoverflow.com/questions/26010813/spring-saml-extension-for-multiple-idps by cc-by-sa and MIT license