Working around spaghetti lambdas and builder in Spring Security v6

1 day ago 5
ARTICLE AD BOX

I am working to adapt Spring Security v6 in my application and one of the GitHub projects I am using as a model has the following filterChain implementation in its @EnableWebSecurity Configuration class:

@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf(AbstractHttpConfigurer::disable) .securityContext((securityContext) -> securityContext.requireExplicitSave(true)) .authorizeHttpRequests(authz -> { authz.requestMatchers(HttpMethod.GET, "/roleHierarchy") .hasRole("STAFF") .requestMatchers("/login*", "/logout*", "/signin/**", "/signup/**", "/customLogin", "/user/registration*", "/registrationConfirm*", "/expiredAccount*", "/registration*", "/badUser*", "/user/resendRegistrationToken*", "/forgetPassword*", "/user/resetPassword*", "/user/savePassword*", "/updatePassword*", "/user/changePassword*", "/emailError*", "/resources/**", "/old/user/registration*", "/successRegister*", "/qrcode*", "/user/enableNewLoc*") .permitAll() .requestMatchers("/invalidSession*") .anonymous() .requestMatchers("/user/updatePassword*") .hasAuthority("CHANGE_PASSWORD_PRIVILEGE") .requestMatchers("/console") .hasAuthority("READ_PRIVILEGE") .anyRequest() .hasAuthority("READ_PRIVILEGE"); }) .formLogin((formLogin) -> formLogin.loginPage("/login") .defaultSuccessUrl("/homepage.html") .failureUrl("/login?error=true") .successHandler(myAuthenticationSuccessHandler) .failureHandler(authenticationFailureHandler) .authenticationDetailsSource(authenticationDetailsSource) .permitAll()) .sessionManagement((sessionManagement) -> sessionManagement.invalidSessionUrl("/invalidSession.html") .maximumSessions(1) .sessionRegistry(sessionRegistry())) .logout((logout) -> logout.logoutSuccessHandler(myLogoutSuccessHandler) .invalidateHttpSession(true) .logoutSuccessUrl("/logout.html?logSucc=true") .deleteCookies("JSESSIONID") .permitAll()) .rememberMe((remember) -> remember.rememberMeServices(rememberMeServices())); return http.build(); }

I can vaguely wrap my head around what this does but the legibility of this code is awful. Is there a way to break this huge and inelegant statement into multiple statements each of which fits in a single line in an average IDE without spilling over into the next line?

Something like taking each lambda into its own line of code and assigning it to an object and then passing that object as the argument where currently the lambda is passed? In other words, is there an alternative way to atomize this code by not using lambdas the ways they are used here or by not using the builder?

Something like

Customizer<FormLoginConfigurer<HttpSecurity>> formLoginCustomizer = (formLogin) -> formLogin.loginPage("/login") .defaultSuccessUrl("/homepage.html") .failureUrl("/login?error=true") .successHandler(myAuthenticationSuccessHandler) .failureHandler(authenticationFailureHandler) .authenticationDetailsSource(authenticationDetailsSource) .permitAll(); http.csrf(AbstractHttpConfigurer::disable) .securityContext(securityContextCustomizer) .authorizeHttpRequests(authorizeHttpRequestsCustomizer) .formLogin(formLoginCustomizer)

I feel like the way it currently is is like trying to swallow a whole chicken instead of cutting it up in pieces. Unless you have superhuman attention span, this is unreadable spaghetti.

Read Entire Article