最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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ò)開(kāi)銷(xiāo)疊加。

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

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

@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)文章

  • idea撤銷(xiāo)git?commit操作詳解

    idea撤銷(xiāo)git?commit操作詳解

    這篇文章主要為大家介紹了idea撤銷(xiāo)git?commit操作詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • java開(kāi)發(fā)中為什么雙重效驗(yàn)鎖要加volatile

    java開(kāi)發(fā)中為什么雙重效驗(yàn)鎖要加volatile

    這篇文章主要為大家介紹了java開(kāi)發(fā)中為什么雙重效驗(yàn)鎖要加volatile原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Java使用JCommander實(shí)現(xiàn)解析命令行參數(shù)

    Java使用JCommander實(shí)現(xiàn)解析命令行參數(shù)

    jcommander?是一個(gè)只有幾十?kb?的?Java?命令行參數(shù)解析工具,可以通過(guò)注解的方式快速實(shí)現(xiàn)命令行參數(shù)解析,本文就來(lái)和大家介紹一下JCommander是如何解析命令行參數(shù)吧
    2023-06-06
  • Java獲得元素屬性的注解信息的步驟

    Java獲得元素屬性的注解信息的步驟

    在Java編程中,注解是一種為代碼添加元數(shù)據(jù)的方式,通過(guò)反射機(jī)制,我們可以獲取元素屬性上的注解信息,這個(gè)過(guò)程對(duì)于框架開(kāi)發(fā)和元數(shù)據(jù)處理非常有用,能夠?qū)崿F(xiàn)更靈活的功能,對(duì)java獲得元素屬性的注解信息相關(guān)知識(shí)感興趣的朋友一起看看吧
    2024-09-09
  • java使用Runtime執(zhí)行系統(tǒng)命令遇到的問(wèn)題

    java使用Runtime執(zhí)行系統(tǒng)命令遇到的問(wèn)題

    這篇文章主要介紹了java使用Runtime執(zhí)行系統(tǒng)命令遇到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java匿名內(nèi)部類(lèi)實(shí)例代碼詳解

    java匿名內(nèi)部類(lèi)實(shí)例代碼詳解

    這篇文章主要介紹了java匿名內(nèi)部類(lèi)實(shí)例代碼詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 排序算法圖解之Java歸并排序的實(shí)現(xiàn)

    排序算法圖解之Java歸并排序的實(shí)現(xiàn)

    歸并排序是建立在歸并操作上的一種有效,穩(wěn)定的排序算法,該算法是采用分治法(Divide?and?Conquer)的一個(gè)非常典型的應(yīng)用。本文主要介紹了歸并排序的實(shí)現(xiàn),需要的可以參考一下
    2022-11-11
  • Java如何通過(guò)反射取實(shí)體類(lèi)字段取值

    Java如何通過(guò)反射取實(shí)體類(lèi)字段取值

    這篇文章主要介紹了Java如何通過(guò)反射取實(shí)體類(lèi)字段取值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 掌握SpringMVC中@InitBinder的實(shí)際應(yīng)用

    掌握SpringMVC中@InitBinder的實(shí)際應(yīng)用

    這篇文章主要介紹了掌握SpringMVC中@InitBinder的實(shí)際應(yīng)用,@InitBinder是Spring MVC框架中的一個(gè)注解,用于自定義數(shù)據(jù)綁定的方法,通過(guò)在控制器中使用@InitBinder注解,可以將特定的數(shù)據(jù)綁定邏輯應(yīng)用于請(qǐng)求參數(shù)的處理過(guò)程中,需要的朋友可以參考下
    2023-10-10
  • SpringMVC如何獲取多種類(lèi)型數(shù)據(jù)響應(yīng)

    SpringMVC如何獲取多種類(lèi)型數(shù)據(jù)響應(yīng)

    這篇文章主要介紹了SpringMVC如何獲取多種類(lèi)型數(shù)據(jù)響應(yīng),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11

最新評(píng)論

温宿县| 张家港市| 安岳县| 鹤峰县| 西华县| 揭东县| 阳春市| 东乡县| 甘肃省| 苏尼特左旗| 板桥市| 弥渡县| 汾西县| 理塘县| 阜城县| 福贡县| 奉贤区| 神池县| 英德市| 会同县| 永泰县| 荆门市| 来安县| 谢通门县| 得荣县| 中西区| 涪陵区| 会宁县| 水城县| 汪清县| 古田县| 寿光市| 江陵县| 十堰市| 龙口市| 崇阳县| 高安市| 河北区| 信阳市| 营山县| 从化市|