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

SpringCloud實(shí)現(xiàn)權(quán)限管理(網(wǎng)關(guān)+jwt版)

 更新時(shí)間:2025年10月31日 09:37:04   作者:一介輸生  
本文主要介紹了SpringCloud實(shí)現(xiàn)權(quán)限管理(網(wǎng)關(guān)+jwt版),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

首先要想一個(gè)問(wèn)題:為什么微服務(wù)不能像普通的Spring Boot項(xiàng)目一樣鑒權(quán)?其實(shí)并不是不能,而是不適合。 在微服務(wù)架構(gòu)中使用 Spring Security + RBAC/JET 時(shí),會(huì)面臨 "重復(fù)鑒權(quán)" 的核心痛點(diǎn)。下面從技術(shù)原理到解決方案完整解析這個(gè)問(wèn)題。

問(wèn)題本質(zhì):為什么會(huì)有重復(fù)鑒權(quán)?

傳統(tǒng)單體架構(gòu)流程

所有權(quán)限校驗(yàn)集中在一個(gè)應(yīng)用內(nèi)完成 • 用戶登錄后,Session或Token在單應(yīng)用中全局有效

微服務(wù)架構(gòu)下的流程

每個(gè)微服務(wù)都需要獨(dú)立完成:

  1. 解析Token
  2. 查詢數(shù)據(jù)庫(kù)驗(yàn)證權(quán)限
  3. 構(gòu)建SecurityContext

假設(shè)有3個(gè)服務(wù)鏈?zhǔn)秸{(diào)用:

客戶端 → 網(wǎng)關(guān) → 服務(wù)A → 服務(wù)B → 服務(wù)C 每個(gè)服務(wù)都重復(fù): 查詢用戶數(shù)據(jù)(1次DB查詢) 查詢權(quán)限數(shù)據(jù)(1次DB查詢) ??總查詢次數(shù) = 3服務(wù) × 2查詢 = 6次? • 在服務(wù)交叉的時(shí)候,導(dǎo)致 多次數(shù)據(jù)庫(kù)查詢重復(fù)計(jì)算,使數(shù)據(jù)庫(kù)壓力倍增和網(wǎng)絡(luò)開銷疊加。

(1)創(chuàng)建 JWT 工具類

在util模塊下創(chuàng)建JWT 工具類

@Component
public class JwtTokenUtil {
    // 密鑰,用于簽名和驗(yàn)證 JWT,應(yīng)妥善保管
    @Value("${jwt.secret}")
    private String secret;
    // JWT 的過(guò)期時(shí)間,這里設(shè)置為 10 小時(shí)
    @Value("${jwt.expiration}")
    private Long expiration;

    // 根據(jù)用戶詳細(xì)信息生成 JWT
    public String generateToken(SysRoleNameUserId sysRoleNameUserId) {
        //自定義的聲明
        Map<String, Object> claims = new HashMap<>();
        //鑒權(quán)所需的權(quán)限角色
        claims.put("identities",sysRoleNameUserId.getRoleNames());
        return createToken(claims, String.valueOf(sysRoleNameUserId.getUserId()));
    }

    // 創(chuàng)建 JWT 的具體方法
    private String createToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .setClaims(claims)//自定義的聲明
                .setSubject(subject)//存的用戶id
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();
    }

    //解析jwt
    public Claims extractAllClaims(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(secret)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }
}

JWT 的密鑰(jwt.secret)應(yīng)通過(guò)配置中心(如 Nacos)或環(huán)境變量注入,避免硬編碼。這里選擇環(huán)境變量注入: 在util模塊下的application.yml配置文件里面指定

jwt:
  secret: your-secret-key-here-must-be-at-least-256-bits-long
  expiration: 1000 * 60 * 60 * 10 # 10 hour

(2)創(chuàng)建JwtFilter

在gateway網(wǎng)關(guān)模塊創(chuàng)建JwtFilter過(guò)濾器來(lái)驗(yàn)證并解析jwt,從而獲取權(quán)限信息

@Component
public class JwtFilter implements GlobalFilter, Ordered {

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        List<String> authHeader = headers.get("Authorization");
        if (authHeader != null && authHeader.get(0).startsWith("Bearer ")) {
            String token = authHeader.get(0).substring(7);
            // 驗(yàn)證 JWT 并提取角色信息
            Claims claims = null;
            try{
                claims = jwtTokenUtil.extractAllClaims(token);
            }catch (IllegalArgumentException e) {
                //解析 JWT 時(shí)發(fā)生其他錯(cuò)誤
                System.out.println("解析 token 時(shí)發(fā)生其他錯(cuò)誤");
            } catch (ExpiredJwtException e) {
                //JWT 已過(guò)期
                System.out.println("token 已過(guò)期");
            }
            //取出權(quán)限角色列表
            Object identitiesObj = claims.get("identities");
            List<GrantedAuthority> authorities = new ArrayList<>();
            if (identitiesObj instanceof List<?>) {
                for (Object role : (List<?>) identitiesObj) {
                    if (role instanceof String) {
                        // 將字符串轉(zhuǎn)換為 SimpleGrantedAuthority
                        authorities.add(new SimpleGrantedAuthority((String) role));
                    }
                }
            }
            String userId = claims.getSubject();
            //將 Authentication 對(duì)象設(shè)置到 SecurityContextHolder 中后,Spring Security 就能在后續(xù)的授權(quán)過(guò)程中使用這些權(quán)限信息了。
            Authentication authentication = new UsernamePasswordAuthenticationToken(userId, null, authorities);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

(3)配置 Spring Security

在網(wǎng)關(guān)gateway模塊配置所有微服務(wù)整體的權(quán)限管理規(guī)則:

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http.csrf().disable()// 關(guān)閉 CSRF(跨站請(qǐng)求偽造)防護(hù)。在無(wú)狀態(tài) API(如 JWT 場(chǎng)景)中,CSRF 防護(hù)不必要(通常依賴 Authorization 頭而非 Cookie)。 避免對(duì) POST、PUT 等請(qǐng)求要求攜帶 CSRF Token。
                .authorizeExchange()
                .pathMatchers("/api/product/**").permitAll()
                .pathMatchers("/admin/**").permitAll()
                .anyExchange().authenticated();
        return http.build();
    }
}

如果各個(gè)微服務(wù)還需要獨(dú)自的更細(xì)粒度的權(quán)限控制,只需要在單個(gè)微服務(wù)模塊中單獨(dú)配置一個(gè)Spring Security就行了。

到此這篇關(guān)于SpringCloud實(shí)現(xiàn)權(quán)限管理(網(wǎng)關(guān)+jwt版)的文章就介紹到這了,更多相關(guān)SpringCloud 權(quán)限管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java報(bào)錯(cuò):java.lang.UnsatisfiedLinkError問(wèn)題的解決辦法

    Java報(bào)錯(cuò):java.lang.UnsatisfiedLinkError問(wèn)題的解決辦法

    在Java開發(fā)中,java.lang.UnsatisfiedLinkError是一種與本地方法調(diào)用相關(guān)的常見異常,本文將詳細(xì)分析這一異常的背景、可能的原因、錯(cuò)誤代碼示例、正確代碼示例,以及編寫代碼時(shí)需要注意的事項(xiàng),需要的朋友可以參考下
    2024-09-09
  • SpringBoot 多數(shù)據(jù)源及事務(wù)解決方案小結(jié)

    SpringBoot 多數(shù)據(jù)源及事務(wù)解決方案小結(jié)

    本文主要介紹了多數(shù)據(jù)源管理的解決方案(應(yīng)用層事務(wù),而非XA二段提交保證),以及對(duì)多個(gè)庫(kù)同時(shí)操作的事務(wù)管理,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • Java將文件上傳到ftp服務(wù)器

    Java將文件上傳到ftp服務(wù)器

    這篇文章主要為大家詳細(xì)介紹了Java將文件上傳到ftp服務(wù)器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • java中struts2實(shí)現(xiàn)文件上傳下載功能

    java中struts2實(shí)現(xiàn)文件上傳下載功能

    這篇文章主要介紹了java中struts2實(shí)現(xiàn)文件上傳下載功能的方法,以實(shí)例形式分析了struts2文件上傳下載功能的實(shí)現(xiàn)技巧與相關(guān)問(wèn)題,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2016-05-05
  • java @Data布爾值boolean的坑及解決

    java @Data布爾值boolean的坑及解決

    本文介紹了在使用Spring框架時(shí),遇到的一個(gè)屬性命名規(guī)則問(wèn)題,在Spring框架中,如果類的屬性名稱第一個(gè)字母小寫,第二個(gè)字母大寫,那么在調(diào)用set方法時(shí),Spring會(huì)將屬性的后面的字母轉(zhuǎn)換為小寫,這種情況下,如果下游消費(fèi)端調(diào)用得到的返回json串
    2024-10-10
  • Java實(shí)現(xiàn)Linux下雙守護(hù)進(jìn)程

    Java實(shí)現(xiàn)Linux下雙守護(hù)進(jìn)程

    這篇文章主要介紹了Java實(shí)現(xiàn)Linux下雙守護(hù)進(jìn)程的思路、原理以及具體實(shí)現(xiàn)方式,非常的詳細(xì),希望對(duì)大家有所幫助
    2014-10-10
  • Java設(shè)計(jì)模式之觀察者模式解析

    Java設(shè)計(jì)模式之觀察者模式解析

    這篇文章主要介紹了Java設(shè)計(jì)模式之觀察者模式解析,觀察者模式,又被稱為發(fā)布/訂閱模式,它定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象,這個(gè)主題對(duì)象在狀態(tài)變化時(shí),會(huì)通知所有的觀察者對(duì)象,使他們能夠自動(dòng)更新自己,需要的朋友可以參考下
    2023-09-09
  • Java Class 加密工具 ClassFinal詳解

    Java Class 加密工具 ClassFinal詳解

    ClassFinal 是一款 java class 文件安全加密工具,支持直接加密jar包或war包,無(wú)需修改任何項(xiàng)目代碼,兼容spring-framework;可避免源碼泄漏或字節(jié)碼被反編譯,這篇文章主要介紹了Java Class 加密工具 ClassFinal,需要的朋友可以參考下
    2023-03-03
  • 如何利用Java獲取當(dāng)天的開始和結(jié)束時(shí)間

    如何利用Java獲取當(dāng)天的開始和結(jié)束時(shí)間

    這篇文章主要介紹了如何使用Java?8的LocalDate和LocalDateTime類獲取指定日期的開始和結(jié)束時(shí)間,展示了如何通過(guò)這些類進(jìn)行日期和時(shí)間的處理,從而簡(jiǎn)化了日期時(shí)間操作,需要的朋友可以參考下
    2025-02-02
  • Java線程隊(duì)列LinkedBlockingQueue的使用

    Java線程隊(duì)列LinkedBlockingQueue的使用

    本文主要介紹了Java線程隊(duì)列LinkedBlockingQueue的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評(píng)論