为什么在 Spring Security 中对“anonymousUser”进行身份验证?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26101738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:05:56  来源:igfitidea点击:

Why is the 'anonymousUser' authenticated in Spring Security?

springjakarta-eeauthenticationspring-security

提问by Ariel

This is my main controller:

这是我的主要控制器:

package org.demian.demibox.controllers;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MainController {
    private String getUsername() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth.isAuthenticated())
            return auth.getName();
        else
            return null;
    }
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String showHome() {
        String username = getUsername();
        System.out.println(username);
        if (username == null || username.length() == 0)
            return "welcome";
        return "index";
    }
}

Even though I am not logged in, auth.isAuthenticated()always returns true. Why is that? And when would auth.isAuthenticated()return false? The name of the authenticated user is anonymousUserif I'm not logged in and username if I am logged in.

即使我没有登录,也auth.isAuthenticated()总是返回true. 这是为什么?什么时候会auth.isAuthenticated()返回 false?anonymousUser如果我没有登录,则经过身份验证的用户的名称是,如果我已登录,则为用户名。

EDIT

编辑

This is my security-context.xmlfile:

这是我的security-context.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"
    xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <security:authentication-manager>
        <security:authentication-provider>
            <security:jdbc-user-service data-source-ref="dataSource" id="jdbcUserService" />
            <!-- <security:password-encoder ref="passwordEncoder" /> -->
        </security:authentication-provider>
    </security:authentication-manager>
    <security:http use-expressions="true">
        <security:intercept-url pattern="/" access="permitAll" />
        <security:intercept-url pattern="/login" access="permitAll" />
        <security:intercept-url pattern="/redeem" access="permitAll" />
        <security:intercept-url pattern="/redeem_code" access="permitAll" />
        <security:intercept-url pattern="/static/**" access="permitAll" />
        <security:intercept-url pattern="/*" access="isAuthenticated()" />
        <security:intercept-url pattern="/**" access="isAuthenticated()" />
        <security:intercept-url pattern="/**" access="denyAll" />
        <security:form-login login-page="/login" authentication-failure-url="/login?error=true" />
        <security:logout logout-success-url="/" />
        <security:remember-me key="offersAppKey" user-service-ref="jdbcUserService" />
    </security:http>
    <security:global-method-security secured-annotations="enabled" />
    <!-- <bean id="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder" /> -->
</beans>

And the following lines are in the web.xmlfile:

以下几行在web.xml文件中:

<filter>
    <display-name>springSecurityFilterChain</display-name>
    <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>

I am using Tomcat 8.0 and all the latest dependencies via Maven.

我通过 Maven 使用 Tomcat 8.0 和所有最新的依赖项。

回答by Aleksandr M

This is how spring-security works by default.

这就是 spring-security 默认的工作方式。

From the docs:

文档

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 SecurityContextHolderto identify which principal was responsible for a given operation. Classes can be authored more robustly if they know the SecurityContextHolderalways contains an Authenticationobject, and never null.

请注意,“经过匿名身份验证”的用户和未经身份验证的用户之间没有真正的概念差异。Spring Security 的匿名身份验证只是为您提供了一种更方便的方式来配置您的访问控制属性。getCallerPrincipal例如,对 servlet API 调用的调用仍将返回 null,即使SecurityContextHolder.

在其他情况下,匿名身份验证很有用,例如当审计拦截器查询SecurityContextHolder以识别哪个主体负责给定操作时。如果类知道SecurityContextHolder总是包含一个Authentication对象,并且从不为空,则可以更健壮地编写类。

If you need to check if it is an anonymousUserthen you can check whether Authenticationobject is AnonymousAuthenticationTokeninstance or not.

如果您需要检查它是否是一个,anonymousUser那么您可以检查Authentication对象是否是AnonymousAuthenticationToken实例。