【问题标题】:sec:authorize returning true for both isAuthenticated() and isAnonymous() in thymeleaf viewsec:authorize 在 thymeleaf 视图中为 isAuthenticated() 和 isAnonymous() 返回 true
【发布时间】: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 应该自动配置它。

标签: spring spring-security thymeleaf


【解决方案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://stackoverflow.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 来避免此类陷阱。

        【讨论】:

          猜你喜欢
          • 2019-08-06
          • 2014-04-28
          • 2012-08-13
          • 2021-02-23
          • 2021-02-21
          • 2018-10-20
          • 1970-01-01
          • 2020-10-07
          相关资源
          最近更新 更多