您当前的位置: 首页 >  微服务

墨家巨子@俏如来

暂无认证

  • 1浏览

    0关注

    188博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

九.SpringCloud+Security+Oauth2实现微服务授权 - Oauth2&JWT的认识

墨家巨子@俏如来 发布时间:2020-10-24 15:16:14 ,浏览量:1

前言

我们的授权方案是 SpringCloud + Security + Oauth2 + JWT 为了方便后面做认证授权先来普及两个概念Oauth2和JWT

Oauth2部分 1.JWT概述 1.1.什么是JWT

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

JWT 以 JSON 对象的形式安全传递信息。因为存在数字签名,因此所传递的信息是安全的。客户端身份经过服务器验证通过后,会生成带有签名的 JSON 对象并将它返回给客户端。客户端在收到这个 JSON 对象后存储起来。

在以后的请求中客户端将 JSON 对象连同请求内容一起发送给服务器,服务器收到请求后通过 JSON 对象标识用户,如果验证不通过则不返回请求的数据。

总结:使用JWT生产的Token是安全的,它实现了数据的安全传输,并且Token中可以携带认证信息,做到真正的无状态,是“客户端Token”模式授权方案的不二选择

1.2.JWT特点
  • 基于JSON,方便解析
  • 可以在令牌中定义内容,方便扩展
  • 非对称加密算法即数字签名,JWT防篡改
  • Token携带认证信息,无效访问认证服务器即可完成权限校验,做到“无状态”
1.3.JWT组成

JWT包含三部分组成

  1. 头部 (header): JSON格式,描述JWT的最基本的信息,如签名算法等效果如下:{"typ":"JWT","alg":"HS256"} 这里指明了签名算法是HS256算法。在使用过程中会对该 JSON进行BASE64编码如:yJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

  2. 载荷(playload) : JSON格式,包含了需要的数据内容,也需要BASE64编码。包含三部分 标准中注册的声明(建议但不强制使用)

    iss: jwt签发者
    sub: jwt所面向的用户
    aud: 接收jwt的一方
    exp: jwt的过期时间,这个过期时间必须要大于签发时间
    nbf: 定义在什么时间之前,该jwt都是不可用的.
    iat: jwt的签发时间
    jti: jwt的唯一身份标识,主要用来作为一次性token。
    

    公共的声明 :公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

    私有的声明 :私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。 定义一个payload: 如 {"sub":"1234","name":"xxx","admin":true} 进行Base64编码后得到JWT第二部分如 eyJzdWIiOiIxMjM0NTY3ODkbmFtZSI6IkpvaG4gRG9lIiwiYW...

  3. 签名 (signature): 通过指定的算法生成哈希,以确保数据不会被篡改。jwt的第三部分是一个签证信息,通过指定的算法生成哈希,以确保数据不会被篡改,这个签证信息由三部分组成:head(base64编码后的);playload(base64编码后的);secret(秘钥)签名后的密文构成JWT第三部分如:ThecMfgYjtoys3JX7dpx3hu6pUm0piZ0tXXr最后JWT构建的内容编码后的字符串

    eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NTc5MDQxODF9.ThecMfgYjtoys3JX7dpx3hu6pUm0piZ0tXXreFU_u3Y
    
2.JWT初探 2.1.创建JWT令牌

首先我们来加入JWT的依赖


 io.jsonwebtoken
 jwt
 0.9.0

令牌的签发

//系统时间
long now=System.currentTimeMillis();
//计算过期时间30秒过期
long exp=now+1000*30;
//使用Jwts签发令牌
JwtBuilder jwtBuilder = Jwts.builder().setId( "111" )	//设置唯一编号
 .setSubject( "zs" )	//主题,可以扔一个JSON
 .setIssuedAt( new Date() )//签发时间
 .setExpiration( new Date( exp ) )//过期时间
 .claim( "roles","admin" )	//扩展数据,角色
 .signWith( SignatureAlgorithm.HS256, "123" );	//使用HS256算法,并设置SecretKey(字符串)
String token = jwtBuilder.compact();
System.out.println(token);

打印一个很长的密文:eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NTc5MDQxODF9.ThecMfgYjtoys3JX7dpx3hu6pUm0piZ0t...

解析令牌

String token ="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NjIyNTM3NTQsImV4cCI6MTU2MjI1Mzc4Mywicm9sZXMiOiJhZG1pbiJ9.CY6CMembCi3mAkBHS3ivzB5w9uvtZim1HkizRu2gWaI";
Claims claims = Jwts.parser().setSigningKey( "123" ).parseClaimsJws( token ).getBody();	
System.out.println(claims);	//扩展数据
System.out.println(claims.get( "roles" ));	//角色信息

打印效果{jti=111, sub=zs…}

总结
关注
打赏
1651329177
查看更多评论
立即登录/注册

微信扫码登录

0.0365s