在Spring Security中缺少ROLE_ANONYMOUS

时间:2012-09-10 20:19:19

标签: java spring-security

我已经使用Spring Security 2.x一段时间了,但最近我切换到3.x.我总是使用自己的UserDetails接口实现和对DB的身份验证。

一切正常(登录,注销,网址过滤,查看授权用户的用户名等)。

唯一要做的就是在未授权用户时显示“请登录”消息。我尝试了几种方法:

<sec:authorize access="not isAnonymous()">
or
<sec:authorize access="hasRole('ROLE_ANONYMOUS')">
etc.

他们都没有奏效。最后,我将<sec:authentication property="principal.authorities" />添加到我的主页输出中,以调试用户真正拥有的角色。这就是我所看到的:

  • 已记录的用户 - [ROLE_USER, ROLE_ADMIN]
  • Unathorized user - ``&lt; - empty String

如果我没记错的话,看起来我以某种方式失去了默认的ROLE_ANONYMOUS权限,它总是被Spring添加。那是最近掉了还是什么?也许我必须以其他方式处理这种匿名访问?

安全背景的相关部分:

<beans:beans
        xmlns="http://www.springframework.org/schema/security"
        xmlns:beans="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <!-- UNPROTECTED RESOURCES -->
    <http pattern="/" security="none"/>
    <http pattern="/favicon.ico" security="none"/>
    <http pattern="/home" security="none"/>
    <http pattern="/login*" security="none"/>
    <http pattern="/resources/**" security="none"/>

    <!-- PROTECTED RESOURCES -->
    <http auto-config='true' use-expressions="true">
        <intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
        <intercept-url pattern="/admin/**" access="hasRole('ROLE_USER,ROLE_ADMIN')"/>
        <form-login login-page="/login" default-target-url="/dashboard" authentication-failure-url="/login?login_error=true"/>
        <logout logout-url="/logout"/>
    </http>

    <beans:bean id="userAccountsAuthenticationProvider" class="pl.xxx.utils.UserAccountsAuthenticationProvider" />

    <beans:bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
        <beans:property name="userPropertyToUse" value="salt" />
    </beans:bean>

    <authentication-manager>
        <authentication-provider user-service-ref="userAccountsAuthenticationProvider">
            <password-encoder ref="standardPasswordEncoder"/>
        </authentication-provider>
    </authentication-manager>
</beans:beans>

1 个答案:

答案 0 :(得分:3)

可以通过几种不同的方式配置匿名身份验证 - 您是使用<http auto-config="true"><anonymous>标记还是自定义bean作为自定义过滤器?如果您发布了security-context.xml,那将会更容易。

无论如何,你想要显示“请登录”,所以我认为你真的想要

<sec:authorize access="isAnonymous()">Please login</sec:authorize>

没有“not”(顺便说一下,如果“not”是此上下文中表达式的有效部分,我无法找到)。

另一种方法是使用isAuthenticated()代替,在EL中否定它并查看它是否适用于您的情况:

<sec:authorize access="isAuthenticated()" var="isAuthenticated" />
<c:if test="${not isAuthenticated}">
  <!-- do stuff -->
</c:if>

修改

security="none"更改为access="IS_AUTHENTICATED_ANONYMOUSLY"并将所选模式移至intercept-url。它应该启用Spring Security的过滤器链并根据请求应用AnonymousAuthenticationFilter

<!-- UNPROTECTED RESOURCES -->
<http pattern="/favicon.ico" security="none"/>
<http pattern="/resources/**" security="none"/>

<!-- PROTECTED RESOURCES -->
<http auto-config='true' use-expressions="true">
    <intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/home" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/login*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
    <intercept-url pattern="/admin/**" access="hasRole('ROLE_USER,ROLE_ADMIN')"/>
    <form-login login-page="/login" default-target-url="/dashboard" authentication-failure-url="/login?login_error=true"/>
    <logout logout-url="/logout"/>
</http>

假设您要在isAnonymous()//home中使用/login*

我之前的解决方案有效,因为security="none"检查isAuthenticated() 总是产生错误,所以否定它就像检查没有被记录一样。