Spring SecurityContext 返回空认证

Spring SecurityContext returning null authentication

我正在使用 Spring 安全性进行用户身份验证,但当用户未登录时,SecurityContext 为空。

在我的 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>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

在我的security.xml我有

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:http="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd">

    <!-- Static resources such as CSS and JS files are ignored by Spring Security -->
    <security:http pattern="/resources/**" security="none" />

    <security:http use-expressions="true">
        <!-- Enables Spring Security CSRF protection -->
        <security:csrf/>
        <!-- Configures the form login -->
        <security:form-login
                login-page="/login"
                login-processing-url="/login/authenticate"
                authentication-failure-url="/login?error=bad_credentials"
                username-parameter="username"
                password-parameter="password"/>
        <!-- Configures the logout function -->
        <security:logout
                logout-url="/logout"
                logout-success-url="/home"
                delete-cookies="JESSIONID"/>

        <security:intercept-url pattern="/**" method="GET" access="permitAll"/>
        <security:intercept-url pattern="/user/register" method="POST" access="permitAll"/>

        <!-- These operations are protected. -->
        <security:intercept-url pattern="/product/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
        <security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
        <security:access-denied-handler error-page="/login"/>

        <!-- Adds social authentication filter to the Spring Security filter chain. -->
        <security:custom-filter ref="socialAuthenticationFilter" before="PRE_AUTH_FILTER" />
    </security:http>

...其他配置...

我得到 null 的代码是:

HttpSession session = request.getSession(true);
SecurityContext securityContext =(SecurityContext) session.getAttribute("SPRING_SECURITY_CONTEXT");
Authentication authentication = securityContext.getAuthentication();
user = (Object) authentication.getPrincipal();

但是当没有用户登录时,我得到的 securityContext 为空。任何我做错的地方的帮助

来自http://docs.spring.io/spring-security/site/docs/3.0.x/reference/anonymous.html

...Note that there is no real conceptual difference between a user who is “anonymously authenticated” and an unauthenticated user. Spring Security's anonymous authentication just gives you a more convenient way to configure your access-control attributes. Calls to servlet API calls such as getCallerPrincipal, for example, will still return null even though there is actually an anonymous authentication object in the SecurityContextHolder.

There are other situations where anonymous authentication is useful, such as when an auditing interceptor queries the SecurityContextHolder to identify which principal was responsible for a given operation. Classes can be authored more robustly if they know the SecurityContextHolder always contains an Authentication object, and never null.

所以这样的设置(也来自引用的页面):

<bean id="anonymousAuthFilter"
  class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
  <property name="key" value="foobar"/>
  <property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
</bean>
<bean id="anonymousAuthenticationProvider"
  class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
  <property name="key" value="foobar"/>
</bean>

..并调整您的 security.xml 条目来自:

permitAll

..至:

ROLE_ANONYMOUS

应该始终为您提供一个 Securitycontext/Authentication 对象(但不一定是“主体”)。