1
votes

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.

2
A solution for this problem is explained in: stackoverflow.com/questions/41388332/… - Jochen Marsaille

2 Answers

3
votes

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.

1
votes

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