美文网首页
微服务实战记录(二),小聚群服务交互安全JWT

微服务实战记录(二),小聚群服务交互安全JWT

作者: 大继 | 来源:发表于2018-06-12 00:38 被阅读0次

    前言

    在服务聚群未用起来前,我门需要找到集群前过度的技术,用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接口

    //待补充
    

    参考

    https://blog.csdn.net/j3T9Z7H/article/details/80059968#

    相关文章

      网友评论

          本文标题:微服务实战记录(二),小聚群服务交互安全JWT

          本文链接:https://www.haomeiwen.com/subject/oimkeftx.html