7

バックグラウンド

こんにちは、 をSpring使用するプロジェクトがありますSpring security。定義することにより、セキュリティ フィルターを定義しました。

 <b:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">

filter-chain-map

そして、web.xml私たちはそうします

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

 <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

そしてそれはすべてうまくいきます:)。 次の次の行Spring sessionに従って接続redisするときdoc

<context:annotation-config />
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>

filter名前付きを作成しますspringSessionRepositoryFilter。したがって、基本的に私たちが行ったことは、すべてのカスタムで、そのフィルターを最初filter-chainのフィルターとして追加することです。すなわち:

<b:bean id="springSecurityFilterChain"   class="org.springframework.security.web.FilterChainProxy">
     <filter-chain-map request-matcher="ant">

           <filter-chain pattern="/api/someapieformobilelogin" filters="none" />  <!-- no filter on login -->
        <filter-chain pattern="/api/**"
            filters="springSessionRepositoryFilter, securityContextFilter,and some other spring security filter />

        <filter-chain pattern="/**"
            filters="springSessionRepositoryFilter, securityContextFilter,and some other spring security filter />

結果: アプリは正常に動作しているようで、と通信してmonitoringいることもredis-cli示されています。springredis

質問

springSessionRepositoryFilter中の使用filter-chainは大丈夫ですか?または、フィルタリングシステムを悪用しましたか?

ありがとう、

オーク

編集

Authenticate上記は、コードからユーザーに希望する場合には機能しないようです。

Authentication authentication = authenticationManager
                .authenticate(authenticationToken);
SecurityContext securityContext = SecurityContextHolder
                .getContext();
securityContext.setAuthentication(authentication);

失敗します。filter-chainたぶん、経由で実行するのに十分ではないからですorg.springframework.security.web.FilterChainProxy

filterのように実行するとどう思いますweb.xmlか?

<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

上記は強制的springSessionRepositoryFilterに前に実行さspringSecurityFilterChainれますが、この例org.springframework.web.filter.DelegatingFilterProxyでは 2 回呼び出されています。springSessionRepositoryFilterアウトフィルターの前にフィルターとして実行する他の方法はありspringSecurityFilterChainますか?

4

2 に答える 2

2

私のテストによると、 springSessionRepositoryFilter最初に実行する必要があります。これは、実装をspringSessionRepositoryFilter置き換えるという事実によるものです。これがファイルHttpSessionを使用した私のソリューションです。xml

redis-cache.xml

<context:annotation-config />
<bean
    class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" />

<bean
    class="org.springframework.security.web.session.HttpSessionEventPublisher" />

<!-- end of seesion managment configuration -->


<bean id="redisConnectionFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <property name="port" value="${app.redis.port}" />
    <property name="hostName" value="${app.redis.hostname}" />
    <property name="password" value="${app.redis.password}" />
    <property name="usePool" value="true" />
</bean>

Spring Session はまだ XML 名前空間のサポートを提供していないため (gh-104 を参照)、 と RedisHttpSessionConfiguration の組み合わせを使用します。これにより、Filter を実装する springSessionRepositoryFilter という名前の Spring Bean が作成されます。フィルターは、HttpSession 実装を Spring Session によってサポートされるように置き換える役割を果たします。この例では、Spring Session は Redis によって支えられています。 ソース

これで、名前がsession filter付けられspringSessionRepositoryFilterたので、実装を置き換えるため、最初のフィルターとして実行する必要がありますHttpSession

そのために、 の最初のフィルタとして宣言しweb.xmlます。フィルターとフィルターの注文チェックアウトの詳細については、ドキュメントを参照してください

web.xml

<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>


<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    /WEB-INF/redis-cache.xml
    </param-value>
</context-param>

 <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

最初に実行されるのはspringSessionRepositoryFilter. しかし、実際org.springframework.web.filter.DelegatingFilterProxyにはクラスが実行されており、Bean の名前でフィルターを探します。そのため、初期設定で作成された Bean を検索します。 参照

に関する余分な行redis-cache.xmlも重要です。そうしspring application contextないと、redis の設定を知ることができません

参照

于 2016-10-30T07:37:47.463 に答える
1

それはどうでもいい事です。Javadocから:

SessionRepositoryFilter は、HttpSession にアクセスするか、応答をコミットする可能性のあるフィルターの前に配置して、セッションがオーバーライドされ、適切に永続化されるようにする必要があります。

springSessionRepositoryFilter応答をコミットしたり にアクセスできるものの前に追加する限り、HttpSession問題ありません。Spring Security の場合、確実にしたい主なことはspringSessionRepositoryFilterSecurityContextPersistenceFilter. springSessionRepositoryFilterこれは、コンテナー内または Spring Security FilterChainProxy(つまり) 内に含めることで実行できます<filter-chain>

于 2015-09-09T05:58:41.013 に答える