当前位置: 代码网 > it编程>编程语言>Java > SpringCloud Gateway 权限认证的实现

SpringCloud Gateway 权限认证的实现

2025年04月16日 Java 我要评论
在微服务架构中,spring cloud gateway 作为网关层,承担着请求转发、权限校验等重要职责。通过集成 spring security 和 jwt(json web token),可以在网

在微服务架构中,spring cloud gateway 作为网关层,承担着请求转发、权限校验等重要职责。通过集成 spring security 和 jwt(json web token),可以在网关层实现集中式的权限认证,确保系统的安全性和数据保护。以下是详细的实现步骤:

一、添加依赖

在 spring boot 项目中,添加 spring cloud gateway、spring security 和 jwt 相关依赖。以下是 pom.xml 的配置示例:

<dependencies>
    <!-- spring cloud gateway -->
    <dependency>
        <groupid>org.springframework.cloud</groupid>
        <artifactid>spring-cloud-starter-gateway</artifactid>
    </dependency>

    <!-- spring security -->
    <dependency>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-security</artifactid>
    </dependency>

    <!-- jwt support -->
    <dependency>
        <groupid>io.jsonwebtoken</groupid>
        <artifactid>jjwt-api</artifactid>
        <version>0.11.5</version>
    </dependency>
    <dependency>
        <groupid>io.jsonwebtoken</groupid>
        <artifactid>jjwt-impl</artifactid>
        <version>0.11.5</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupid>io.jsonwebtoken</groupid>
        <artifactid>jjwt-jackson</artifactid>
        <version>0.11.5</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>

二、配置 spring security

在 spring cloud gateway 中,使用 spring security 的 webflux 模块来实现权限校验。以下是一个典型的配置类:

@configuration
@enablewebfluxsecurity
public class securityconfig {

    @bean
    public securitywebfilterchain securitywebfilterchain(serverhttpsecurity http, jwtauthenticationmanager jwtauthenticationmanager) {
        http
            .csrf().disable() // 禁用 csrf 保护
            .authorizeexchange(exchanges -> exchanges
                .pathmatchers("/login", "/register").permitall() // 公开登录和注册接口
                .anyexchange().authenticated()) // 其他请求需要认证
            .addfilterat(jwtauthenticationfilter(jwtauthenticationmanager), securitywebfilterchain.class);

        return http.build();
    }

    private authenticationwebfilter jwtauthenticationfilter(jwtauthenticationmanager jwtauthenticationmanager) {
        authenticationwebfilter filter = new authenticationwebfilter(jwtauthenticationmanager);
        filter.setserverauthenticationconverter(new bearertokenserverauthenticationconverter());
        return filter;
    }
}

三、实现 jwt 工具类

jwt 工具类用于生成和解析 jwt 令牌。以下是工具类的实现:

@component
public class jwtutil {
    private string secret = "yoursecretkey"; // 密钥应存储在安全的地方,避免硬编码

    public mono<string> extractusername(string token) {
        return mono.just(extractclaim(token, claims::getsubject));
    }

    public date extractexpiration(string token) {
        return extractclaim(token, claims::getexpiration);
    }

    public <t> t extractclaim(string token, function<claims, t> claimsresolver) {
        final claims claims = extractallclaims(token);
        return claimsresolver.apply(claims);
    }

    private claims extractallclaims(string token) {
        return jwts.parser().setsigningkey(secret).parseclaimsjws(token).getbody();
    }

    public mono<string> generatetoken(userdetails userdetails) {
        map<string, object> claims = new hashmap<>();
        return mono.just(createtoken(claims, userdetails.getusername()));
    }

    private string createtoken(map<string, object> claims, string subject) {
        return jwts.builder()
                .setclaims(claims)
                .setsubject(subject)
                .setissuedat(new date(system.currenttimemillis()))
                .setexpiration(new date(system.currenttimemillis() + 1000 * 60 * 60 * 10)) // 10小时过期
                .signwith(signaturealgorithm.hs256, secret)
                .compact();
    }

    public mono<boolean> validatetoken(string token, userdetails userdetails) {
        final string username = extractusername(token).block();
        return mono.just(username.equals(userdetails.getusername()) && !istokenexpired(token));
    }

    private boolean istokenexpired(string token) {
        return extractexpiration(token).before(new date());
    }
}

四、实现 jwt 认证管理器

jwt 认证管理器用于处理 jwt 的验证逻辑:

@component
public class jwtauthenticationmanager implements reactiveauthenticationmanager {
    private final jwtutil jwtutil;
    private final userdetailsservice userdetailsservice;

    public jwtauthenticationmanager(jwtutil jwtutil, userdetailsservice userdetailsservice) {
        this.jwtutil = jwtutil;
        this.userdetailsservice = userdetailsservice;
    }

    @override
    public mono<authentication> authenticate(authentication authentication) {
        string token = (string) authentication.getcredentials();
        return jwtutil.extractusername(token)
                .flatmap(username -> {
                    if (jwtutil.validatetoken(token, userdetailsservice.loaduserbyusername(username)).block()) {
                        userdetails userdetails = userdetailsservice.loaduserbyusername(username);
                        return mono.just(new usernamepasswordauthenticationtoken(userdetails, token, userdetails.getauthorities()));
                    } else {
                        return mono.empty();
                    }
                });
    }
}

五、实现 bearer token 转换器

bearer token 转换器用于从请求头中提取 jwt 令牌:

public class bearertokenserverauthenticationconverter implements serverauthenticationconverter {
    @override
    public mono<authentication> convert(serverwebexchange exchange) {
        string authheader = exchange.getrequest().getheaders().getfirst("authorization");
        if (authheader != null && authheader.startswith("bearer ")) {
            string token = authheader.substring(7);
            return mono.just(new bearertokenauthentication(token));
        }
        return mono.empty();
    }
}

六、配置 gateway 路由

在 application.yml 文件中配置路由规则:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - path=/users/**
          filters:
            - jwtauthenticationfilter

七、总结

到此这篇关于springcloud gateway 权限认证的实现的文章就介绍到这了,更多相关springcloud gateway 权限认证内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

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

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com