Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot Security - Thymeleaf sec:authorize-url not working

The sec:authorize-url Tag does not work with Spring boot security by default:

git clone https://github.com/spring-projects/spring-boot

Project spring-boot-sample-web-method-security:

Add dependency

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity3</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>

Adapt the controller from the sample:

@RequestMapping("/")
public String home(Map<String, Object> model) {
model.put("message", "Hello World");
model.put("title", "Hello Home");
model.put("date", new Date());
return "home";
}

@RequestMapping("/admin/foo")
public String home2(Map<String, Object> model) {
    model.put("message", "Hello World");
    model.put("title", "Hello Home");
    model.put("date", new Date());
    return "home";
}

Add url matching to application security:

http.authorizeRequests().antMatchers("/login").permitAll()
    .antMatchers("/admin/**").hasRole("ADMIN")
...

Add testcode in home.html

<div sec:authorize="hasRole('ROLE_ADMIN')">
    has role admin
 </div>
 <div sec:authorize-url="/admin/foo">
    can see /admin
 </div>

When I start the app and login I will always see the "can see /admin" part no matter if I can actually access the url or not. The role evaluation itself works as expected, as does the url permission itself (I get a 403 when I try to access it with ROLE_USER).

If I add a dummy privilegeEvaluator to the web security configuration that simply returns false for every request, the div will disappear correctly.

Am I missing something here? Is this expected behaviour and what do I need to define to make authorize-url work that way it used to when configuring security with xml?

Update: Basic authentication

This issue is connected to Basic authentication and its AutoConfiguration in SpringBootWebSecurityConfiguration:

In SampleMethodSecurityApplication change the ApplicationSecurity order by replacing:

@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)

with

@Order(SecurityProperties.BASIC_AUTH_ORDER + 1)

and deactivate basic in spring boot application.properties

security.basic.enabled: false

Now the authorize-url tag will work as expected, but you have lost http basic AutoConfiguration of course.

Leaving security.basic.enabled: true and changing the order of the ApplicationSecurity to be higher than BASIC_AUTH_ORDER will leave you with Basic authentication instead of form login...

Update - PrivilegeEvaluator

I have found the following workaround. Simply register the security interceptor manually in your SecurityConfig:

@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(final WebSecurity web) throws Exception {
        final HttpSecurity http = getHttp();
        web.postBuildAction(new Runnable() {
            @Override
            public void run() {
                web.securityInterceptor(http.getSharedObject(FilterSecurityInterceptor.class));
            }
        });
    }

It allows you to use the recommended ACCESS_OVERRIDE_ORDER and http basic auto configuration. I have posted more details here Any explanation why this works is appreciated.

like image 651
phlebas Avatar asked Nov 10 '22 08:11

phlebas


1 Answers

using thymeleaf-extras-springsecurity4 should solve the problem

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
like image 101
cw24 Avatar answered Nov 15 '22 11:11

cw24