发表于: 2018-10-18 23:13:50
1 491
今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin)
补充了一些概念的东西:
阅读前提:
用公钥加密,就要用私钥解密,反之毅然;
对称加密:使用同一个秘钥加密和解密;
SAML:安全声明标记语言: Security Assertion Markup Language:
基于 XML标准的,用于在不同的安全领域之间交换认证和授权的数据;(XML框架,也就是一组协议和规范)
不同安全领域: identity provider and service provider;(JWT也是这个功能)
简述:
简洁的,URL安全的表述形性声明规范;
简洁: 通过URL,POST参数;或者在HTTP head发送; (数据量非常小)
自包含:负载中包含了所有用户需要的信息,避免多次查询数据库;
使用流程:第一次登录后,接下来的每个请求都包含JWT,用来验证用户身份以及对路由,服务和资源的访问权限进行验证;由于信息是经过签名的,所以可以确保发送的信息没有经过伪造;
存放:local storage 或者cookie;
(由于Cookie的空间限制3kb,把Session的信息存放在JWT中,可能不太够,就要放在local storage,但是会带来另一个隐患,下文提到)
使用情况: 访问一个受保护的路由或者资源的时候,应该Authorization头部使用Bearer模式添加JWT;
Authorization:Bear<token>
Tip:用户状态不在服务器存储,所以是一种无状态的协议。
JWT结构: Header 头部. Payload 负载 Signature 签名
Header.Payload.Signature;
Header:
内容:{“alg”:”HS256”,”typ”:”JWT”}:
包含两部分:Token类型:Json Web Tocken; 加密算法:HS256;
操作:alg和typ使用 Base64Url编码,组成JWT结构的第一部分;
Playload:
内容:
Claim:
content: 一些实体(用户)的状态和额外的元数据;
Type:
reserved Claim :
public Claim :可在客户端解密——所以只添加用户相关或者业务需要的必要信息;(理论上能添加任何信息)
private Claim:provider和consumer共同定义的声明,也不建议存放敏感信息?????(不能理解)
iss——签发者;exp——过期时间戳;sub——面向用户;aub——接收方;iat——签发时间;jti:唯一身份表示,用来作为一次性tocken,避免回避重放攻击; …...
例子:
{“sub”:123123”,”name”:”Arno“,”admin”:true} 经过Base64URL编码后,作为JWT结构的第二部分;
Signature (secret:保存在客户端;应该是未经过base64Url编码,只经过header的加密方式加密过;)
先创建一个秘钥;用head中指定签名算法进行签名;
EG: HMACSHA256(base64UrlEncode(header)+”.”+base64UrlEncode(payload),secret) ,验证消息的发送 (存疑)
者以及消息是没有经过
SAML和JWT都能使用非对称秘钥进行加密;
JWT能直接映射成对象,SAML不行; 使用的话,我没对比过,优劣不好说;
另外JWT和Cookie和session的对比:
Session:是存放在服务器端,在使用的时候会面临两个问题:
多服务:Session共享问题;
业务:业务量的提升,会导致存放在内存中的Session增加,使得开销增大;
缺点:不便防止 CSRF: cross-site request forgery;
JWT:
优点是简洁,占用空间小;
缺点是:
不便防止: XXS:Cross Site Scripting: 跨站脚本攻击
更多的空间占用,导致不能放Cookie只能放在Local Storage,则更容易遭受到XSS攻击;
对于找到的一些其它缺点:
1:无法作废已经删除的Tocken:其实是可以的,在网关的时候,进行服务器缓存JWT的一个判断,如果删除了,则该Tocken作废;
2:对Jwt可能被破解,只要对称秘钥或者私钥没有被窃取,就还算安全;对于防止暴力破解,可以使用慢哈希加密;
所以,很多博客真的有毒;
工具类:
public class JwtHelper {
private final static String base64Secret = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY=";
private final static int expiresSecond = 172800000;
public static Claims parseJWT(String jsonWebToken) {
try {
Claims claims = Jwts.parser()
.setSigningKey(DatatypeConverter.parseBase64Binary(base64Secret))
.parseClaimsJws(jsonWebToken).getBody();
return claims;
} catch (Exception ex) {
return null;
}
}
public static String createJWT(String username, String roles, String privileges) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//生成签名密钥
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Secret);
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
//添加构成JWT的参数
JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
.claim("user_name", username)
.claim("user_role", roles)
.claim("user_privilege", privileges)
.signWith(signatureAlgorithm, signingKey);
//添加Token过期时间
if (expiresSecond >= 0) {
long expMillis = nowMillis + expiresSecond;
Date exp = new Date(expMillis);
builder.setExpiration(exp).setNotBefore(now);
}
//生成JWT
return builder.compact();
}
}
JWT参考网站
JWT替代参考:JJWT
JWT缺陷(有毒)
2:代码部分——略,还没抽离好
明天计划的事情:(一定要写非常细致的内容)
优化代码;继续测试
遇到的问题:(遇到什么困难,怎么解决的)
很多知识点一知半解;
收获:(通过今天的学习,学到了什么知识)
如上
评论