Spring Cloud Gateway——(三)微服务网关实现JWT鉴权
2020-01-11 18:09
1501 查看
Spring Cloud Gateway——(三)微服务网关实现JWT鉴权
1. JWT 实现微服务鉴权
1.1 什么是JWT?
JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。
-
JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。
头部(Header)
头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。
-
载荷(playload)
载荷就是存放有效信息的地方
-
签证(signature)
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
1.2 JJWT签发与验证token
JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解。它被设计成一个以建筑为中心的流畅界面,隐藏了它的大部分复杂性。
官方文档:https://github.com/jwtk/jjwt
1.3 JJWT快速入门
-
在项目中添加依赖
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency>
-
创建测试类生成token
JwtBuilder builder= Jwts.builder() .setId("007") //设置唯一编号 .setSubject("小马")//设置主题 可以是JSON数据 .setIssuedAt(new Date())//设置签发日期 .setExpiration(new Date(System.currentTimeMillis()+3600))//设置过期时间 .signWith(SignatureAlgorithm.HS256,"xm");//设置签名 使用HS256算法,并设置SecretKey(字符串) //构建 并返回一个字符串 System.out.println( builder.compact() );
-
解析token
String compactJwt="eyJhbGciOiJIUzI1NiJ9.eyJqdGk...之前生成的token..."; Claims claims =Jwts.parser() .setSigningKey("xm") .parseClaimsJws(compactJwt) .getBody(); System.out.println(claims);
1.4 在微服务中实现jjwt鉴权
(1)在网关服务和用户登录服务中添加依赖依赖
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency>
(2)在服务中创建类: JwtUtil 用于jjwt token生成和解析
package com.xm.system.util; import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; import java.util.Date; /** * @title: JwtUtil JWT工具类 * @projectName: * @description: TODO * @author: Zack_Tzh * @date: 2019/12/10 9:31 */ public class JwtUtil { /** * 设置有效期为 60 * 60 秒 */ private static final Long JWT_TTL = 3600000L; /** * 设置秘钥明文 */ private static final String JWT_KEY= "NVIDIA"; /** * 创建toke * @param id * @param subject * @param ttlMillis * @return */ public static String createJWT(String id,String subject,Long ttlMillis){ SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); if(ttlMillis==null){ ttlMillis=JwtUtil.JWT_TTL; } long expMillis = nowMillis + ttlMillis; Date expDate = new Date(expMillis); SecretKey secretKey = generalKey(); JwtBuilder builder = Jwts.builder() //唯一的ID .setId(id) // 主题 可以是JSON数据 .setSubject(subject) // 签发者 .setIssuer("admin") // 签发时间 .setIssuedAt(now) //使用HS256对称加密算法签名, 第二个参数为秘钥 .signWith(signatureAlgorithm, secretKey) // 设置过期时间 .setExpiration(expDate); return builder.compact(); } /** * 解析JWT * @param compactJwt * @return * @throws Exception */ public static Claims parseJWT(String compactJwt) throws Exception { SecretKey secretKey = generalKey(); return Jwts.parser().setSigningKey(secretKey).parseClaimsJws( compactJwt).getBody(); } /** * 生成加密后的秘钥 secretKey * @return */ public static SecretKey generalKey() { byte[] encodedKey = Base64.getEncoder().encode(JwtUtil.JWT_KEY.getBytes()); SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES"); return key; } }
(3)在用户登录的login方法时,用户登录成功 则 签发TOKEN
/** * 登录 * @param admin * @return */ @PostMapping("/login") public Result login(@RequestBody Admin admin){ boolean result = adminService.login(admin);//验证密码是否正确 if (result){ //密码是正确的 //生成jwt令牌,返回到客户端 Map<String,String> info = new HashMap<>(); info.put("username",admin.getLoginName()); //基于工具类生成jwt令牌 String jwt = JwtUtil.createJWT(UUID.randomUUID().toString(), admin.getLoginName(), null); info.put("token",jwt); return new Result(true, StatusCodeEnum.OK,info); }else{ //密码错误 return new Result(false, StatusCodeEnum.ERROR); } }
(3)在网关创建过滤器,用于token验证
package com.xm.system.filter; import com.xm.system.util.JwtUtil; import org.apache.commons.lang.StringUtils; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * @title: AuthorizeFilter * @projectName: xm * @description: TODO * @author: Zack_Tzh * @date: 2019/12/10 14:46 */ @Component public class AuthorizeFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //1. 获取请求 ServerHttpRequest request = exchange.getRequest(); //2. 则获取响应 ServerHttpResponse response = exchange.getResponse(); //3. 如果是登录请求则放行 if (request.getURI().getPath().contains("/admin/login")) { return chain.filter(exchange); } //4. 获取请求头 HttpHeaders headers = request.getHeaders(); //5. 请求头中获取令牌 String token = headers.getFirst("token"); //6. 判断请求头中是否有令牌 if (StringUtils.isEmpty(token)) { //7. 响应中放入返回的状态吗, 没有权限访问 response.setStatusCode(HttpStatus.UNAUTHORIZED); //8. 返回 return response.setComplete(); } //9. 如果请求头中有令牌则解析令牌 try { JwtUtil.parseJWT(token); } catch (Exception e) { e.printStackTrace(); //10. 解析jwt令牌出错, 说明令牌过期或者伪造等不合法情况出现 response.setStatusCode(HttpStatus.UNAUTHORIZED); //11. 返回 return response.setComplete(); } //12. 放行 return chain.filter(exchange); } @Override public int getOrder() { return 0; } }
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 【MS】springcloud-gateway 中实现服务之间鉴权,只能从网关访问,禁止直接访问服务
- Spring Cloud Gateway 服务网关快速实现解析
- SpringCloud之网关服务(gateway)
- Spring Cloud微服务中网关服务是如何实现的?(Zuul篇)
- Spring Cloud 服务网关Zuul的实现
- Springcloud_ad-gateway微服务网关(zuul)方式restAPI,以及zuul网关配置
- springboot+spring cloud实现简单的gateway注册服务
- Spring Cloud与微服务学习总结(3)——认证鉴权与API权限控制在微服务架构中的设计与实现(一)
- Spring Cloud微服务中网关服务是如何实现的?(Zuul篇)
- spring cloud 使用Zuul 实现API网关服务问题
- Spring Cloud与微服务学习总结(5)——认证鉴权与API权限控制在微服务架构中的设计与实现(三)
- SpringCloud之网关服务(gateway)
- 微服务网关实战——Spring Cloud Gateway
- Spring Cloud与微服务学习总结(4)——认证鉴权与API权限控制在微服务架构中的设计与实现(二)
- 基于Spring cloud gateway定制的微服务网关
- SpringCloud系列:利用Zuul实现统一服务网关服务,简单实现IP白名单功能
- Spring Cloud 系列之 Spring cloud gateway 实现网关路由转发和过滤功能
- SpringCloud微服务(05):Zuul组件,实现路由网关控制
- spring cloud jwt用户鉴权及服务鉴权
- spring Cloud Gateway + JWT 实现统一的认证授权