web-dev-qa-db-fra.com

sec: authorise et sec: authentification, les annotations ne doivent pas être

J'ai un projet Spring + Thymeleaf avec le code d'affichage suivant.

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring3-3.dtd">
<html
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:th="http://www.thymeleaf.org"
        xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">

<head>
    <title>Contacts</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<div id="content">
    <h1>Welcome to the site!</h1>
    <p th:if="${loginError}">Wrong user or password</p>
    <form th:action="@{/j_spring_security_check}" method="post">
        <label for="j_username">Email address</label>:
        <input type="text" id="j_username" name="j_username"/> <br/>
        <label for="j_password">Password</label>:
        <input type="password" id="j_password" name="j_password"/> <br/>
        <input type="submit" value="Log in"/>
    </form>
</div>

<div sec:authorize="isAuthenticated()">
    User: <span sec:authentication="name">miquel</span>
</div>
</body>
</html>

Les attributs sec: authorize et sec: authentication ne fonctionnent pas comme prévu: la div est toujours affichée, même si aucun utilisateur n'est connecté, et la plage lit toujours "miquel". 

Suit un extrait pertinent de ma classe de contrôleur. 

@RequestMapping(value = "/welcome.html") 
public String wellcome() { 
    Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 
    System.out.println("username: " + auth.getName()); 

    return "home"; 
}

L'instruction println fonctionne comme prévu - si aucun utilisateur n'est connecté, elle affiche "anonymousUser", sinon le nom d'utilisateur. 

Qu'est-ce que je fais mal?

17
Dušan Rychnovský

Après avoir comparé de près mon application à l’application de démonstration Thymeleaf & Spring Security, j’ai découvert la source de l’erreur.

Apparemment, pour que Thymeleaf puisse traiter les attributs sec:authorize et sec:authentication, vous devez enregistrer SpringSecurityDialect en tant que dialecte supplémentaire du bean du moteur de modèle.

<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />
    <property name="additionalDialects">
        <set>
            <bean class="org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect" />
        </set>
    </property>
</bean>

Ceci est surprenant car il n’ya aucune mention de ce fait sur la page de documentation sur Thymeleaf . J'espère que cela aidera d'autres personnes qui feront face au même problème à l'avenir.

21
Dušan Rychnovský

Dans Spring Boot, je devais simplement ajouter la dépendance suivante:

    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity4</artifactId>
    </dependency>
15
JanTheGun

Pour la version de configuration Java, cela a également fonctionné pour moi en ajoutant le dialecte de sécurité Spring:

 @Bean
public SpringTemplateEngine templateEngine() {
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setTemplateResolver(templateResolver());
    templateEngine.addDialect(new TilesDialect());
    templateEngine.addDialect(new SpringSecurityDialect());
    return templateEngine;
}
6
Mihaita Tinta

Vous pouvez également souhaiter effacer le cache du modèle après un événement d'authentification afin que votre modèle soit traité à nouveau avec de nouvelles données d'authentification. Ou définissez les modèles sensibles à une session de connexion sur non mis en cache (c'est ce que j'ai fait), à l'aide de ServletContextTemplateResolver.setNonCacheablePatterns().

0
Greg