SpringBoot3.0 + SpringSecurity 分离版

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。SpringBoot3.0 + SpringSecurity 分离版,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

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.不需要继承了,配置类注释SpringBoot3.0 + SpringSecurity 分离版

 2.2.校验类换成HttpSecurity

SpringBoot3.0 + SpringSecurity 分离版

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

SpringBoot3.0 + SpringSecurity 分离版

 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);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192749.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!