单点登录JWT与Spring Security OAuth

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单点登录JWT与Spring Security OAuth相关的知识,希望对你有一定的参考价值。

参考技术A

通过 JWT 配合 Spring Security OAuth2 使用的方式,可以避免 每次请求 远程调度 认证授权服务。 资源服务器 只需要从 授权服务器 验证一次,返回 JWT。返回的 JWT 包含了 用户 的所有信息,包括 权限信息

1. 什么是JWT

JSON Web Token(JWT)是一种开放的标准(RFC 7519),JWT 定义了一种 紧凑 自包含 的标准,旨在将各个主体的信息包装为 JSON 对象。 主体信息 是通过 数字签名 进行 加密 验证 的。经常使用 HMAC 算法或 RSA( 公钥 / 私钥 非对称性加密 )算法对 JWT 进行签名, 安全性很高

2. JWT的结构

JWT 的结构由三部分组成:Header(头)、Payload(有效负荷)和 Signature(签名)。因此 JWT 通常的格式是 xxxxx.yyyyy.zzzzz。

2.1. Header

Header 通常是由 两部分 组成:令牌的 类型 (即 JWT)和使用的 算法类型 ,如 HMAC、SHA256 和 RSA。例如:

将 Header 用 Base64 编码作为 JWT 的 第一部分 ,不建议在 JWT 的 Header 中放置 敏感信息

2.2. Payload

下面是 Payload 部分的一个示例:

将 Payload 用 Base64 编码作为 JWT 的 第二部分 ,不建议在 JWT 的 Payload 中放置 敏感信息

2.3. Signature

要创建签名部分,需要利用 秘钥 对 Base64 编码后的 Header 和 Payload 进行 加密 ,加密算法的公式如下:

签名 可以用于验证 消息 传递过程 中有没有被更改。对于使用 私钥签名 的 token,它还可以验证 JWT 的 发送方 是否为它所称的 发送方

3. JWT的工作方式

客户端 获取 JWT 后,对于以后的 每次请求 ,都不需要再通过 授权服务 来判断该请求的 用户 以及该 用户的权限 。在微服务系统中,可以利用 JWT 实现 单点登录 。认证流程图如下:

4. 案例工程结构

工程原理示意图如下:

5. 构建auth-service授权服务

UserServiceDetail.java

UserRepository.java

实体类 User 和上一篇文章的内容一样,需要实现 UserDetails 接口,实体类 Role 需要实现 GrantedAuthority 接口。

User.java

Role.java

jks 文件的生成需要使用 Java keytool 工具,保证 Java 环境变量没问题,输入命令如下:

其中,-alias 选项为 别名 ,-keyalg 为 加密算法 ,-keypass 和 -storepass 为 密码选项 ,-keystore 为 jks 的 文件名称 ,-validity 为配置 jks 文件 过期时间 (单位:天)。

生成的 jks 文件作为 私钥 ,只允许 授权服务 所持有,用作 加密生成 JWT。把生成的 jks 文件放到 auth-service 模块的 src/main/resource 目录下即可。

对于 user-service 这样的 资源服务 ,需要使用 jks 的 公钥 对 JWT 进行 解密 。获取 jks 文件的 公钥 的命令如下:

这个命令要求安装 openSSL 下载地址,然后手动把安装的 openssl.exe 所在目录配置到 环境变量

输入密码 fzp123 后,显示的信息很多,只需要提取 PUBLIC KEY,即如下所示:

新建一个 public.cert 文件,将上面的 公钥信息 复制到 public.cert 文件中并保存。并将文件放到 user-service 等 资源服务 的 src/main/resources 目录下。至此 auth-service 搭建完毕。

maven 在项目编译时,可能会将 jks 文件 编译 ,导致 jks 文件 乱码 ,最后不可用。需要在 pom.xml 文件中添加以下内容:

6. 构建user-service资源服务

注入 JwtTokenStore 类型的 Bean,同时初始化 JWT 转换器 JwtAccessTokenConverter,设置用于解密 JWT 的 公钥

配置 资源服务 的认证管理,除了 注册 登录 的接口之外,其他的接口都需要 认证

新建一个配置类 GlobalMethodSecurityConfig,通过 @EnableGlobalMethodSecurity 注解开启 方法级别 安全验证

拷贝 auth-service 模块的 User、Role 和 UserRepository 三个类到本模块。在 Service 层的 UserService 编写一个 插入用户 的方法,代码如下:

配置用于用户密码 加密 的工具类 BPwdEncoderUtil:

实现一个 用户注册 的 API 接口 /user/register,代码如下:

在 Service 层的 UserServiceDetail 中添加一个 login() 方法,代码如下:

AuthServiceClient 作为 Feign Client,通过向 auth-service 服务接口 /oauth/token 远程调用获取 JWT。在请求 /oauth/token 的 API 接口中,需要在 请求头 传入 Authorization 信息, 认证类型 ( grant_type )、用户名 ( username ) 和 密码 ( password ),代码如下:

其中,AuthServiceHystrix 为 AuthServiceClient 的 熔断器 ,代码如下:

JWT 包含了 access_token、token_type 和 refresh_token 等信息,代码如下:

UserLoginDTO 包含了一个 User 和一个 JWT 成员属性,用于返回数据的实体:

登录异常类 UserLoginException

全局异常处理 切面类 ExceptionHandle

在 Web 层的 UserController 类中新增一个登录的 API 接口 /user/login 如下:

依次启动 eureka-service,auth-service 和 user-service 三个服务。

7. 使用Postman测试

因为没有权限,访问被拒绝。在数据库手动添加 ROLE_ADMIN 权限,并与该用户关联。重新登录并获取 JWT,再次请求 /user/foo 接口。

在本案例中,用户通过 登录接口 来获取 授权服务 加密后的 JWT。用户成功获取 JWT 后,在以后每次访问 资源服务 的请求中,都需要携带上 JWT。 资源服务 通过 公钥解密 JWT, 解密成功 后可以获取 用户信息 权限信息 ,从而判断该 JWT 所对应的 用户 是谁,具有什么 权限

获取一次 Token,多次使用, 资源服务 不再每次访问 授权服务 该 Token 所对应的 用户信息 和用户的 权限信息

一旦 用户信息 或者 权限信息 发生了改变,Token 中存储的相关信息并 没有改变 ,需要 重新登录 获取新的 Token。就算重新获取了 Token,如果原来的 Token 没有过期,仍然是可以使用的。一种改进方式是在登录成功后,将获取的 Token 缓存 网关上 。如果用户的 权限更改 ,将 网关 上缓存的 Token 删除 。当请求经过 网关 ,判断请求的 Token 在 缓存 中是否存在,如果缓存中不存在该 Token,则提示用户 重新登录

Spring Security + JWT 实现单点登录,还有谁不会??

本文我们来看下 SpringSecurity + JWT 实现单点登录操作,本文 2W 字,预计阅读时间 30 min,文章提供了代码骨架,建议收藏。 一、什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系

以上是关于单点登录JWT与Spring Security OAuth的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security + JWT 实现单点登录,还有谁不会。。。

Spring Security整合JWT,实现单点登录,So Easy~!

Java开发 - 单点登录初体验(Spring Security + JWT)

基于Spring Security Oauth2的SSO单点登录+JWT权限控制实践

springboot+security+JWT实现单点登录

Spring Security 解析 —— 基于JWT的单点登陆(SSO)开发及原理解析