[SPRING] 다중 IDP를위한 스프링 SAML 확장
SPRING다중 IDP를위한 스프링 SAML 확장
우리는 응용 프로그램에 SP로 saml 확장을 사용할 계획입니다. 그러나 우리 신청서의 요구 사항은 1 개 이상의 IDP와 의사 소통을해야한다는 것입니다. 어느 한 사람이 나에게 IDP를 여러 개 사용하는 예를 들어 주시거나 직접 지시 해 주실 수 있습니까?
나는 또한 Spring saml extension이 OPENAM / Ping federate / ADFs2.0 등과 같은 어떤 종류의 IDPS를 지원하는지 알고 싶습니다.
감사, - 비 카스
해결법
-
==============================
1.당신의 질문에 대한 모든 대답은 Spring SAML 매뉴얼에서 찾을 수 있습니다.
당신의 질문에 대한 모든 대답은 Spring SAML 매뉴얼에서 찾을 수 있습니다.
제품의 일부로 포함 된 샘플 애플리케이션에는 두 개의 IDP에 대한 메타 데이터가 이미 포함되어 있으며이를 예제로 사용합니다.
IDP에 관한 진술은 1.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.나는 최근 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; }
from https://stackoverflow.com/questions/26010813/spring-saml-extension-for-multiple-idps by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 구성 요소 검사로 발견 된 Bean을 재정의하는 방법이 있습니까? (0) | 2019.04.30 |
---|---|
[SPRING] ArrayList를 org.springframework.batch.core.JobParameter에 캐스트 할 수 없습니다. (0) | 2019.04.30 |
[SPRING] Stateless 웹 애플리케이션 개발을 위해 Spring MVC 사용 (0) | 2019.04.30 |
[SPRING] 간단한 jdbc 호출을 사용하여 입력 매개 변수로 배열을 저장 프로 시저에 전달하십시오. (0) | 2019.04.30 |
[SPRING] Spring을 사용하여 동일한 클래스를 주입 할 수 있습니까? (0) | 2019.04.30 |