package io.github.xxyopen.novel.monitor.config;

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import jakarta.servlet.DispatcherType;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.util.UUID;

import static org.springframework.http.HttpMethod.DELETE;
import static org.springframework.http.HttpMethod.POST;

/**
 * Spring Security 配置
 *
 * @author xiongxiaoyang
 * @date 2022/6/8
 */
@Configuration(proxyBeanMethods = false)
public class SecuritySecureConfig {

    private final AdminServerProperties adminServer;

    private final SecurityProperties security;

    public SecuritySecureConfig(AdminServerProperties adminServer, SecurityProperties security) {
        this.adminServer = adminServer;
        this.security = security;
    }

    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter('redirectTo');
        successHandler.setDefaultTargetUrl(this.adminServer.path('/'));

        http.authorizeHttpRequests((authorizeRequests) -> authorizeRequests //
                .requestMatchers(new AntPathRequestMatcher(this.adminServer.path('/assets/**'))).permitAll()
                .requestMatchers(new AntPathRequestMatcher(this.adminServer.path('/actuator/info'))).permitAll()
                .requestMatchers(new AntPathRequestMatcher(adminServer.path('/actuator/health'))).permitAll()
                .requestMatchers(new AntPathRequestMatcher(this.adminServer.path('/login'))).permitAll()
                .dispatcherTypeMatchers(DispatcherType.ASYNC)
                .permitAll() // https://github.com/spring-projects/spring-security/issues/11027
                .anyRequest().authenticated())
            .formLogin((formLogin) -> formLogin.loginPage(this.adminServer.path('/login'))
                .successHandler(successHandler))
            .logout((logout) -> logout.logoutUrl(this.adminServer.path('/logout')))
            .httpBasic(Customizer.withDefaults());

        http.addFilterAfter(new CustomCsrfFilter(), BasicAuthenticationFilter.class)
            .csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler()).ignoringRequestMatchers(
                    new AntPathRequestMatcher(this.adminServer.path('/instances'), POST.toString()),
                    new AntPathRequestMatcher(this.adminServer.path('/instances/*'), DELETE.toString()),
                    new AntPathRequestMatcher(this.adminServer.path('/actuator/**'))
                ));

        http.rememberMe((rememberMe) -> rememberMe.key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600));

        return http.build();

    }

    // Required to provide UserDetailsService for 'remember functionality'
    @Bean
    public InMemoryUserDetailsManager userDetailsService(PasswordEncoder passwordEncoder) {
        UserDetails user = User.withUsername('user').password(passwordEncoder.encode('password')).roles('USER').build();
        return new InMemoryUserDetailsManager(user);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
Spring Security 安全配置详解 - io.github.xxyopen.novel.monitor.config.SecuritySecureConfig

原文地址: https://www.cveoy.top/t/topic/uN2 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录