[SPRING] 봄 SAML - 읽기 및 실행시 상쾌한 IdP가 메타 데이터
SPRING봄 SAML - 읽기 및 실행시 상쾌한 IdP가 메타 데이터
나는 봄 - SAML 확장자 WSO2과 SSOCircle을 사용하고 있습니다. 우리는이 시점에서 구성을 테스트하는 우리의 ApplicationContext 내에서 2 개 IdP가의 2 SP의를 정의했습니다. 그래서, 현재, 우리는 우리의 스프링의 XML 설정 내에서이 개 정적으로 정의 IdP 구성의이이 노력하고 있습니다. 테스트 목적을 위해 우리는 IdP가 메타 데이터가 우리의 WAR 아카이브의 내부에 내장되도록 CachingMetadataManager 및 ResourceBackedMetadataProvider의 조합을 사용하고 있습니다. 견본:
<bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager">
<constructor-arg>
<list>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
<constructor-arg>
<bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider">
<constructor-arg>
<bean class="java.util.Timer"/>
</constructor-arg>
<constructor-arg>
<bean class="org.opensaml.util.resource.ClasspathResource">
<constructor-arg value="/metadata/wso2idp_metadata.xml"/>
</bean>
</constructor-arg>
<property name="parserPool" ref="parserPool"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
</bean>
</constructor-arg>
</bean>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
<constructor-arg>
<bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider">
<constructor-arg>
<bean class="java.util.Timer"/>
</constructor-arg>
<constructor-arg>
<bean class="org.opensaml.util.resource.ClasspathResource">
<constructor-arg value="/metadata/ssocircleidp_metadata.xml"/>
</bean>
</constructor-arg>
<property name="parserPool" ref="parserPool"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
</bean>
</constructor-arg>
</bean>
</list>
</constructor-arg>
생산을 위해, 우리는 (중앙에 위치) 데이터베이스에 우리의 IdP가 메타 데이터를 저장할 수 있어야합니다. 나는 WAR을 다시 배포 또는 서버 (들)을 다시 시작하지 않고 메타 데이터를 추가, 제거 및 수정할 수 있어야합니다. 처음에 나는이 CachingMetadataManager을 무시하고 동적으로 모든 메타 데이터 공급자를로드 할 수있는 noarg 생성자를 정의 할 수 있다고 생각하지만, CachingMetadataManager 만 MetadataProvider 목록에 취해야 하나의 생성자를 정의하기 때문에이 불가능합니다. 나는 다음을 수행 결국 :
<bean id="metadataList" class="org.arbfile.util.security.saml.DBMetadataProviderList">
<constructor-arg ref="parserPool" />
<constructor-arg>
<bean class="java.util.Timer"/>
</constructor-arg>
</bean>
<bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager">
<constructor-arg ref="metadataList" />
</bean>
콩 metadataList은 간단하게 정의 할 수 있습니다 :
public final class DBMetadataProviderList extends ArrayList<MetadataProvider>
{
private final static Logger log = LoggerFactory.getLogger(DBMetadataProviderList.class);
private ParserPool parser;
public DBMetadataProviderList(ParserPool _parser, Timer _timer) throws MetadataProviderException
{
this.parser = _parser;
// Lookup metadata from DB
}
}
이 날은 동적으로 IdP가 메타 데이터에 읽을 수 없습니다. 그것이 비록 새로 고침 할 때 내 논리는 아래로 떨어진다. 그러나 나는 그것이 3 ~ 4 세이며, 봄 포럼에서 해당 게시물을 발견했다. 동적 IdP가 메타 데이터, 캐시를 추가하고, 읽고 업데이트하는 가장 좋은 방법은 무엇입니까 그것은 어떤 간격으로 캐시 새로 고침이? DB를 테이블에 내 경우 1 행에 하나의 IdP가 메타 데이터 정의에 달합니다.
해결법
-
==============================
1.여러 게시물을 읽고 소스 코드를 스캔 후, 나는이 질문에 대한 대답은 내가 생각했던 것보다 더 복잡하다 발견했다. 해결하기 위해 정말 3 개 가지 시나리오가 있습니다.
여러 게시물을 읽고 소스 코드를 스캔 후, 나는이 질문에 대한 대답은 내가 생각했던 것보다 더 복잡하다 발견했다. 해결하기 위해 정말 3 개 가지 시나리오가 있습니다.
나는 한 번에이 하나의 각에 걸릴 수 있습니다. 항목 1 : 아마 신속하고 더러운 솔루션으로이 문제를 해결하지만, 검토 (내 영업 이익)이 DBMetadataProviderList 클래스를 위의 방법에는 여러 가지가 있습니다. 여기에 더 완전한 생성자 코드는 다음과 같습니다
//This constructor allows us to read in metadata stored in a database. public DBMetadataProviderList(ParserPool _parser, Timer _timer) throws MetadataProviderException { this.parser = _parser; List<String> metadataProviderIds = getUniqueEntityIdListFromDB(); for (final String mdprovId : metadataProviderIds) { DBMetadataProvider metadataProvider = new DBMetadataProvider(_timer, mdprovId); metadataProvider.setParserPool(this.parser); metadataProvider.setMaxRefreshDelay(480000); // 8 mins (set low for testing) metadataProvider.setMinRefreshDelay(120000); // 2 mins ExtendedMetadataDelegate md = new ExtendedMetadataDelegate(metadataProvider, new ExtendedMetadata()); add(md); } }
2 번 항목을 해결하기 위해 나는 가이드로 FilesystemMetadataProvider을 사용하고 DBMetadataProvider 클래스를 만들었습니다. AbstractReloadingMetadataProvider 클래스를 확장하고 우리가 내장되어 opensaml 감사는 상쾌한 캐시 fetchMetadata () 메소드를 구현함으로써. 아래는 중요한 부분 (예를 들어, 코드에만 해당)입니다 :
public class DBMetadataProvider extends AbstractReloadingMetadataProvider { private String metaDataEntityId; // unique Id for DB lookups /** * Constructor. * @param entityId the entity Id of the metadata. Use as key to identify a database row. */ public DBMetadataProvider(String entityId) { super(); setMetaDataEntityId(entityId); } /** * Constructor. * @param backgroundTaskTimer timer used to refresh metadata in the background * @param entityId the entity Id of the metadata. Use as key to identify a database row. */ public DBMetadataProvider(Timer backgroundTaskTimer, String entityId) { super(backgroundTaskTimer); setMetaDataEntityId(entityId); } public String getMetaDataEntityId() { return metaDataEntityId; } public void setMetaDataEntityId(String metaDataEntityId){ this.metaDataEntityId = metaDataEntityId; } @Override protected String getMetadataIdentifier() { return getMetaDataEntityId(); } // This example code simply does straight JDBC @Override protected byte[] fetchMetadata() throws MetadataProviderException { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = JDBCUtility.getConnection(); ps = conn.prepareStatement("select bla bla bla ENTITY_ID = ?"); ps.setString(1, getMetaDataEntityId()); rs = ps.executeQuery(); if (rs.next()) { // include a modified date column in schema so that we know if row has changed Timestamp sqldt = rs.getTimestamp("MOD_DATE"); // use TimeStamp here to get full datetime DateTime metadataUpdateTime = new DateTime(sqldt.getTime(), ISOChronology.getInstanceUTC()); if (getLastRefresh() == null || getLastUpdate() == null || metadataUpdateTime.isAfter(getLastRefresh())) { log.info("Reading IdP metadata from database with entityId = " + getMetaDataEntityId()); Clob clob = rs.getClob("XML_IDP_METADATA"); return clob2Bytes(clob); } return null; } else { // row was not found throw new MetadataProviderException("Metadata with entityId = '" + getMetaDataEntityId() + "' does not exist"); } } catch (Exception e) { String msg = "Unable to query metadata from database with entityId = " + getMetaDataEntityId(); log.error(msg, e); throw new MetadataProviderException(msg, e); } finally { // clean up connections } } }
이 자원은 나를 캐시 다시로드 메타 데이터 프로 바이더 클래스에 맞는 기술을 회복했습니다. 마지막으로, 항목 # 3이 게시물을 구현하여 해결할 수 있습니다.
from https://stackoverflow.com/questions/42906985/spring-saml-reading-and-refreshing-idp-metadata-at-runtime by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 어떻게 WebSocket을을 사용하여 MySQL의에서 라이브 알림 업데이트를 얻으려면? (0) | 2019.10.03 |
---|---|
[SPRING] ContextRefreshedEvent 봄에 발사 될 때? (0) | 2019.10.03 |
[SPRING] 어떻게 봄 부팅 응용 프로그램에서 활성 구성을 기록하는? (0) | 2019.10.03 |
[SPRING] 봄 부팅 및 스프링 데이터 JPA와 인터셉터 또는 수신기를 최대 절전 모드 (0) | 2019.10.03 |
[SPRING] 무엇 여러 필드에 대한 findBy를 사용하는 스프링 데이터 JPA 방법이며, 또한 모든 필드에 포함하는 절을 사용 (0) | 2019.10.03 |