Spring Security 6配置
本文最后更新于129 天前,其中的信息可能已经过时,如有错误请发送邮件到3088506834@qq.com

过滤链配置

配置关闭csrf并关闭默认登录接口,且从 application.yml 获取排除url规则进行排除

 
    @Resource
    private SecurityExcludedUrlsConfig excludedUrlsConfig;

    @Bean
    public SecurityFilterChain customSecurityFilterChain(HttpSecurity http) throws Exception {
        http
                .addFilterBefore(checkTokenFilter, UsernamePasswordAuthenticationFilter.class)
                .userDetailsService(customerUserDetailsService)
                .formLogin(AbstractHttpConfigurer::disable
                )
                .csrf(csrf -> csrf.disable())
                .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
                http.authorizeHttpRequests(auth -> {
                    excludedUrlsConfig.getUrls().forEach(url -> auth.requestMatchers(url).permitAll());
                    auth.anyRequest().authenticated();
                })

                .exceptionHandling(exceptionHandling ->
                        exceptionHandling
                                .authenticationEntryPoint(loginAuthenticationHandler)
                                .accessDeniedHandler(loginAccessDefineHandler)
                )
                .cors(cors -> cors.configurationSource(configurationSource()))
                .headers(headers -> headers.frameOptions(frameOptionsConfig -> frameOptionsConfig.disable()))
                .headers(headers -> headers.frameOptions(frameOptionsConfig -> frameOptionsConfig.sameOrigin()));
        return http.build();
    }
Java

SecurityExcludedUrlsConfig.class

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
 * online.yudream.platform.config
 *
 * @author SiberianHusky
 * * @date 2025/7/5
 */
@Setter
@Getter
@Configuration
@ConfigurationProperties(prefix = "security.excluded-urls")
public class SecurityExcludedUrlsConfig {

    private List<String> urls;

}
Java

application.yml

security:
  excluded-urls:
    urls:
      - /user/login
      - /user/register
Java

跨域配置

    private CorsConfigurationSource configurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedHeaders(Collections.singletonList("*"));
        corsConfiguration.setAllowedMethods(Collections.singletonList("*"));
        corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
        corsConfiguration.setMaxAge(3600L);

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

SecurityConfig.class

package online.yudream.platform.config;

import jakarta.annotation.Resource;
import online.yudream.platform.filter.CheckTokenFilter;
import online.yudream.platform.handler.AjaxAuthenticationFailureHandler;
import online.yudream.platform.handler.AjaxAuthenticationSuccessHandler;
import online.yudream.platform.handler.LoginAccessDefineHandler;
import online.yudream.platform.handler.LoginAuthenticationHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
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.Collections;

@Configuration
@EnableWebSecurity()
@EnableMethodSecurity
public class SecurityConfig implements WebSecurityConfigurer<WebSecurity> {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    private AjaxAuthenticationSuccessHandler ajaxAuthenticationSuccessHandler;

//    @Autowired
//    private AjaxAuthenticationFailureHandler ajaxAuthenticationFailureHandler;
    @Resource
    private LoginAuthenticationHandler loginAuthenticationHandler;
    @Resource
    private LoginAccessDefineHandler loginAccessDefineHandler;

    @Resource
    private CheckTokenFilter checkTokenFilter;

    @Resource
    private UserDetailsService customerUserDetailsService;
    @Resource
    private SecurityExcludedUrlsConfig excludedUrlsConfig;



    @Bean
    public SecurityFilterChain customSecurityFilterChain(HttpSecurity http) throws Exception {
        http
                .addFilterBefore(checkTokenFilter, UsernamePasswordAuthenticationFilter.class)
                .userDetailsService(customerUserDetailsService)
                .formLogin(AbstractHttpConfigurer::disable
                )
                .csrf(csrf -> csrf.disable())
                .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
                http.authorizeHttpRequests(auth -> {
                    excludedUrlsConfig.getUrls().forEach(url -> auth.requestMatchers(url).permitAll());
                    auth.anyRequest().authenticated();
                })

                .exceptionHandling(exceptionHandling ->
                        exceptionHandling
                                .authenticationEntryPoint(loginAuthenticationHandler)
                                .accessDeniedHandler(loginAccessDefineHandler)
                )
                .cors(cors -> cors.configurationSource(configurationSource()))
                .headers(headers -> headers.frameOptions(frameOptionsConfig -> frameOptionsConfig.disable()))
                .headers(headers -> headers.frameOptions(frameOptionsConfig -> frameOptionsConfig.sameOrigin()));
        return http.build();
    }

    private CorsConfigurationSource configurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedHeaders(Collections.singletonList("*"));
        corsConfiguration.setAllowedMethods(Collections.singletonList("*"));
        corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
        corsConfiguration.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

    @Override
    public void init(WebSecurity builder) throws Exception {

    }

    @Override
    public void configure(WebSecurity builder) throws Exception {

    }
}
Java

JWT过滤层

JwtUtils

package online.yudream.platform.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import online.yudream.platform.exception.CustomerAuthenticationException;
import org.apache.tomcat.websocket.AuthenticationException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Map;

/**
 * online.yudream.platform.utils
 *
 * @author SiberianHusky
 * * @date 2025/7/5
 */
@Component
public class JWTUtils {
    @Value("${application.security.jwt.secret-key}")
    private String SECRET;
    @Value("${application.security.jwt.expiration}")
    private int EXPIRATION;
    @Value("${application.security.jwt.refresh-token.expiration}")
    private int REFRESH_TOKEN_EXPIRATION;

    /**
     * @Param: 传入需要设置的payload信息
     * @return: 返回token
     */
    public String generateToken(Map<String, String> map) {
        return getJwt(map, EXPIRATION);
    }

    public String getJwt(Map<String, String> map, int refreshTokenExpiration) {
        JWTCreator.Builder builder = JWT.create();
        map.forEach(builder::withClaim);
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND, refreshTokenExpiration);
        builder.withExpiresAt(instance.getTime());
        return builder.sign(Algorithm.HMAC256(SECRET));
    }

    /**
     * @Param: 传入token
     * @return:
     */

    public void verify(String token) {

        try {
            JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
        } catch (Exception e) {
            throw new CustomerAuthenticationException("token验证失败");
        }

    }


    /**
     * @Param: 传入token
     * @return: 解密的token信息
     */

    public String getTokenInfo(String token) {

        return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token).getClaim("username").asString();

    }
}
Java

CheckTokenFilter

package online.yudream.platform.filter;

import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import online.yudream.platform.config.SecurityExcludedUrlsConfig;
import online.yudream.platform.exception.CustomerAuthenticationException;
import online.yudream.platform.utils.JWTUtils;
import online.yudream.platform.utils.RedisCache;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.PathContainer;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * online.yudream.platform.filter
 *
 * @author SiberianHusky
 * * @date 2025/7/5
 */
@Data
@Component
@EqualsAndHashCode(callSuper = false)
@Slf4j
public class CheckTokenFilter extends OncePerRequestFilter {
    private String loginUrl = "/login";

    //    @Autowired
//    private AjaxAuthenticationFailureHandler loginFailureHandler;
    @Autowired
    private UserDetailsService customerUserDetailsService;
    private final PathPatternParser pathPatternParser = new PathPatternParser();
    @Autowired
    private JWTUtils jwtUtils;

    @Resource
    private RedisCache redisCache;

    @Autowired
    private SecurityExcludedUrlsConfig excludedUrlsConfig;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws IOException, ServletException {
        //获取请求的url(读取配置文件的url)
        String url = httpServletRequest.getRequestURI();
        if (isExcludedUrl(url)) {
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        } else {

            //token验证(如果不是登录请求 验证toekn)
            if (!url.equals(loginUrl)) {
                validateToken(httpServletRequest);
            }

            filterChain.doFilter(httpServletRequest, httpServletResponse);
        }

    }

    private boolean isExcludedUrl(String url) {
        List<PathPattern> patterns = excludedUrlsConfig.getUrls().stream()
                .map(pathPatternParser::parse)
                .collect(Collectors.toList());
        return patterns.stream().anyMatch(pattern -> pattern.matches(PathContainer.parsePath(url)));
    }

    //token验证
    private void validateToken(HttpServletRequest request) {
        //从请求的头部获取token
        String token = request.getHeader("Authorization");
        //如果请求头部没有获取到token,则从请求参数中获取token
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter("token");
        }
        if (StringUtils.isEmpty(token)) {
            // 请求参数中也没有 那就从redis中进行获取根据ip地址取
            token = redisCache.getCacheObject(request.getRemoteAddr());
        }
        if (StringUtils.isEmpty(token)) {
            throw new CustomerAuthenticationException("token不存在!");
        }
        //解析token
        String username = jwtUtils.getTokenInfo(token);
        if (StringUtils.isEmpty(username)) {
            throw new CustomerAuthenticationException("token解析失败!");
        }
        //获取用户信息
        UserDetails user = customerUserDetailsService.loadUserByUsername(username);
        if (user == null) {
            throw new CustomerAuthenticationException("token验证失败!");
        }
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
    }
}
Java
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇