SpringBoot3.0 + SpringSecurity 分离版

1.序 

SpringBoot2.6 + SpringSecurity 分离版_securityconfig配置_一枚小蜗牛H的博客-CSDN博客

参考2.6,升级SpingBoot3.0 相对于SpringSecurity也升级到了6.0相对应配置变化。

由于升级到3.0,jdk也必须是17+。首先没有了javax包,需要的都需要改,jwt也是一样。swagger配置的也不生效了,3.0只支持openapi3,knife4j包要升级到4.0,具体看knife4j官网。

2.Security配置类修改

请看代码对比修改

package com.cn.config.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
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;

/**
 * @program: demo
 * @Description 配置
 * @Date 2023/3/8
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity//开启注解权限配置
public class SecurityConfig {
    /**
     * 自定义授权拦截器
     */
    @Autowired
    private MyLoginJwtFilter myLoginJwtFilter;
    /**
     * 自定义UserDetailsService实现
     */
    @Autowired
    private MyUserDetailService myUserDetailService;
    /**
     * 认证失败
     */
    @Autowired
    private MyAuthenticationEntryPoint myAuthenticationEntryPoint;
    /**
     * 授权失败
     */
    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;
    /**
     * 注销成功
     */
    @Autowired
    private MyLogoutSuccessHandler myLogoutSuccessHandler;

    /**
     * 强散列哈希加密实现 没有这个会报错 There is no PasswordEncoder mapped for the id “null“
     */
    @Bean
    public BCryptPasswordEncoder newBCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    //暴露出来 解决无法直接注入 AuthenticationManager
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

    /**
     * 配置类
     *
     * @param httpSecurity HttpSecurity
     * @throws Exception Exception
     */
    @Bean
    SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                //过滤请求
                .authorizeHttpRequests()
                //对于登录login 注册register 验证码captchaImage 放开
                .requestMatchers("/login/**").permitAll()
                //测试功能 放开
                .requestMatchers("/test/**").permitAll()
                //静态资源 放开
                .requestMatchers(HttpMethod.GET, "/", "/*.html", "/*.css", "/*.js", "/*/*.html", "/*/*.css", "/*/*.js", "/*/api-docs/**","/webjars/**","/*.ioc").permitAll()
                .anyRequest()
                //所有请求都必须认证
                .authenticated()
                .and()
                .formLogin()
                .and()
                .exceptionHandling()
                //没登录提示信息
                .authenticationEntryPoint(myAuthenticationEntryPoint)
                //授权失败
                .accessDeniedHandler(myAccessDeniedHandler)
                //退出登录提示信息
                .and().logout().logoutUrl("/logout")
                .logoutSuccessHandler(myLogoutSuccessHandler)
                //跨域处理方案
                .and().cors().configurationSource(configurationSource())
                //关闭csrf
                .and().csrf().disable()
        ;

        //替换自带的filter
        //at: 用来某个 filter 替换过滤器链中哪个 filter
        //before: 放在过滤器链中哪个 filter 之前
        //after: 放在过滤器链中那个 filter 之后
        httpSecurity.addFilterBefore(myLoginJwtFilter, UsernamePasswordAuthenticationFilter.class);

        return httpSecurity.build();
    }


    /**
     * 跨域解决方案
     *
     * @return CorsConfigurationSource
     */
    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;
    }

}

 2.1.不需要继承了,配置类注释

 2.2.校验类换成HttpSecurity

 2.3.过滤链过期修改与更新

 3.自定义拦截器

package com.cn.config.security;

import com.cn.common.Constants;
import com.cn.utils.JwtUtil;
import com.cn.utils.RedisCacheUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
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 java.io.IOException;

/**
 * @program: SpringSecurityDemo
 * @Description LoginFilter
 * @Date 2023/3/8
 */
@Slf4j
@Component
public class MyLoginJwtFilter extends OncePerRequestFilter {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private RedisCacheUtil redisCacheUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //鉴权验证
        //获取token
        String token = JwtUtil.getHeaderToken(request);
        if (StringUtils.isNotBlank(token)) {
            //获取用户名
            String username = JwtUtil.parseTokenName(token);
            if (StringUtils.isNotBlank(username)) {
                //判断是否有效
                String redisKey = Constants.REDIS_USER + token;
                if (redisCacheUtil.isKey(redisKey)) {
                    //获取资源
                    UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), null, userDetails.getAuthorities());
                    //存入资源
                    authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                }
            }
        }
        //放行
        filterChain.doFilter(request, response);
    }
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值