The sec:authorize-url Tag does not work with Spring boot security by default:
git clone https://github.com/spring-projects/spring-boot
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?
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...
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.
using thymeleaf-extras-springsecurity4 should solve the problem
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With