繁体   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