Sec: authorize и sec: аннотации проверки подлинности не работают

У меня есть проект Spring + Thymeleaf со следующим кодом вида.

    <!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>

Атрибуты sec: authorize и sec: authentication не работают должным образом - всегда отображается div, даже если ни один пользователь не вошел в систему, а диапазон всегда читает "miquel".

Выполняет соответствующий фрагмент из моего класса контроллера.

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

            return "home"; 
    } 

Оператор println работает как ожидалось - если ни один пользователь не вошел в систему, он печатает "anonymousUser", иначе имя пользователя.

Что я делаю неправильно?

Ответы

Ответ 1

После сравнения моего приложения с демонстрационным приложением Thymeleaf и Spring Security я обнаружил источник ошибки.

По-видимому, для того, чтобы Тимелеаф обработал атрибуты sec:authorize и sec:authentication, вам необходимо зарегистрировать SpringSecurityDialect в качестве дополнительного диалекта механизма шаблона bean.

<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>

Это удивительно, поскольку об этом факте нет на связанной странице документации Thymeleaf. Надеюсь, это поможет другим, которые будут сталкиваться с тем же вопросом в будущем.

Ответ 2

В Spring Загрузка Мне просто пришлось добавить следующую зависимость:

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

Ответ 3

Для версии java config она тоже работала для меня, добавив диагноз безопасности spring:

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

Ответ 4

Кроме того, вы можете очистить кеш шаблона после события аутентификации, чтобы ваш шаблон был повторно обработан с помощью новых данных аутентификации. Или установите шаблоны, которые чувствительны к сеансу входа в систему, не кэшированные (это то, что я сделал), используя ServletContextTemplateResolver.setNonCacheablePatterns().