1

I am trying to get my web Application to work again with the new Spring Boot version 1.3.5, but the thymeleaf dialect does not seem to work any longer.

I added

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

to my .pom and even registered a bean in my security configuration:

@Bean
public SpringSecurityDialect springSecurityDialect(){
    SpringSecurityDialect dialect = new SpringSecurityDialect();
    return dialect;
}

(although I would assume spring boot would do that for me anyway). Wen using expressions like, e. g.

<li sec:authorize="hasRole('SITE_ADMIN') || hasRole('TENANT_ADMIN')">Admin 
</li>

the expression will not be rendered, as the role seems to be null although I can inject my custom User element into the controller:

@RequestMapping(value="/", method=RequestMethod.GET)
public String homePage(@AuthenticationPrincipal VZUser user, Model model){
    model.addAttribute("email", user.getEmail());
    return "home/index";
}

From debugging, I see the Principal object injected is not null, but the template does not seem to be able to parse the sec: objects. I deleted the xmlns namespace and reinserted it without effect. And the documentation on this feature is quite frankly appalling. Anything I miss?

Oh yeah. The same code (without the new dependency and with the namespace declaration in the xhtml template) worked in Spring Boot 1.3.2...

UPDATE

I think it has to do with the fact that I use a custom UserDetailsService. I have no problems with the in memory service. however, My custom User implementation just has the following:

@Override
public Collection<? extends GrantedAuthority> getAuthorities(){
  List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
  for(VZUserRoles role: roles){
    authorities.add(new SimpleGrantedAuthority(role.name()));
  }
  return authorities;
}

I define an elementary UserDetails Service and put it int the AuthenticationMAnagerBuilder. Authentication works fine, it just does not seem to get passed along to the view.

1

2 Answers 2

3

Indeed, you don't need to define the SpringSecurityDialect bean, it's done for you by the Spring Boot auto-configuration.

I don't see anything wrong in your example here and I've tried to reproduce the issue without success.

With the following dependencies:

     <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

A simple Controller:

@Controller
public class HomeController {

    @RequestMapping("/")
    public String home() {
        return "index";
    }
}

A custom security configuration:

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("brian").password("password").roles("USER");
    }

}

An index.html template:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
</head>
<body>
<h2>Thymleaf example</h2>
<p sec:authorize="hasRole('ROLE_USER')">
    Authenticated
</p>
<p th:text="${#authentication.principal.username}">the_username</p>
</body>
</html>

Everything works as expected.

Feel free to create an issue once you have a minimal repro project.

3
  • Thanks! I don't have any problems as long as I use the in Memory UserDetailsService. However, having stored my accounts in MongoDB, I need a custom Service (which works fine for authentication, btw).
    – thomi
    Commented Jun 24, 2016 at 9:31
  • then maybe the issue is with that custom service (not adhering to the Principal contract or not filling roles?), and not the Thymeleaf extension here... Commented Jun 24, 2016 at 12:58
  • Could be. I can use ${#authentication.principal.authorities}, however. So the Principal is there. Maybe I will just work around the problem for now. As I said. Prior to Spring Boot 1.3.5 there has been no issue with the same code.
    – thomi
    Commented Jun 25, 2016 at 6:13
1

I found a workaround, which supposingly has to do with the way Spring Security 4 handles roles.

sec:authorize="hasAuthority('SITE_ADMIN')"

works just fine

Not the answer you're looking for? Browse other questions tagged or ask your own question.