SpringCloud Gateway 权限认证的实现

2025-05-14 11:46:04 145
魁首哥

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

一、添加依赖

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


    
    
        org.springframework.cloud
        spring-cloud-starter-gateway
    

    
    
        org.springframework.boot
        spring-boot-starter-security
    

    
    
        io.jsonwebtoken
        jjwt-api
        0.11.5
    
    
        io.jsonwebtoken
        jjwt-impl
        0.11.5
        runtime
    
    
        io.jsonwebtoken
        jjwt-jackson
        0.11.5
        runtime
    

二、配置 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 extractusername(string token) {
        return mono.just(extractclaim(token, claims::getsubject));
    }

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

    public  t extractclaim(string token, function 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 generatetoken(userdetails userdetails) {
        map claims = new hashmap<>();
        return mono.just(createtoken(claims, userdetails.getusername()));
    }

    private string createtoken(map 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 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 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 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 权限认证内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

分享
海报
145
上一篇:Java警告:原发性版11需要目标发行版11的解决方法和步骤 下一篇:SpringBoot集成Milvus实现数据增删改查功能

忘记密码?

图形验证码