web-dev-qa-db-ja.com

Spring Securityで「anonymousUser」が認証されるのはなぜですか?

これが私のメインコントローラーです。

_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";
    }
}
_

ログインしていなくても、auth.isAuthenticated()は常にtrueを返します。何故ですか?そして、auth.isAuthenticated()はいつfalseを返しますか?認証されたユーザーの名前は、ログインしていない場合はanonymousUser、ログインしている場合はユーザー名です。

編集

これは私の_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>
_

また、次の行が_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>
_

Tomcat 8.0とすべての最新の依存関係をMaven経由で使用しています。

36
Ariel

これは、デフォルトでspring-securityが機能する方法です。

ドキュメント から:

「匿名で認証された」ユーザーと認証されていないユーザーとの間に実際の概念上の違いはないことに注意してください。 Spring Securityの匿名認証は、アクセス制御属性を設定するためのより便利な方法を提供するだけです。たとえば、getCallerPrincipalなどのサーブレットAPI呼び出しは、SecurityContextHolderに匿名認証オブジェクトが実際に存在していても、nullを返します。

監査インターセプターがSecurityContextHolderを照会して、どのプリンシパルが特定の操作を担当したかを識別する場合など、匿名認証が役立つ状況が他にもあります。 SecurityContextHolderが常にAuthenticationオブジェクトを含み、決してnullでないことを知っている場合、クラスをより堅牢に作成できます。

anonymousUserかどうかを確認する必要がある場合は、AuthenticationオブジェクトがAnonymousAuthenticationTokenインスタンスであるかどうかを確認できます。

40
Aleksandr M