在微服务架构中,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 monoextractusername(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 monoauthenticate(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 monoconvert(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