I am seeing everywhere in the documentation the following shape for authorization rules:
http.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/resources/**", "/signup", "/about").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().denyAll()
);
but I did a test and the shape
http.authorizeRequests().requestMatchers().anyRequest().authenticated()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().denyAll()
looks functionally equivalent (correct me if Im wrong) and it is much more readable
Is there any reason why the lambda one is preferred? I don't see a noticeable gain from the lazy-evaluation and it is much more readable, and still type safe. If there is any reason why this shape is discouraged would be nice to have it documented
Thanks!!
Comment From: rwinch
I'll start with readability is certain subjective, but it is the team's belief that lambdas are more readable. We've seen how the community uses non-lambda configuration and it is often misconfigured. This is especially true as you add more configuration. Consider the following:
http
.formLogin().and()
.securityMatchers().requestMatchers("/admin/**").and()
.authorizeHttpRequests().requestMatchers().anyRequest().authenticated()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().denyAll();
It can be confusing what methods are operating on what object. The configuration above configures form login, then it configures all of HttpSecurity to only work with URLs that start with /admin (none of this security would impact a URL of /foo). Then it maps all URLs that start with /admin/ to require the role ADMIN and all other URLs (which is no URLs) to denyAll.
The lambda ensures it is obvious what context the DSL is operating in:
http
.formLogin(withDefaults())
.securityMatchers(security -> security
.requestMatchers("/admin/**")
)
.authorizeHttpRequests(exchange -> exchange
.requestMatchers("/resources/**", "/signup", "/about").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().denyAll()
)
.formLogin();
Comment From: nightswimmings
That explains why I intuitively self-adopted the convention to always use the syntax:
``` http.formLogin(withDefaults()) http.securityMatchers().requestMatchers("/admin/") http.authorizeHttpRequests().requestMatchers("/resources/", "/signup", "/about").permitAll() .requestMatchers("/admin/**").hasRole("ADMIN") .anyRequest().denyAll() http.formLogin() ````
it totally makes sense the lambda syntax with this in mind, if you avoid the http. call every time