JWT令牌
JWT 就是用一种结构化封装的方式来生成 token 的技术。 这种结构化体可以分为 HEADER(头部)、PAYLOAD(数据体)和 SIGNATURE(签名)三部分。如下图:
JWT如何使用
JWT令牌的使用,授权服务和受保护的资源服务无需再访问数据库或者RPC服务,可直接解析令牌本身的信息。
开源工具JJWT封装了Base64URL编码和对称HMAC、非对称RSA的一系列算法,可方便使用无需关系具体编码和签名算法实现。Demo如下:
String sharedTokenSecret="hellooauthhellooauthhellooauthhellooauth";//密钥
Key key = new SecretKeySpec(sharedTokenSecret.getBytes(),
SignatureAlgorithm.HS256.getJcaName());
//生成JWT令牌
String jwts=
Jwts.builder().setHeaderParams(headerMap).setClaims(payloadMap).signWith(key,SignatureAlgorithm.HS256).compact()
//解析JWT令牌
Jws<Claims> claimsJws =Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(jwts);
JwsHeader header = claimsJws.getHeader();
Claims body = claimsJws.getBody();
JWT的优点和缺点
三个优点:
- 用计算代替存储,时间换空间。
- 加密。传输过程中保障了传输的安全性。
- 挣钱系统的的可用性和可伸缩性。
缺点:
- JWT 无法修改令牌状态,如果出现某种错误,在令牌有效期内将无法处理。
解决方法 缩小JWT令牌的秘钥颗粒度至用户级别,一个用户一个秘钥。修改秘钥来达到修改令牌;
注册
官方规范给出的使用访问令牌请求的方式,有三种:
- Form-Encoded Body Parameter(表单参数)
- URI Query Parameter(URI 查询参数)
- Authorization Request Header Field(授权请求头部字段)
OAuth2.0 的许可类型
- 授权码许可:通过授权码code获取access_toke(安全性最高,首选授权码许可)
- 资源拥有者许可:通过资源拥有者的用户名 和密码获取access_token
- 客户端凭据许可:通过第三方appid和app_sercet获取access_token
Map<String, String> params = new HashMap<String, String>();
params.put("grant_type","client_credentials");
params.put("app_id","APPIDTEST");
params.put("app_secret","APPSECRETTEST");
String accessToken = HttpURLClient.doPost(oauthURl,HttpURLClient.mapToStr(params));
- 隐式许可:通过浏览器中的第三方软件的appid 来获取access_token
资源拥有者对于浏览器就没有任何保密的数据可以隐藏了,也不再需要应用密钥 app_secret 的值了,也不用再通过授权码 code 来换取访问令牌 access_token 的值了。因为使用授权码的目的之一,就是把浏览器和第三方软件的信息做一个隔离,确保浏览器看不到第三方软件最重要的访问令牌 access_token 的值。
Map<String, String> params = new HashMap<String, String>();
params.put("response_type","token");//告诉授权服务直接返回access_token
params.put("redirect_uri","http://localhost:8080/AppServlet-ch02");
params.put("app_id","APPIDTEST");
String toOauthUrl = URLParamsUtil.appendParams(oauthUrl,params);//构造请求授权的URl
response.sendRedirect(toOauthUrl);
如何选择到底使用哪种授权许可类型
建议:
在对接 OAuth 2.0 的时候先考虑授权码许可类型,其次再结合现实生产环境来选择:
- 如果第三方软件是官方出品,那么可以直接使用资源拥有者凭据许可;
- 如果第三方软件就是只嵌入到浏览器端的应用且没有服务端,那就只能选择隐式许可;
- 如果第三方软件获取的信息不属于任何一个第三方用户,那可以直接使用客户端凭据许可类型。