3

他の認証メカニズムに加えて、Spring Security saml をアプリケーションにかなり標準的に実装しています。既定の SAML は構成されませんが、フォームから構成できるため、既定では SAML を無効にする必要があります。SAML のオン/オフを簡単に切り替えられるようにしたいのですが、これを行う最善の方法がわかりません。

1 つのアプローチは、saml が有効かどうかを確認し、有効な場合は samlFilter チェーンを無視するカスタム FilterChainProxy を実行し ( Spring Security のデフォルト フィルター スタックから 1 つのフィルターを削除する方法は? )、同様の実装を行うことのようです。メタデータ ジェネレーター フィルター。

どんなアドバイスも素晴らしいでしょう。

これが私の設定です:

<http auto-config="false" use-expressions="true"
      access-decision-manager-ref="webAccessDecisionManager"
      disable-url-rewriting="false"
      create-session="never"
      authentication-manager-ref="authenticationManager">

    <custom-filter before="FIRST" ref="metadataGeneratorFilter"/>
    <custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter"/>
</http>

メタデータ ジェネレーター フィルター:

<beans:bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
    <beans:constructor-arg>
        <beans:bean class="org.springframework.security.saml.metadata.MetadataGenerator">
            <beans:property name="entityId" value="${saml.entityId}"/>
            <beans:property name="signMetadata" value="${saml.signMetadata}"/>
        </beans:bean>
    </beans:constructor-arg>
</beans:bean>

サム フィルター:

<beans:bean id="samlFilter" class="org.springframework.security.web.FilterChainProxy">
    <filter-chain-map request-matcher="ant">
        <filter-chain pattern="/saml/login/**" filters="samlEntryPoint"/>
        <filter-chain pattern="/saml/logout/**" filters="samlLogoutFilter"/>
        <filter-chain pattern="/saml/metadata/**" filters="metadataDisplayFilter"/>
        <filter-chain pattern="/saml/SSO/**" filters="samlWebSSOProcessingFilter"/>
        <filter-chain pattern="/saml/SSOHoK/**" filters="samlWebSSOHoKProcessingFilter"/>
        <filter-chain pattern="/saml/SingleLogout/**" filters="samlLogoutProcessingFilter"/>
        <filter-chain pattern="/saml/discovery/**" filters="samlIDPDiscovery"/>
    </filter-chain-map>
</beans:bean>

編集:これが私の実装です。これは少しハックであり、非推奨の方法に依存していますが、機能します

以下のスニペットは、MetadataGeneratorFilter を無効にします。

public class MyMetadataGeneratorFilter extends MetadataGeneratorFilter {

    private boolean isActive = false;

    public MyMetadataGeneratorFilter(MetadataGenerator generator) {
        super(generator);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (isActive) {
            processMetadataInitialization((HttpServletRequest) request);
        }
        chain.doFilter(request, response);
    }

    public void setActive(boolean active) {
        isActive = active;
    }
}

autowired である samlFilter / FilterChainMap もあります。saml が有効になっている場合は、このチェーンをそのままにしておきます。無効になっている場合は、saml を有効または無効にするサービスの空のマップにチェーンを設定します。

初期化時に、filterchainmap 値を取得します。

private Map<RequestMatcher, List<Filter>> map;

@Override
public void init() throws ServiceException, MetadataProviderException {

    SamlConfig samlConfig = getConfig();
    map = samlFilter.getFilterChainMap();

    applySamlConfig(samlConfig);

}

以下のメソッドでは、フィルター チェーン マップを、Spring xml で提供される元のマップ (有効な場合) または空のマップ (無効な場合) に設定します。

public void applySamlConfig(SamlConfig samlConfig) throws ServiceException, MetadataProviderException {


    if (!samlConfig.isEnabled()) {
        Map<RequestMatcher, List<Filter>> emptyMap = samlFilter.getFilterChainMap();
        emptyMap.clear();
        samlFilter.setFilterChainMap(emptyMap);
        return;
    }

    samlFilter.setFilterChainMap(map);
4

3 に答える 3

2

entry-point-ref 定義にカスタム フィルターを追加しました。機能が有効になっていない場合、このフィルターは次のすべてのフィルターをスキップします。

<security:http entry-point-ref="samlEntryPoint">
  <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
  <!-- This filter checks if the SSO-Feature is enabled - otherwise all following security filters will be skipped -->
  <security:custom-filter before="BASIC_AUTH_FILTER" ref="ssoEnabledFilter"/>
  <security:custom-filter before="FIRST" ref="metadataGeneratorFilter" />
  <security:custom-filter after="BASIC_AUTH_FILTER" ref="samlFilter" />

ssoEnabledFilter:

    public class SsoEnabledFilter extends GenericFilterBean {

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain) throws IOException, ServletException {
        boolean ssoEnabled = isSsoEnabled();

        if (ssoEnabled) {
            filterChain.doFilter(request, response);
        } else {
            request.getRequestDispatcher(((HttpServletRequest) request).getServletPath()).forward(request, response);
        }
      }
   }
于 2015-06-24T13:11:56.130 に答える
1

編集:TheTurkishによって通知されたエラーを修正

実行中のアプリケーションで SAML の使用を切り替えられるようにしたい場合は、samlFilter のラッパーを使用する方が簡単です。例えば

public class FilterWrapper extends GenericFilterBean {

    private Filter inner;
    private boolean active;
    private boolean targetFilterLifeCycle = false;


    public Filter getInner() {
        return inner;
    }

    public void setInner(Filter inner) {
        this.inner = inner;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    @Override
    public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws IOException, ServletException {
        if (active) {
            inner.doFilter(sr, sr1, fc);
        }
        else {
            fc.doFilter(str,sr1);
        }
    }

    @Override
    protected void initFilterBean() throws ServletException {
        super.initFilterBean();
        if (inner == null) {
            throw new ServletException("Inner cannot be null");
        }
        if (targetFilterLifeCycle) {
            inner.init(getFilterConfig());
        }
    }

    @Override
    public void destroy() {
        super.destroy();
        if (inner != null && targetFilterLifeCycle) {
            inner.destroy();
        }
    }
}

そのように使用できます:

<bean id="samlFilter" class="...FilterWrapper" p:active="false">
    <property name=inner>
        <!-- the real samlFilter bean -->
        <bean class="org.springframework.security.web.FilterChainProxy">
        ...
        </bean>
    </property>
</bean>

これは Bean であるため、Saml をアクティブ化/非アクティブ化する場所に注入し、単純に呼び出します。

samlFilter.setActive(active);
于 2014-08-07T15:19:44.960 に答える
1

これまでのところ、バックエンド構成に基づいて特定の Bean を含めるかスキップするカスタム Spring 名前空間を使用してこれを実装し、バックエンド構成が変更された場合に Spring コンテキストをリロードしてきました。

于 2014-08-07T12:47:33.623 に答える