As per spring docs it says:
Returns a Customizer that does not alter the input argument.
But what does this exactly mean?
For e.g. what is the result if I use it like this:
@EnableWebSecurity
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeHttpRequests((authz) -> authz.anyRequest().authenticated())
.httpBasic(withDefaults());
return http.build();
}
}
CodePudding user response:
According to java doc, we have
public HttpSecurity httpBasic(Customizer<HttpBasicConfigurer<HttpSecurity>> httpBasicCustomizer) throws Exception {
httpBasicCustomizer.customize((HttpBasicConfigurer)this.getOrApply(new HttpBasicConfigurer()));
return this;
}
The parameter is of type Customizer<HttpBasicConfigurer<HttpSecurity>>
which can be used as a lambda function to pass the changes that you want to be applied in the configurer that you provide to the httpBasic
method. This method also returns the built HttpSecurity
so the configurer is already applied, when the httpBasic(....)
method ends.
A relative to your example let's name it Example 1
httpSecurity.httpBasic(httpSecurityHttpBasicConfigurer -> {
httpSecurityHttpBasicConfigurer.realmName("My Realm");
httpSecurityHttpBasicConfigurer.authenticationEntryPoint(new YourAuthEntryClass());
})
.authorizeRequests().and().csrf().disable().authorizeHttpRequests((authz) -> authz.anyRequest().authenticated());
So the configurer is going to apply the realmName
and authenticationEntryPoint
to the httpSecurity
via the lambda function which you have provided.
In case you didn't want to make any modifications to the httpSecurity
inside the httpBasic
method you could as well have done the
httpSecurity.httpBasic(httpSecurityHttpBasicConfigurer -> {} )
.authorizeRequests().and().csrf().disable().authorizeHttpRequests((authz) -> authz.anyRequest().authenticated());
And Spring just to avoid writting this nonsese httpSecurityHttpBasicConfigurer -> {}
as parameter has also gave you this with static withDefaults
method in the functional interface Customizer
. Keep in mind that this Customizer
is just a generic Interface and will be used in other places as well not just here.
@FunctionalInterface public interface Customizer<T> { void customize(T t); static <T> Customizer<T> withDefaults() { return (t) -> { }; } }
So to avoid the
httpSecurity.httpBasic(httpSecurityHttpBasicConfigurer -> {} )....
you can as well write
httpSecurity.httpBasic(Customizer.withDefaults())....
meaning no configuration will be applied inside the httpBasic
method in the httpSecurity
object.
Keep in mind however, that you also have available another method from Java Docs
public HttpBasicConfigurer<HttpSecurity> httpBasic() throws Exception { return (HttpBasicConfigurer)this.getOrApply(new HttpBasicConfigurer()); }
which could be used as well and this doesn't return the modified httpSecurity
object but an HttpBasicConfigurer
instead which could be written as to modify the httpSecurity
using the builder pattern.
So the Example 1 could now be written as
httpSecurity.httpBasic()
.realmName("My Realm")
.authenticationEntryPoint(new YourAuthEntryClass())
.and().authorizeRequests().and().csrf().disable()
.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated());
And in case you didn't want to apply any basic http configuration changes to the httpSecurity
you could just skip the methods realmName
and authenticationEntryPoint
from the builder pattern, and it would have provide you again with the default basic configurations for httpSecurity
httpSecurity.httpBasic()
.and()
.authorizeRequests().and().csrf().disable()
.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated());
which would be exactly the same with the version of
httpSecurity.httpBasic(Customizer.withDefaults())
.authorizeRequests().and().csrf().disable()
.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated());
CodePudding user response:
use default setting.
for ex,
- whom to authorize
- how to authorize