欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot3.x接入Security6.x實(shí)現(xiàn)JWT認(rèn)證的完整步驟

 更新時(shí)間:2025年02月15日 09:42:53   作者:草青工作室  
這篇文章主要介紹了Spring?Boot?3.x中Spring?Security?6.x的安全配置變化,特別是JWT過(guò)濾器的工作原理和配置方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、引言

SpringBoot3.x的安全默認(rèn)依賴(lài)Security6.x,Security6.x于Security5.7以前的配置有了很大區(qū)別。我們將深入探討這兩個(gè)版本之間的差異,以及它們?nèi)绾斡绊懍F(xiàn)代Web應(yīng)用的安全架構(gòu)。特別是,我們將重點(diǎn)分析JWT(JSON Web Tokens)過(guò)濾器的工作原理,以及它是如何與匿名訪問(wèn)相結(jié)合,為應(yīng)用提供更加靈活的安全控制。

二、環(huán)境

  • JDK 17
  • SpringBoot 3.2
  • Security 6.3

三、Maven依賴(lài)

<!-- Security安全 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>3.2.2</version>
</dependency>
<!-- jwt接口認(rèn)證 -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>4.4.0</version>
</dependency>      

四、認(rèn)識(shí)JWT

JSON Web Token (JWT)是一個(gè)開(kāi)放標(biāo)準(zhǔn)(RFC 7519),它定義了一種緊湊的、自包含的方式,用于作為JSON對(duì)象在各方之間安全地傳輸信息。該信息可以被驗(yàn)證和信任,因?yàn)樗菙?shù)字簽名的。

1. JWT組成

JSON Web Token由三部分組成,它們之間用圓點(diǎn)(.)連接,一個(gè)典型的JWT看起來(lái)是這個(gè)樣子的:

  • 第一部分:header典型的由兩部分組成:token的類(lèi)型(“JWT”)和算法名稱(chēng)(比如:HMAC SHA256或者RSA等等),然后,用Base64對(duì)這個(gè)JSON編碼就得到JWT的第一部分。
  • 第二部分:payload它包含聲明(要求),聲明是關(guān)于實(shí)體(通常是用戶(hù))和其他數(shù)據(jù)的聲明。
  • 第三部分:簽名是用于驗(yàn)證消息在傳遞過(guò)程中有沒(méi)有被更改,并且對(duì)于使用私鑰簽名的token,它還可以驗(yàn)證JWT的發(fā)送方是否為它所稱(chēng)的發(fā)送方。

注意:不要在JWT的payload或header中放置敏感信息,除非它們是加密的。

{
 alg: "RS256"
}.
{
//存儲(chǔ)自定義的用戶(hù)信息,屬性可以自定擴(kuò)充
 login_name: "admin",
 user_id: "xxxxx",
 ...
}.
[signature]
  • 請(qǐng)求header應(yīng)該是這樣的:Authorization: Bearer

五、認(rèn)識(shí)Security6.x

1. 和舊版本的區(qū)別(Security5.7以前的版本)

SpringBoot3中默認(rèn)Security升級(jí)到了6.x寫(xiě)法上發(fā)生了很大的變化,最顯著的變化之一就是對(duì)WebSecurityConfigurerAdapter類(lèi)的使用方式的改變。這個(gè)類(lèi)在 Spring Security 中被廣泛用于自定義安全配置。以下是主要的差異和寫(xiě)法上的變化:

  • 廢棄WebSecurityConfigurerAdapter:

在Security5.x 版本中,WebSecurityConfigurerAdapter 是實(shí)現(xiàn)安全配置的常用方法。用戶(hù)通過(guò)繼承這個(gè)類(lèi),并覆蓋其方法來(lái)自定義安全配置。到了 Spring Security 6.x,WebSecurityConfigurerAdapter 被標(biāo)記為過(guò)時(shí)(deprecated),意味著它可能在未來(lái)的版本中被移除。這一變化是為了推動(dòng)使用更現(xiàn)代的配置方法,即使用組件式配置。

  • 新版本建議使用組件式配置:

在 Spring Security 6.x 中,推薦使用組件式配置。這意味著你可以創(chuàng)建一個(gè)配置類(lèi),該類(lèi)不再需要繼承 WebSecurityConfigurerAdapter。
你可以直接定義一個(gè)或多個(gè) SecurityFilterChain Bean來(lái)配置安全規(guī)則。這種方式更加靈活,并且與 Spring Framework 的整體風(fēng)格更加一致。

2. Security6.x的默認(rèn)篩選器

支持的所有篩選器在spring-security-config-6.2.1.jar包的org.springframework.security.config.annotation.web.builders.FilterOrderRegistration類(lèi)的構(gòu)造函數(shù)中定義,并確定了執(zhí)行順序。

FilterOrderRegistration() {
    Step order = new Step(INITIAL_ORDER, ORDER_STEP);
    put(DisableEncodeUrlFilter.class, order.next());
    put(ForceEagerSessionCreationFilter.class, order.next());
    put(ChannelProcessingFilter.class, order.next());
    order.next(); // gh-8105
    put(WebAsyncManagerIntegrationFilter.class, order.next());
    put(SecurityContextHolderFilter.class, order.next());
    put(SecurityContextPersistenceFilter.class, order.next());
    put(HeaderWriterFilter.class, order.next());
    put(CorsFilter.class, order.next());
    put(CsrfFilter.class, order.next());
    put(LogoutFilter.class, order.next());
    this.filterToOrder.put(
            "org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter",
            order.next());
    this.filterToOrder.put(
            "org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter",
            order.next());
    put(X509AuthenticationFilter.class, order.next());
    put(AbstractPreAuthenticatedProcessingFilter.class, order.next());
    this.filterToOrder.put("org.springframework.security.cas.web.CasAuthenticationFilter", order.next());
    this.filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter",
            order.next());
    this.filterToOrder.put(
            "org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter",
            order.next());
    put(UsernamePasswordAuthenticationFilter.class, order.next());
    order.next(); // gh-8105
    put(DefaultLoginPageGeneratingFilter.class, order.next());
    put(DefaultLogoutPageGeneratingFilter.class, order.next());
    put(ConcurrentSessionFilter.class, order.next());
    put(DigestAuthenticationFilter.class, order.next());
    this.filterToOrder.put(
            "org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter",
            order.next());
    put(BasicAuthenticationFilter.class, order.next());
    put(RequestCacheAwareFilter.class, order.next());
    put(SecurityContextHolderAwareRequestFilter.class, order.next());
    put(JaasApiIntegrationFilter.class, order.next());
    put(RememberMeAuthenticationFilter.class, order.next());
    put(AnonymousAuthenticationFilter.class, order.next());
    this.filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter",
            order.next());
    put(SessionManagementFilter.class, order.next());
    put(ExceptionTranslationFilter.class, order.next());
    put(FilterSecurityInterceptor.class, order.next());
    put(AuthorizationFilter.class, order.next());
    put(SwitchUserFilter.class, order.next());
}

3. 注冊(cè)SecurityFilterChain

    private final String[] permitUrlArr = new String[]{"xxx"};
    /**
     * 配置Spring Security安全鏈。
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        //初始化jwt過(guò)濾器,并設(shè)置jwt公鑰
        var jwtTokenFilter = new JwtTokenFilter();
        //Security6.x關(guān)閉默認(rèn)登錄頁(yè)
        httpSecurity.removeConfigurers(DefaultLoginPageConfigurer.class);
        logger.info("注冊(cè)JWT認(rèn)證SecurityFilterChain");
        var chain = httpSecurity
                // 自定義權(quán)限攔截規(guī)則
                .authorizeHttpRequests((requests) -> {
                    //requests.anyRequest().permitAll(); //放行所有請(qǐng)求!!!
                    //允許匿名訪問(wèn)
                    requests
                            //自定可匿名訪問(wèn)地址,放到permitAllUrl中即可
                            .requestMatchers(permitUrlArr).permitAll()
                            //除上面聲明的可匿名訪問(wèn)地址,其它所有請(qǐng)求全部需要進(jìn)行認(rèn)證
                            .anyRequest()
                            .authenticated();
                })
                // 禁用HTTP響應(yīng)標(biāo)頭
                .headers(headersCustomizer -> {headersCustomizer
                            .cacheControl(cache -> cache.disable())
                            .frameOptions(options -> options.sameOrigin());})
                //會(huì)話(huà)設(shè)為無(wú)狀態(tài),基于token,所以不需要session
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                //添加自定義的JWT認(rèn)證篩選器,驗(yàn)證header中jwt有效性,將插入到UsernamePasswordAuthenticationFilter之前 
                .addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class)
                //禁用表單登錄
                .formLogin(formLogin -> formLogin.disable())
                //禁用httpBasic登錄
                .httpBasic(httpBasic -> httpBasic.disable())
                //禁用rememberMe
                .rememberMe(rememberMe -> rememberMe.disable())
                // 禁用CSRF,因?yàn)椴皇褂胹ession
                .csrf(csrf -> csrf.disable())
                //允許跨域請(qǐng)求
                .cors(Customizer.withDefaults())
                .build();
        return chain;
    }

六、基于OncePerRequestFilter自定義JWT認(rèn)證篩選器

使用OncePerRequestFilter的優(yōu)點(diǎn)是,能保證一個(gè)請(qǐng)求只過(guò)一次篩選器??梢栽趂ilter中實(shí)現(xiàn)對(duì)jwt的校驗(yàn),驗(yàn)證成功后需要對(duì)Security上下文進(jìn)行標(biāo)注。標(biāo)記認(rèn)證已經(jīng)通過(guò),這點(diǎn)非常重要。如果認(rèn)證完了不標(biāo)注,后邊的過(guò)濾器還是認(rèn)為未認(rèn)證導(dǎo)致無(wú)權(quán)限失敗。

1. 標(biāo)記認(rèn)證成功

//接入Spring Security6.x上下文,標(biāo)記為已認(rèn)證狀態(tài)
JwtAuthenticationToken jwtToken = new JwtAuthenticationToken(null);
jwtToken.setAuthenticated(true); //標(biāo)記認(rèn)證通過(guò)
SecurityContextHolder.getContext().setAuthentication(jwtToken);

七、遇到的問(wèn)題

1. 加入Security6后,一直出現(xiàn)登錄頁(yè)

關(guān)閉默認(rèn)登錄頁(yè)有兩個(gè)設(shè)置可以完成,可以刪除DefaultLoginPageConfigurer類(lèi)的加載,或者調(diào)用formLogin()函數(shù),具體如下:

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        //Security6.x關(guān)閉默認(rèn)登錄頁(yè)
        httpSecurity.removeConfigurers(DefaultLoginPageConfigurer.class);
        var chain = httpSecurity
                //禁用表單登錄
                .formLogin(formLogin -> formLogin.disable())
                .build();
        return chain;
    }

2. 配置完匿名訪問(wèn)的URL后,仍然執(zhí)行自定的篩選器

如果出現(xiàn)配置完匿名訪問(wèn)的URL后,仍然執(zhí)行自定的篩選器,的問(wèn)題。那原因就在于這個(gè)自定義篩選器上了,
只通過(guò)requests.requestMatchers(…).permitAll(); 配置的匿名訪問(wèn)只能對(duì)默認(rèn)篩選器起效,如果想
對(duì)自定義刪除器起效,還需要構(gòu)建WebSecurityCustomizer Bean對(duì)象,基于匿名函數(shù)配置要匿名訪問(wèn)的地址。
一下是官網(wǎng)推薦的一個(gè)寫(xiě)法,這里建議把兩個(gè)位置,配置的匿名訪問(wèn)地址,使用一個(gè)公共數(shù)組進(jìn)行管理,這樣
能保證兩個(gè)位置配置的一致性。

    /** 其它不需要認(rèn)證的地址 */
    private final String[] permitUrlArr = new String[]{
            "/login"
            ,"/error"
            //靜態(tài)資源
            ,"/static/**.ico"
            ,"/static/**.js"
            ,"/static/**.css"
            //匹配springdoc
            ,"/doc.html"
            ,"/webjars/**"
            //匹配swagger路徑(默認(rèn))
            , "/swagger-ui.html"
            , "/swagger-ui/index.html"
            , "/v3/api-docs/**"
            , "/swagger-ui/**"
            //監(jiān)控檢測(cè)
            , "/actuator/**"
    };
    @Bean
    public WebSecurityCustomizer ignoringCustomize(){
        return (web) -> web.ignoring()
                .requestMatchers(permitUrlArr);
    }
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        //初始化jwt過(guò)濾器,并設(shè)置jwt公鑰
        var jwtTokenFilter = new JwtTokenFilter();
        //Security6.x關(guān)閉默認(rèn)登錄頁(yè)
        httpSecurity.removeConfigurers(DefaultLoginPageConfigurer.class);
        logger.info("注冊(cè)JWT認(rèn)證SecurityFilterChain");
        var chain = httpSecurity
                // 自定義權(quán)限攔截規(guī)則
                .authorizeHttpRequests((requests) -> {
                    //允許匿名訪問(wèn)
                    requests
                            //自定可匿名訪問(wèn)地址,放到permitAllUrl中即可
                            .requestMatchers(permitUrlArr).permitAll()
                            //除上面聲明的可匿名訪問(wèn)地址,其它所有請(qǐng)求全部需要進(jìn)行認(rèn)證
                            .anyRequest()
                            .authenticated();
                }).build();
        return chain;
    }                    

八、完成JWT認(rèn)證的主要代碼

目前是對(duì)已有jwt的認(rèn)證,下發(fā)的jwt是基于RSA加密的內(nèi)容,需要使用公鑰進(jìn)行解密,公鑰一般配置在yml文件里。關(guān)鍵邏輯設(shè)計(jì)3部分,SecuritConfig、JwtTokenFilter、JwtUtil。

1. JwtUtil

公鑰是統(tǒng)一認(rèn)證中心下發(fā)的,目前寫(xiě)在yml中,格式如下:

jwt.keyValue: |
          -----BEGIN PUBLIC KEY-----
          xxxxxxxx
          -----END PUBLIC KEY-----

JwtUtil類(lèi)提供了驗(yàn)證方法,出于性能考慮使用了單例模式,驗(yàn)證器只需要實(shí)例化一次。

public class JwtUtil {
    private static JwtUtil instance = new JwtUtil();
    private static JWTVerifier jwtVerifier;
    //配置文件中公鑰的key值
    private static final String jwtPublicKeyConfig="jwt.keyValue";

    private JwtUtil()  {}

    /**
     * 基于固定配置文件的公鑰初始化JWT驗(yàn)證器
     * @return
     */
    public static JwtUtil getInstance(){
        if (jwtVerifier == null){
            String publicKey = SpringUtil.getConfig(jwtPublicKeyConfig);
            return getInstance(publicKey);
        }
        return instance;
    }
    /**
     * 基于自定義公鑰初始化JWT驗(yàn)證器
     * @return
     */
    public static JwtUtil getInstance(String publicKey) {
        if (jwtVerifier == null){
            initVerifier(publicKey);
        }
        return instance;
    }

    // 靜態(tài)的初始化函數(shù)
    private static synchronized void initVerifier(String publicKey) {
        if (jwtVerifier != null)
            return;

        //替換為實(shí)際的Base64編碼的RSA公鑰字符串
        String publicKeyStr = publicKey.replaceAll("\\s", "") // 去除所有空白字符,包括換行符
                .replace("-----BEGINPUBLICKEY-----", "")
                .replace("-----ENDPUBLICKEY-----", "");
        // 將Base64編碼的公鑰字符串轉(zhuǎn)換為PublicKey對(duì)象
        byte[] encodedPublicKey = Base64.getDecoder().decode(publicKeyStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedPublicKey);
        KeyFactory keyFactory = null;
        try {
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey pubKey = keyFactory.generatePublic(keySpec);
            // 使用公鑰創(chuàng)建一個(gè)Algorithm對(duì)象,用于驗(yàn)證token的簽名
            Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) pubKey, null);
            // 解析和驗(yàn)證token
            jwtVerifier = JWT.require(algorithm).build();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException(e);
        }catch (Exception e){
            throw new RuntimeException(e);
        }

    }

    /**
     * 解析和驗(yàn)證JWT token。
     *
     * @param token JWT token字符串
     * @return 解碼后的JWT對(duì)象
     * @throws Exception 如果解析或驗(yàn)證失敗,拋出異常
     */
    public DecodedJWT verifyToken(String token) {
        return jwtVerifier.verify(token);
    }
}

2. JwtTokenFilter

該類(lèi)是校驗(yàn)的主要邏輯,完成了jwt校驗(yàn)、已認(rèn)證的標(biāo)注。

public class JwtTokenFilter extends OncePerRequestFilter {
    private static Logger logger = LoggerFactory.getLogger(JwtTokenFilter.class);
    private JwtUtil jwtUtil;
    //獲取yml中的配置
    public String getConfig(String configKey) {
        var bean = applicationContext.getBean(Environment.class);
        var val = bean.getProperty(configKey);
        return val;
    }
    public JwtTokenFilter() throws ServletException {
        String jwtPubliKey = getConfig("jwt.keyValue");
        initTokenFilter(jwtPubliKey);
    }

    public JwtTokenFilter(String jwtPubliKey) throws ServletException {
        initTokenFilter(jwtPubliKey);
    }

    @Override
    protected void initFilterBean() throws ServletException {
    }
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        var pass = doTokenFilter(request,response,filterChain);
        if(!pass){
            return;
        }
        filterChain.doFilter(request,response);
    }

    /**
     * 初始化Token過(guò)濾器。
     * @throws ServletException 如果在初始化過(guò)程中發(fā)生錯(cuò)誤,則拋出ServletException異常
     */
    public void  initTokenFilter(String publicKey) throws ServletException {
        logger.info("初始化TokenFilter");
        if(StringUtils.isBlank(publicKey)){
            throw new ServletException("jwtPublicKey is null");
        }
        logger.info("jwtPublicKey:{}",publicKey);
        jwtUtil = JwtUtil.getInstance(publicKey);
        logger.info("初始化JwtUtil完成");
    }

    protected Boolean doTokenFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 從請(qǐng)求頭中獲取token
        String token = request.getHeader("Authorization");
        if(StringUtils.isBlank(token)){
            logger.info("jwt token為空,{} {}",request.getMethod(),request.getRequestURI());
            // 驗(yàn)證失敗,返回401狀態(tài)碼
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token");
            return false;
        }

        // 假設(shè)token是以"Bearer "開(kāi)頭的,需要去掉這個(gè)前綴
        if (token.startsWith("Bearer")) {
            token = token.replaceAll("Bearer\s+","");
        }
        logger.debug(request.getRequestURI());
        try {
            // 調(diào)用JwtUtils進(jìn)行token驗(yàn)證
            DecodedJWT jwtDecode = jwtUtil.verifyToken(token);
            //接入Spring Security6.x上下文,標(biāo)記為已認(rèn)證狀態(tài)
            JwtAuthenticationToken jwtToken = new JwtAuthenticationToken(null);
            jwtToken.setAuthenticated(true);
            SecurityContextHolder.getContext().setAuthentication(jwtToken);
            //將登錄信息寫(xiě)入spring security上下文
        } catch (JWTVerificationException ex) {
            logger.info("jwt token 非法");
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "非法token:"+ex.getMessage());
            return false;
        } catch (Exception ex) {
            throw ex;
        }
        logger.debug("token驗(yàn)證通過(guò)");
        return true;
    }

    public static class JwtAuthenticationToken extends AbstractAuthenticationToken {
        private User userInfo;
        public JwtAuthenticationToken(User user) {
            super(null);
            this.userInfo =user;
        }
        @Override
        public User getPrincipal() {
            return userInfo;
        }
        @Override
        public Object getCredentials() {
            throw new UnsupportedOperationException();
        }

        @Override
        public boolean implies(Subject subject) {
            return super.implies(subject);
        }
    }

}

3. SecuritConfig

該類(lèi)完成了對(duì)需要匿名訪問(wèn)的地址的配置,還有自定義filter的注入。

@Configuration
public class SecurityConfig {
    private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
    /** 其它不需要認(rèn)證的地址 */
    private final String[] permitUrlArr = new String[]{
            "/login"
            ,"/error"
            //靜態(tài)資源
            ,"/static/**.ico"
            ,"/static/**.js"
            ,"/static/**.css"
            //匹配springdoc
            ,"/doc.html"
            ,"/webjars/**"
            //匹配swagger路徑(默認(rèn))
            , "/swagger-ui.html"
            , "/swagger-ui/index.html"
            , "/v3/api-docs/**"
            , "/swagger-ui/**"
            //監(jiān)控檢測(cè)
            , "/actuator/**"
    };
    @Bean
    public WebSecurityCustomizer ignoringCustomize(){
        return (web) -> web.ignoring()
                .requestMatchers(permitUrlArr);
    }
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        //初始化jwt過(guò)濾器,并設(shè)置jwt公鑰
        var jwtTokenFilter = new JwtTokenFilter();
        //Security6.x關(guān)閉默認(rèn)登錄頁(yè)
        httpSecurity.removeConfigurers(DefaultLoginPageConfigurer.class);
        logger.info("注冊(cè)JWT認(rèn)證SecurityFilterChain");
        var chain = httpSecurity
                // 自定義權(quán)限攔截規(guī)則
                .authorizeHttpRequests((requests) -> {
                    //requests.anyRequest().permitAll(); //放行所有請(qǐng)求!!!
                    //允許匿名訪問(wèn)
                    requests
                            //自定可匿名訪問(wèn)地址,放到permitAllUrl中即可
                            .requestMatchers(permitUrlArr).permitAll()
                            //除上面聲明的可匿名訪問(wèn)地址,其它所有請(qǐng)求全部需要進(jìn)行認(rèn)證
                            .anyRequest()
                            .authenticated();
                })
                // 禁用HTTP響應(yīng)標(biāo)頭
                .headers(headersCustomizer -> {headersCustomizer
                            .cacheControl(cache -> cache.disable())
                            .frameOptions(options -> options.sameOrigin());})
                //會(huì)話(huà)設(shè)為無(wú)狀態(tài),基于token,所以不需要session
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                //添加自定義的JWT認(rèn)證篩選器,驗(yàn)證header中jwt有效性,將插入到UsernamePasswordAuthenticationFilter之前 
                .addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class)
                //禁用表單登錄
                .formLogin(formLogin -> formLogin.disable())
                //禁用httpBasic登錄
                .httpBasic(httpBasic -> httpBasic.disable())
                //禁用rememberMe
                .rememberMe(rememberMe -> rememberMe.disable())
                // 禁用CSRF,因?yàn)椴皇褂胹ession
                .csrf(csrf -> csrf.disable())
                //允許跨域請(qǐng)求
                .cors(Customizer.withDefaults())
                .build();
        return chain;
    }
    @Bean
    public FilterRegistrationBean disableSpringBootErrorFilter(ErrorPageFilter filter){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(filter);
        filterRegistrationBean.setEnabled(false);
        return filterRegistrationBean;
    }
}

總結(jié)

以上支持介紹了對(duì)于已有JWT統(tǒng)一認(rèn)證系統(tǒng)的接入(JWT解析和認(rèn)證),不涉及JWT生成和管理相關(guān)內(nèi)容。

目前的用戶(hù)信息是基于JWT動(dòng)態(tài)解析的,所以暫時(shí)沒(méi)有基于AbstractAuthenticationToken在Security上下文中存放用戶(hù)信息,JwtAuthenticationToken已經(jīng)支持自定義用戶(hù)信息的存儲(chǔ),只需要按需傳入即可?;赟ecurity上下文獲取用戶(hù)信息使用SecurityContextHolder.getContext().getAuthentication().getPrincipal();方法。

到此這篇關(guān)于SpringBoot3.x接入Security6.x實(shí)現(xiàn)JWT認(rèn)證的文章就介紹到這了,更多相關(guān)SpringBoot3接入Security6.x實(shí)現(xiàn)JWT認(rèn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何把本地idea上的項(xiàng)目上傳到github上(推薦)

    如何把本地idea上的項(xiàng)目上傳到github上(推薦)

    這篇文章主要介紹了如何把本地idea上的項(xiàng)目上傳到github上,本文通過(guò)圖文的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Spring Batch批處理框架使用解析

    Spring Batch批處理框架使用解析

    這篇文章主要介紹了Spring Batch批處理框架使用解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • SpringMVC?中的視圖使用?JSP的過(guò)程

    SpringMVC?中的視圖使用?JSP的過(guò)程

    本文介紹了如何在?SpringMVC?中使用?JSP?視圖,包括如何創(chuàng)建?JSP?視圖、配置?JSP?視圖解析器、以及如何在控制器方法中使用JSP視圖,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-07-07
  • mybatis-plus @DS實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源原理

    mybatis-plus @DS實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源原理

    本文主要介紹了mybatis-plus @DS實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • java基于AspectJ(面向切面編程)編碼示例分享

    java基于AspectJ(面向切面編程)編碼示例分享

    AspectJ是一種面向切面程序設(shè)計(jì)的基于Java的實(shí)現(xiàn),下面對(duì)過(guò)示例學(xué)習(xí)他的使用方法,需要的朋友可以參考下
    2014-02-02
  • 使用Java實(shí)現(xiàn)一個(gè)能保留計(jì)算過(guò)程的計(jì)算器

    使用Java實(shí)現(xiàn)一個(gè)能保留計(jì)算過(guò)程的計(jì)算器

    計(jì)算器是我們?nèi)粘I钪谐S玫墓ぞ咧?它能夠進(jìn)行基本的數(shù)學(xué)運(yùn)算,如加法、減法、乘法和除法,而在設(shè)計(jì)一個(gè)計(jì)算器時(shí),我們可以通過(guò)使用Java編程語(yǔ)言來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的控制臺(tái)計(jì)算器,并且讓它能夠保留計(jì)算過(guò)程,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-11-11
  • java中的i++和++i的區(qū)別詳解

    java中的i++和++i的區(qū)別詳解

    這篇文章主要介紹了java中的i++和++i的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • servlet Cookie使用方法詳解(六)

    servlet Cookie使用方法詳解(六)

    這篇文章主要為大家詳細(xì)介紹了servlet Cookie的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • 詳解Java中自定義注解的使用

    詳解Java中自定義注解的使用

    Annontation是Java5開(kāi)始引入的新特征,中文名稱(chēng)叫注解,它提供了一種安全的類(lèi)似注釋的機(jī)制,用來(lái)將任何的信息或元數(shù)據(jù)(metadata)與程序元素(類(lèi)、方法、成員變量等)進(jìn)行關(guān)聯(lián)。本文主要介紹了自定義注解的使用,希望對(duì)大家有所幫助
    2023-03-03
  • SpringCloudGateway 網(wǎng)關(guān)登錄校驗(yàn)實(shí)現(xiàn)思路

    SpringCloudGateway 網(wǎng)關(guān)登錄校驗(yàn)實(shí)現(xiàn)思路

    文章介紹了在微服務(wù)架構(gòu)中使用Spring Cloud Gateway進(jìn)行登錄校驗(yàn)的方法,通過(guò)在網(wǎng)關(guān)層面進(jìn)行登錄校驗(yàn),并將用戶(hù)信息通過(guò)請(qǐng)求頭傳遞給下游微服務(wù),解決了每個(gè)微服務(wù)都需要獨(dú)立進(jìn)行登錄校驗(yàn)的問(wèn)題,此外,還討論了如何在微服務(wù)之間傳遞用戶(hù)信息
    2024-11-11

最新評(píng)論