前言
在服务聚群未用起来前,我门需要找到集群前过度的技术,用spring security 和注册中心,Oauth过于笨重,所以选用了JWT来过度。
JWT适用场景
- 代替传统session,并去中心化。
- 由于去中心话也适用于开放型服务鉴权(像微信公众号开发一样保持可用会话),服务与客户端交互类型。
- 高安全型类型,由于JWT每次请求都带有签名所以也适用单次高安全请求,由服务和客户端同时拥有密钥,并省略登陆过程。
本次主要对,高安全请求类型进行描述。
- 借由同事经验,密钥在启动服务输入保存在内存更为安全。
- 密钥尽量使用非称加密(如 RSA)后的类似字符组(如 :rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM),尽量不要使用有意义单词。
- 不暴露密钥
借助场景
- 积分转帐服务,由于涉及到钱需要高度安全。
整体流程
User Cent Transfer request
|
|
Client(Ui)
|
|
Cent Service
报文设计
- HEAD 固定为HS256,加密类型描述
{
"typ":"JWT",
"alg":"HS256"
}
- Payload (内容主体)
{
"requestId":"2018061123120011001",
"fromCentId":"1001",
"toCentId":"1002",
"number":100
}
- 签名
rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM
利用requestId来保证请求安全
- 巧妙使用requestId 来保证业务安全,也就是使用业务处理完成后的Id来做requestId
- 例如奖励,先生成相关奖励日志,再使用奖励日志id作为requestId
客户端
- 组合请求报文
- 报文有效期设计在1分钟,保证服务之间网络出现问题时超时处理。
public static String centTransferRequestJwtToken(String requestId,String fromCentId,String toCentId,Double number){
HashMap<String, Object> map = new HashMap<>();
//you can put any data in the map
map.put("requestId", requestId);
map.put("fromCentId",fromCentId);
map.put("toCentId",toCentId);
map.put("number",number);
String jwt = Jwts.builder()
.setClaims(map)
.setExpiration(new Date(System.currentTimeMillis() + 60000L))// 1 min
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
return jwt;
}
服务端
- 提供JWT转帐服务
- 校验签名
public static Map<String, Object> validateTokenAndReturnBodyMap(String token){
try {
// parse the token.
Map<String, Object> body = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
return body;
}catch (Exception e){
throw new IllegalStateException("Invalid Token. "+e.getMessage());
}
}
测试
@Test
public void test(){
/**
* 模拟客服端,生产请求令牌和请求
*/
String token = centTransferRequestJwtToken("2018061123120011001",
"1001",
"1002",
100.0
);
System.out.println("请求Token:");
System.out.println(token);
/**
* 模拟服务端,校验令牌
*/
Map<String, Object> body = validateTokenAndReturnBodyMap(token);
System.out.println("验证并取出请求参数:");
for(Map.Entry e:body.entrySet()){
System.out.println(e.getKey() + ":" + e.getValue());
}
//do business ...
//end
}
测试结果
请求Token:
eyJhbGciOiJIUzUxMiJ9.eyJmcm9tQ2VudElkIjoiMTAwMSIsIm51bWJlciI6MTAwLjAsInJlcXVlc3RJZCI6IjIwMTgwNjExMjMxMjAwMTEwMDEiLCJleHAiOjE1Mjg3MzQ4OTgsInRvQ2VudElkIjoiMTAwMiJ9.-ls2EGOJVHuj4fR0GtIz-VSRShR2Fr48w8YR0s83iQwzp3B0ZR3cHgbFT7mGmVRAYOFkX5wmtzzR_237foT5mA
验证并取出请求参数:
fromCentId:1001
number:100.0
requestId:2018061123120011001
exp:1528734898
toCentId:1002
整合cent服务提供Restfull接口
//待补充
网友评论