Home > Mobile >  What is the purpose of withDefaults() is spring
What is the purpose of withDefaults() is spring

Time:08-31

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,

  1. whom to authorize
  2. how to authorize
  • Related