web-dev-qa-db-fra.com

Pourquoi «l'utilisateur anonyme» est-il authentifié dans Spring Security?

Ceci est mon contrôleur principal:

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

Même si je ne suis pas connecté, auth.isAuthenticated() renvoie toujours true. Pourquoi donc? Et quand auth.isAuthenticated() retournerait false? Le nom de l'utilisateur authentifié est anonymousUser si je ne suis pas connecté et nom d'utilisateur si je suis connecté.

MODIFIER

Voici mon fichier 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>

Et les lignes suivantes sont dans le fichier 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>

J'utilise Tomcat 8.0 et toutes les dernières dépendances via Maven.

36
Ariel

C'est ainsi que Spring-Security fonctionne par défaut.

De les docs :

Notez qu'il n'y a pas de réelle différence conceptuelle entre un utilisateur "authentifié anonymement" et un utilisateur non authentifié. L'authentification anonyme de Spring Security vous offre simplement un moyen plus pratique de configurer vos attributs de contrôle d'accès. Les appels aux appels d'API de servlet tels que getCallerPrincipal, par exemple, renverront toujours null même s'il existe en fait un objet d'authentification anonyme dans le SecurityContextHolder.

Il existe d'autres situations où l'authentification anonyme est utile, comme lorsqu'un intercepteur d'audit interroge le SecurityContextHolder pour identifier le principal responsable d'une opération donnée. Les classes peuvent être créées de manière plus robuste si elles savent que SecurityContextHolder contient toujours un objet Authentication, et jamais null.

Si vous devez vérifier s'il s'agit d'un anonymousUser, vous pouvez vérifier si l'objet Authentication est une instance de AnonymousAuthenticationToken ou non.

40
Aleksandr M