簡體   English   中英

Spring Security 3.1.4具有表單登錄名的多個http元素

[英]Spring security 3.1.4 multiple http elements with form-login's

我完全知道這個問題已經問過很多遍了,但是我還沒有偶然發現答案。 如果它在那里,我很抱歉,對此的鏈接將不勝感激。

當前的工作配置

以下是我當前正在使用的配置的摘要,該配置允許在沒有任何安全性的情況下訪問上述<http />元素塊,但是需要具有角色之一的經過身份驗證的用戶才能登錄。

<http pattern="/" security="none" disable-url-rewriting="true" />
<http pattern="/login" security="none" disable-url-rewriting="true" />
<http pattern="/cookieInfo" security="none" disable-url-rewriting="true" />
<http pattern="/error" security="none" disable-url-rewriting="true" />
<http pattern="/cookiesDisabled" security="none" disable-url-rewriting="true" />
<http pattern="/loginFailed" security="none" disable-url-rewriting="true" />
<http pattern="/static/**" security="none" disable-url-rewriting="true" />

<http access-decision-manager-ref="accessDecisionManager" disable-url-rewriting="true">
    <custom-filter before="FIRST" ref="cookiePresentFilter" />
    <intercept-url pattern="/**" access="ROLE_1,ROLE_2,ROLE_3" />
    <form-login login-page="/login" default-target-url='/loginSuccess' always-use-default-target='true' authentication-failure-url="/loginFailed" />
    <logout />
</http>

所需的,不起作用的配置

我想有一個特殊的部分,下面顯示為<http pattern="/foo/**" ... ,其中沒有強制使用的默認目標。 我希望在全部捕獲之前僅具有一個更具體的模式就足夠了,但是在所有情況下,它似乎都只使用最終的全部捕獲塊。 我已經嘗試將intercept-url pattern="/**"設為intercept-url pattern="/foo/**"也無濟於事。

有任何想法嗎?!

<http pattern="/" security="none" disable-url-rewriting="true" />
<http pattern="/login" security="none" disable-url-rewriting="true" />
<http pattern="/loginFailed" security="none" disable-url-rewriting="true" />
<http pattern="/static/**" security="none" disable-url-rewriting="true" />

<http pattern="/foo/**" access-decision-manager-ref="accessDecisionManager" disable-url-rewriting="true">
    <intercept-url pattern="/**" access="ROLE_1,ROLE_2,ROLE_3" />
    <form-login login-page="/login" authentication-failure-url="/loginFailed" />
    <logout />
</http>

<http access-decision-manager-ref="accessDecisionManager" disable-url-rewriting="true">
    <intercept-url pattern="/**" access="ROLE_1,ROLE_2,ROLE_3" />
    <form-login login-page="/login" default-target-url='/loginSuccess' always-use-default-target='true' authentication-failure-url="/loginFailed" />
    <logout />
</http>

為什么這不起作用

之所以不起作用,是因為發生了以下情況:

  • 如果您請求匹配/ foo / **的URL,則該頁面將緩存在RequestCache中 通過將請求緩存在HttpSession中來實現默認實現。
  • 然后,Spring Security會將您發送到/ login,其中可能包含張貼到/ j_spring_security_check的表格
  • 當用戶進行身份驗證時,請求為/ j_spring_security_check,並且與/ foo / **不匹配,因此由第二個元素進行身份驗證。 always-use-default-target="true"在驗證時應用,而不是在發送到登錄表單時應用。 由於身份驗證請求與/ foo / **不匹配,因此始終會將用戶發送到default-target-url

修復此設置

要解決此問題,您需要執行以下操作:

<http pattern="/foo/**" ...>
    <intercept-url pattern="/foo/login" access="ROLE_ANONYMOUS"/>
    <intercept-url pattern="/**" access="ROLE_1,ROLE_2,ROLE_3" />
    <form-login
        ... 
        default-target-url="/loginSuccess 
        login-page="/foo/login" 
        login-processing-url="/foo/authenticate" />
    ...
</http>

/富/登錄

<form method="post" action="<c:url value='/foo/authenticate'/>">
   ...
</form>

更改的重點:

  • 更新塊配置以發送到其他登錄頁面。 這允許提交與/ foo / **匹配的自定義URL
  • 確保自定義登錄頁面被授予匿名用戶訪問權限
  • 更新塊配置以在與/ foo / **匹配的URL上處理身份驗證,這確保了always-use-default-target="false"

更好的選擇

如果RequestCache為空,Spring Security會將用戶發送到default-target-url。 這意味着,如果RequestCache忽略了要發送到default-target-url的請求,則所有內容都將起作用。

對於您的示例,您可以執行以下操作:

<http access-decision-manager-ref="accessDecisionManager" disable-url-rewriting="true">
    <intercept-url pattern="/**" access="ROLE_1,ROLE_2,ROLE_3" />
    <form-login login-page="/login" default-target-url='/loginSuccess' always-use-default-target='true' authentication-failure-url="/loginFailed" />
    <logout />

    <request-cache ref="requestCache"/>
</http>

<bean:bean id="requestCache" class="org.springframework.security.web.savedrequest.HttpSessionRequestCache">
    <bean:property name="requestMatcher">
        <bean:bean class="org.springframework.security.web.util.RegexRequestMatcher">
            <bean:constructor-arg value="^(?!/foo/).+"/>
            <bean:constructor-arg><bean:null/></bean:constructor-arg>
            <bean:constructor-arg value="true"/>
        </bean:bean>
    </bean:property>
</bean:bean>

強調:

  • 僅使用main(不要使用/ foo / **塊)
  • 更新該塊以使用request-cache元素
  • 創建一個HttpSessionRequestCache實例,該實例僅保存應重定向到的請求。 換句話說,忽略應始終發送到default-target-url的請求。 示例配置將把與/ foo / **不匹配的任何請求發送到default-target-url。

將您的配置文件更改為以下內容:

<http access-decision-manager-ref="accessDecisionManager" disable-url-rewriting="true">
    <intercept-url pattern="/foo/**" access="permitAll" />
    <intercept-url pattern="/**" access="ROLE_1,ROLE_2,ROLE_3" />
    <form-login login-page="/login" default-target-url='/loginSuccess' always-use-default-target='true' authentication-failure-url="/loginFailed" />
    <logout />
</http>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM