Kleber Mota
Kleber Mota

Reputation: 9065

sec:authorize returning true for both isAuthenticated() and isAnonymous() in thymeleaf view

In my current spring-boot project, I have in my view a snippet of code like this in my thymeleaf view:

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

where only one of the snippets 1 or 2 should be displayed in the same time. But right now, when I open this view in the browser, the two areas are being displayed.

Anyone can see what's wrong here?

ps.: my thymeleaf configuration class is this:

@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.: my spring-security configuration class is that:

@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();
        }
}

Upvotes: 6

Views: 15119

Answers (5)

bpgriner
bpgriner

Reputation: 391

My fix was to add thymeleaf-extras-springsecurity4 to my web app dependencies.

I had a parent pom that was importing spring boot (1.4.1.RELEASE), which includes the thymeleaf extras, but my child pom (which houses the web app code) needed to call out the specific thymeleaf extras dependency like so:

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

And voilà ... it now works.

I was attempting to do:

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

in a thymeleaf template (.html file) to only show that div and it's contents when a user was logged in. However, it was showing that div all the time.

I wish it would have thrown an error saying it couldn't recognize the spring security tag prior to including the thymeleaf extras dependency ... it would have made debugging much easier.

Upvotes: 12

sam
sam

Reputation: 2004

Tried all the above methods but didn't work for me, however it might have worked for others. What worked for me is below:

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

Here is my configuration settings for 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;
}

Upvotes: 0

Mert Doe
Mert Doe

Reputation: 578

In my case changing

spring.jpa.hibernate.ddl-auto=auto

to

spring.jpa.hibernate.ddl-auto=none

in application.properties file was the solution.

Upvotes: -4

Bankole Hussein Salako
Bankole Hussein Salako

Reputation: 334

This could be as a result the thymeleaf-extras-springsecurity4 artifact being missing on your classpath. I was having this issue and discovered that (after pulling most of my hair out) the SpringSecurity dialect was not loaded for thymeleaf because the of the jar's absence. Added this dependency by:

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

Hope this helps. See https://stackoverflow.com/a/31622977/4091838

Upvotes: 3

JavaGuy
JavaGuy

Reputation: 21

In your configuration, you have set all URLs to have anonymous access

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

try this

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

Due to the permitAll(), all the urls are accessible by anonymous users, and also to authenticated users, so both are being shown. Try switch case to avoid such pitfalls.

Upvotes: -1

Related Questions