天天看點

springboot3-springsecurity配置

作者:好學麻醬zX
package ******;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @Author
 * @Desc spring security 由于前後端分離是以伺服器端不能用session控制,通過基于 token機制 進行登陸驗證
 */
@SpringBootConfiguration
@EnableWebSecurity // 開啟WebSecurity支援
@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true, jsr250Enabled = true)
public class WebSecurityByTokenConfig {

    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Autowired
    public void setJwtAuthenticationTokenFilter(JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter) {
        this.jwtAuthenticationTokenFilter = jwtAuthenticationTokenFilter;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return configure(http);
    }

    protected SecurityFilterChain configure(HttpSecurity http) throws Exception {

        http
                // 開啟跨域
                .cors().configurationSource(corsConfigurationSource())
                .and()
                .csrf()
                .disable() // 禁用csrf保護
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 禁用session
                .and()
                .headers().frameOptions().disable() //允許iframe通路
                .and()
                .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> {
                    try {
                        authorizationManagerRequestMatcherRegistry
                                .requestMatchers("/login/**").permitAll() // 登入過濾
                                

                                .requestMatchers("/static/**").permitAll() // 靜态資源
                               
                                .anyRequest().fullyAuthenticated()
                                .and()
                                .exceptionHandling() // 異常處理
                                .authenticationEntryPoint(new RestAuthenticationEntryPoint()) // 未認證異常處理
                                .accessDeniedHandler(new SysAccessDeniedHandler()); // 權限拒絕異常處理
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    
                })
                // 添加前置過濾器
                .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
                //禁用header緩存
                .headers().cacheControl();
        return http.build();


    }


    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return new WebSecurityCustomizer() {
            @Override
            public void customize(WebSecurity web) {
                web.ignoring().requestMatchers("/images/**", "/js/**", "/webjars/**");
            }
        };

    }

    /**
     * 跨域配置
     *
     * @return
     */
    private CorsConfigurationSource corsConfigurationSource() {

        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Collections.singletonList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(Collections.singletonList("*"));

        List<String> exposedHeaders = Arrays.asList("X-Authenticate", "Content-Length", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Content-Type", "Date", "_token", "Token");
        exposedHeaders.forEach(configuration::addExposedHeader);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }


}
           

繼續閱讀