用户身份认证
1.单一服务器模式
一般过程如下:
1.用户向服务器发送用户名和密码。
2.验证服务器后,相关数据(如用户名,用户角色等)将保存在当前会话(session) 中。
3.服务器向用户返回session, id, session信息都会写入到用户的C ookie.
4.用户的每个后续请求都将通过在Cookie中取出session. id传给服务器。
5.服务器收到session, id并对比之前保存的数据,确认用户的身份。
缺点:
●单点性能压力,无法扩展。
●分布式架构中,需要session共享方案,session共享方案存在性能瓶颈。
- cas 和oauth2
一般过程如下:
- 当业务A、业务B需要登录时,将跳到SSO系统。
- SSO从用户信息数据库中获取用户信息并校验用户信息,SSO系统完成登录。
- 然后将用户信息存入缓存(例如redis)。
- 当用户访问业务A或业务B,需要判断用户是否登录时,将跳转到SSO系统中进行用户身份验证,SSO判断缓存中是否存在用户身份信息。
- 这样,只要其中一个系统完成登录,其他的应用系统也就随之登录了。这就是单点登录(SSO)的定义。
优点 :
用户身份信息独立管理,更好的分布式管理。可以自己扩展安全策略
缺点:
认证服务器访问压力较大。
3.token
优点:
- 无状态: token是无状态,session是有状态的
- 基于标准化:你的API可以采用标准化的 JSON Web Token (JWT)
缺点:
- 占用带宽
- 无法在服务器端销毁
访问令牌
令牌类型
思路
JWT使用
导入依赖
创建普通maven项目,导入依赖
<dependencies>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
了解jwt组成
创建测试
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.Test;
import java.util.Date;
import java.util.UUID;
public class JwtTests {
private static long tokenExpiration=1000*60*60;
private static String tokenSignKey="laobinggan";
@Test
public void testCreateToken(){
String jwt= Jwts.builder()
//设置头
.setHeaderParam("alg","HS256")
.setHeaderParam("typ","JWT")
//设置载荷默认数据数据
.setSubject("test")
.setIssuer("laobingan")
.setAudience("me")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis()+tokenExpiration))
.setNotBefore(new Date(System.currentTimeMillis()+1000*20))
.setId(UUID.randomUUID().toString())
//设置载荷自定义数据
.claim("name","lily")
//设置签名
.signWith(SignatureAlgorithm.HS256,tokenSignKey)
//组装
.compact();
System.out.println(jwt);
}
}
输出
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0IiwiaXNzIjoibGFvYmluZ2FuIiwiYXVkIjoibWUiLCJpYXQiOjE2MzE5MzMzMDIsImV4cCI6MTYzMTkzNjkwMiwibmJmIjoxNjMxOTMzMzAzLCJqdGkiOiI2NmY4YWY2Yy0zYWQ0LTRiYTAtODg5My1iZDU3NDNlYmFjNjMiLCJuYW1lIjoibGlseSJ9.f57O1aHH6kYF7Zxx80CTKCZ89VietD-P7s9K9fRB6xs
解析
@Test
public void parentJWT(){
String jwt ="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0IiwiaXNzIjoibGFvYmluZ2FuIiwiYXVkIjoibWUiLCJpYXQiOjE2MzE5MzMzMDIsImV4cCI6MTYzMTkzNjkwMiwibmJmIjoxNjMxOTMzMzAzLCJqdGkiOiI2NmY4YWY2Yy0zYWQ0LTRiYTAtODg5My1iZDU3NDNlYmFjNjMiLCJuYW1lIjoibGlseSJ9.f57O1aHH6kYF7Zxx80CTKCZ89VietD-P7s9K9fRB6xs";
JwtParser parser = Jwts.parser();
Jws<Claims> claimsJws = parser.setSigningKey(tokenSignKey).parseClaimsJws(jwt);
Claims body = claimsJws.getBody();
String name = (String) body.get("name");
System.out.println(name);
}
输入
lily