没有 WebSecurityConfigurerAdapter 的 Spring Security

fsk*_*304 15 java spring spring-security spring-boot

我正在尝试更新到 Spring Boot 2.7.0-SNAPSHOT。WebSecurityConfigurerAdapter 在此版本中已弃用。

旧的 WebSecurityConfig 与 WebSecurityConfigurerAdapter (工作正常):

/**
 * SecurityConfig
 *
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;

    @Autowired
    private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    @Autowired
    private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler;

    @Autowired
    private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler;

    @Autowired
    private OAuth2UserServiceImpl oAuth2UserServiceImpl;

    /**
     * for development
     * 
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        // for development
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    public void configure(WebSecurity web) {
        // ignoring
        web.ignoring().antMatchers("/css/**", "/js/**", "/img/**", "/lib/**", "/favicon.ico", "/oauth2");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests().antMatchers("/", "/login", "/error", "/message/**").permitAll();
        http.authorizeRequests().anyRequest().authenticated();
        http.formLogin();
        http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint("/login"));
        http.addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class);

        // OAuth2
        http.oauth2Login().loginPage("/").defaultSuccessUrl("/home", false);
        http.oauth2Login().userInfoEndpoint().userService(oAuth2UserServiceImpl);
        http.oauth2Login().successHandler(oAuth2AuthenticationSuccessHandler);
        http.oauth2Login().failureHandler(oAuth2AuthenticationFailureHandler);


        http.logout().logoutUrl("/logout").logoutSuccessUrl("/login").deleteCookies("JSESSIONID");

        http.csrf().disable();

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .enableSessionUrlRewriting(false);
    }

    private MyAuthenticationFilter authenticationFilter() throws Exception {
        MyAuthenticationFilter filter = new MyAuthenticationFilter();
        filter.setAuthenticationManager(authenticationManagerBean());
        filter.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler);
        filter.setAuthenticationFailureHandler(customAuthenticationFailureHandler);

        filter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/authentication", "POST"));
        return filter;
    }

    private AuthenticationEntryPoint authenticationEntryPoint(String loginFormUrl) {
        return new MyLoginUrlAuthenticationEntryPoint(loginFormUrl);
    }

}

Run Code Online (Sandbox Code Playgroud)

读完这篇博文后,我修改了新的WebSecurityConfig:

/**
 * SecurityConfig
 *
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    @Autowired
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;

    @Autowired
    private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    @Autowired
    private OAuth2AuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler;

    @Autowired
    private OAuth2AuthenticationFailureHandler oAuth2AuthenticationFailureHandler;

    @Autowired
    private OAuth2UserServiceImpl oAuth2UserServiceImpl;

    /**
     * for development
     * 
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        // for development
        return NoOpPasswordEncoder.getInstance();
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().antMatchers(
                "/css/**", "/js/**", "/img/**", "/lib/**", "/favicon.ico", "/oauth2");
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http.authorizeRequests().antMatchers("/", "/login", "/error", "/message/**").permitAll();
        http.authorizeRequests().anyRequest().authenticated();
        http.formLogin();
        http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint("/login"));
        http.addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class);

        // OAuth2
        http.oauth2Login().loginPage("/").defaultSuccessUrl("/home", false);
        http.oauth2Login().userInfoEndpoint().userService(oAuth2UserServiceImpl);
        http.oauth2Login().successHandler(oAuth2AuthenticationSuccessHandler);
        http.oauth2Login().failureHandler(oAuth2AuthenticationFailureHandler);

        http.logout().logoutUrl("/logout").logoutSuccessUrl("/login").deleteCookies("JSESSIONID");

        http.csrf().disable();

        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .enableSessionUrlRewriting(false);

        return http.build();
    }

    private MyAuthenticationFilter authenticationFilter() throws Exception {
        MyAuthenticationFilter filter = new MyAuthenticationFilter();

        // How can I fix this? ------------------------------------------
        filter.setAuthenticationManager(authenticationManagerBean());
        // --------------------------------------------------------------

        filter.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler);
        filter.setAuthenticationFailureHandler(customAuthenticationFailureHandler);
        filter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/authentication", "POST"));
        return filter;
    }

    private AuthenticationEntryPoint authenticationEntryPoint(String loginFormUrl) {
        return new MyLoginUrlAuthenticationEntryPoint(loginFormUrl);
    }

}

Run Code Online (Sandbox Code Playgroud)

我能够修复两种方法。(#configure(WebSecurity web)和#configure(HttpSecurity http))

但是,我不知道如何修复authenticationManagerBean()。我从哪里获取 AuthenticationManager?

小智 9

这是我花了一天时间配置的整个课程。希望它可以节省您的时间。

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class ApplicationSecurityConfig {

    private final UserDetailsService userService;
    private final AuthenticationConfiguration configuration;
    
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        AbstractAuthenticationProcessingFilter filter = new CustomizedAuthenticationFilter(authenticationManager());
        filter.setFilterProcessesUrl("/api/login");
        http.csrf().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.authorizeRequests().antMatchers(HttpMethod.POST, "/api/login").permitAll();
        http.authorizeRequests().anyRequest().authenticated();
        http.addFilter(filter);
        
        return http.build();
    }

    @Bean
    AuthenticationManager authenticationManager() throws Exception {
        return configuration.getAuthenticationManager();
    }
    
    @Autowired
    void configure(AuthenticationManagerBuilder builder) throws Exception {
        builder.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
    }
}
Run Code Online (Sandbox Code Playgroud)


Ele*_*ana 4

您可以创建自定义 DSL。这实际上就是 Spring Security 内部的工作方式。

public class MyCustomDsl extends AbstractHttpConfigurer<MyCustomDsl, HttpSecurity> {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
        http.addFilterBefore(new MyAuthenticationFilter(authenticationManager), UsernamePasswordAuthenticationFilter.class);
    }

    public static MyCustomDsl customDsl() {
        return new MyCustomDsl();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以在构建时应用自定义 DSL SecurityFilterChain

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    // ...
    http.apply(customDsl());
    return http.build();
}
Run Code Online (Sandbox Code Playgroud)