sec:authorize 在 thymeleaf 视图中为 isAuthenticated() 和 isAnonymous() 返回 true

Posted

技术标签:

【中文标题】sec:authorize 在 thymeleaf 视图中为 isAuthenticated() 和 isAnonymous() 返回 true【英文标题】:sec:authorize returning true for both isAuthenticated() and isAnonymous() in thymeleaf view 【发布时间】:2015-12-30 12:39:39 【问题描述】:

在我当前的 spring-boot 项目中,我的 thymeleaf 视图中有这样的 sn-p 代码:

<div class="account">
    <ul>
        <li id="your-account" sec:authorize="isAnonymous()">
            ... code 1 ...
        </li>
        <li id="your-account" sec:authorize="isAuthenticated()">
            ... code 2 ...
        </li>
        <li th:if="$cart">
            ...
        </li>
    </ul>
</div>

其中只有一个 sn-ps 1 或 2 应同时显示。但是现在,当我在浏览器中打开这个视图时,两个区域都被显示出来了。

任何人都可以看到这里出了什么问题?

ps.:我的thymeleaf配置类是这样的:

@Configuration
public class Thymeleaf 

  @Bean
  public SpringTemplateEngine templateEngine() 
    SpringTemplateEngine engine  =  new SpringTemplateEngine();

    final Set<IDialect> dialects = new HashSet<IDialect>();
    dialects.add( new SpringSecurityDialect() );
    engine.setDialects( dialects );

    return engine;
  


ps.:我的 spring-security 配置类是这样的:

@Configuration
@ComponentScan(value="com.spring.loja")
@EnableGlobalMethodSecurity(prePostEnabled=true)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 
        @Autowired
        private UserDetailsService userDetailsService;

        @Autowired
        private SocialUserDetailsService socialUserDetailsService;

        @Autowired
        private PasswordEncoder passwordEncoder;

        @Autowired
      private AuthenticationManagerBuilder auth;

        @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .csrf()
                .disable()
            .authorizeRequests()
                .antMatchers("/b3/**", "/v1.1/**", "/**", "/destaque/**", "/categoria/**").permitAll()
                .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/signin")
                    .loginProcessingUrl("/login").permitAll()
                    .usernameParameter("login")
                    .passwordParameter("senha")
                    .and()
                .logout()
                    .logoutUrl("/logout")
                    .logoutSuccessUrl("/")
                    .and()
                .apply(new SpringSocialConfigurer());
    

        @Override
        public void configure(WebSecurity web) throws Exception 
            DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
        handler.setPermissionEvaluator(new CustomPermissionEvaluator());
        web.expressionHandler(handler);
    

        @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder);
    

        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception 
            return auth.getOrBuild();
        

【问题讨论】:

是的,我试过了。但不要工作,因为我使用的是来自包 thymeleaf-extras-springsecurity3 的标签,而不是来自 spring-security-taglibs 的标签 thymeleaf-extras-springsecurity3 提供的任何其他功能是否有效? &lt;div th:text="$#authentication.name" /&gt; 显示什么?我认为您不需要 templateEngine bean,spring boot 应该自动配置它。 【参考方案1】:

我的解决方法是将thymeleaf-extras-springsecurity4 添加到我的网络应用依赖项中。

我有一个父 pom 正在导入 spring boot (1.4.1.RELEASE),其中包括 thymeleaf extras,但我的子 pom(其中包含 Web 应用程序代码)需要像这样调用特定的 thymeleaf extras 依赖项:

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

瞧……它现在可以工作了。

我试图这样做:

<div sec:authorize="hasRole('ROLE_USER')"></div>

在 thymeleaf 模板(.html 文件)中仅在用户登录时显示该 div 及其内容。但是,它一直显示该 div。

我希望它会在包含 thymeleaf extras 依赖项之前抛出一个错误,说它无法识别 spring 安全标签......它会使调试变得更加容易。

【讨论】:

如果您查看功能损坏的源代码,您会注意到 sec: 标签只是简单地按原样发送到客户端而没有被服务器评估(这就是 div 一直显示的原因)。我在相同的修复程序中遇到了同样的问题 - 很难追踪,因为大多数代码示例只包含 HTML 并且没有提及依赖项要求。 如果您使用“hasRole('ROLE_USER')”,这最终会要求 ROLE_ROLE_USER,因为 hasRole() 会自动将 ROLE_ 添加到相关角色的前面。 hasAuthority("ROLE_USER") 如果您想将 ROLE_ 保留在那里【参考方案2】:

尝试了上述所有方法,但对我不起作用,但它可能对其他人有用。对我有用的是:

<properties>
    <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
    <thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

这是我对 thymeleaf 的配置设置:

@Bean
public SpringTemplateEngine templateEngine() 
    SpringTemplateEngine templateEngine = new SpringTemplateEngine();
    templateEngine.setTemplateResolver(thymeleafTemplateResolver());
    templateEngine.setEnableSpringELCompiler(true);
    templateEngine.addDialect(new SpringSecurityDialect());
    return templateEngine;


@Bean
public SpringResourceTemplateResolver thymeleafTemplateResolver() 
    SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
    templateResolver.setPrefix("classpath:templates/");
    templateResolver.setSuffix(".html");
    templateResolver.setCacheable(false);
    templateResolver.setTemplateMode(TemplateMode.HTML);
    return templateResolver;


@Bean
public ThymeleafViewResolver thymeleafViewResolver() 
    ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
    viewResolver.setTemplateEngine(templateEngine());
    viewResolver.setCharacterEncoding("UTF-8");
    return viewResolver;

【讨论】:

【参考方案3】:

在我的情况下改变

spring.jpa.hibernate.ddl-auto=auto

spring.jpa.hibernate.ddl-auto=none

application.properties 文件中是解决方案。

【讨论】:

【参考方案4】:

这可能是因为您的类路径中缺少 thymeleaf-extras-springsecurity4 工件。我遇到了这个问题,发现(在拔掉我的大部分头发之后)SpringSecurity 方言没有为百里香加载,因为没有罐子。通过以下方式添加此依赖项:

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

希望这会有所帮助。见https://***.com/a/31622977/4091838

【讨论】:

【参考方案5】:

在您的配置中,您已将所有 URL 设置为具有匿名访问权限

.antMatchers("/b3/**", "/v1.1/**", "/**", "/destaque/**", "/categoria/**").permitAll()

试试这个

.antMatchers("/b3/**", "/v1.1/**", "/**", "/destaque/**", "/categoria/**")
    .anyRequest().authenticated()
                .and()

由于 permitAll(),匿名用户和经过身份验证的用户都可以访问所有 url,因此两者都被显示。尝试使用 switch case 来避免此类陷阱。

【讨论】:

以上是关于sec:authorize 在 thymeleaf 视图中为 isAuthenticated() 和 isAnonymous() 返回 true的主要内容,如果未能解决你的问题,请参考以下文章

sec:authorize 在 thymeleaf 视图中为 isAuthenticated() 和 isAnonymous() 返回 true

sec:authorize 在 thymeleaf 视图中为 isAuthenticated() 和 isAnonymous() 返回 true

sec:authorize 在 Spring 启动应用程序中使用 Thymeleaf 时未按预期工作

thymeleaf.extras.springsecurity4 sec:authorize 不起作用

Spring Security - Thymeleaf - 我可以在 sec:authorize 标签中评估 SPEL 表达式吗?

Spring Security Role Hierarchy 不适用于 Thymeleaf sec:authorize