SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥

文章目录

  • 一、用户认证分析
    • 1.1 认证与授权
      • 身份认证
      • 用户授权
    • 1.2 单点登录
    • 1.3 第三方登录
  • 二、认证技术方案了解(单点登录+第三方授权认证)
    • 2.1单点登录技术方案
    • 2.2 Oauth2认证
  • 三、SpringSecurity Oauth2.0入门
    • 导入依赖
    • Oauth2的四种授权模式
    • 1. 授权码模式授权
      • 1.1申请授权码
      • 1.2申请令牌
      • 1.3令牌校验
      • 1.4刷新令牌
    • 2. 密码模式授权
      • 2.1申请令牌
    • 3、资源服务授权
  • 四、公钥加密私钥解密
    • 生成证书
    • 查询证书信息:
    • mac下载openssl
        • 安装openssl方式一 使用brew命令
        • 安装openssl方式二
    • 导出公钥
    • 基于私钥生成Jwt令牌(使用私钥加盐)
    • 使用公钥解析Jwt令牌

一、用户认证分析

SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第1张图片
上面流程图描述了用户要操作的各个微服务,用户查看个人信息需要访问用户微服务,下单需要访问订单微服务,秒杀抢购商品需要访问秒杀微服务。
每个服务都需要认证用户的身份,身份认证成功后,需要识别用户的角色然后授权访问对应的功能。

1.1 认证与授权

身份认证

用户身份认证即用户去访问系统资源时系统要求验证用户的身份信息,身份合法方可继续访问。常见的用户身份认证表现形式有:用户名密码登录,指纹打卡等方式。说通俗点,就相当于校验用户账号密码是否正确

用户授权

用户认证通过后去访问系统的资源,系统会判断用户是否拥有访问资源的权限,只允许访问有权限的系统资源,没有权限的资源将无法访,这个过程叫用户授权

1.2 单点登录

用户访问的项目中,至少有3个微服务需要识别用户身份,如果用户访问每个微服务都登录一次就太麻烦了,为了提高用户的体验,我们需要实现让用户在一个系统中登录,其他任意受信任的系统都可以访问,这个功能就叫单点登录
单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。 SSO的 定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统

1.3 第三方登录

随着国内及国外巨头们的平台开放战略以及移动互联网的发展,第三方登录已经不是一个陌生的产品设 计概念了。 所谓的第三方登录,是说基于用户在第三方平台上已有的账号和密码来快速完成己方应用的 登录或者注册的功能。而这里的第三方平台,一般是已经拥有大量用户的平台,国外的比如 Facebook,Twitter等,国内的比如微博、微信、QQ等。

二、认证技术方案了解(单点登录+第三方授权认证)

2.1单点登录技术方案

Java中有很多用户认证的框架都可以实现单点登录:
1、Apache Shiro.
2、CAS
3、Spring security

2.2 Oauth2认证

第三方认证技术方案最主要是解决认证协议的通用标准问题,因为要实现跨系统认证,各系统之间要遵 循一定的 接口协议。 OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时, 任何第三方都可以使用OAUTH认 证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而 OAUTH是开放的。业界提供了OAUTH的多种实现如PHP、JavaScript,Java,Ruby等各种语言开发 包,大大节约了程序员的时间,因而OAUTH是简易的。互联网很多服务如Open API,很多大公司如 Google,Yahoo,Microsoft等都提供了OAUTH认证服务,这些都足以说明OAUTH标准逐渐成为开放 资源授权的标准。 Oauth协议目前发展到2.0版本,1.0版本过于复杂,2.0版本已得到广泛应用。
Oauth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容, Oauth2.0是 Oauth协议的延续版。

三、SpringSecurity Oauth2.0入门

导入依赖

 		<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-data</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

Oauth2的四种授权模式

Oauth2有一下授权模式:

  1. 授权码模式(Authorization Code )常用
  2. 密码模式(Resource Owner Password Credentials) 常用
  3. 隐式授权模式 不常用
  4. 客户端模式 不常用

1. 授权码模式授权

Oauth2包括以下角色:
1、客户端 本身不存储资源,需要通过资源拥有者的授权去请求资源服务器的资源,比如:畅购、Android客户端、畅购Web客户端(浏览器端)、微信客户端等。
2、资源拥有者 通常为用户,也可以是应用程序,即该资源的拥有者。
3、授权服务器(也称认证服务器) 用来对资源拥有的身份进行认证、对访问资源进行授权。客户端要 想访问资源需要通过认证服务器由资源拥有者授 权后方可访问。
4、资源服务器 存储资源的服务器,比如,畅购用户管理服务器存储了畅购的用户信息,微信的资源服 务存储了微信的用户信息等。客户端最终访问资源服务器获取资源信息。

授权码授权流程:
1、客户端(比如说淘宝官网)请求第三方授权
2、资源拥有者(用户)同意给客户端授权
3、客户端获取到授权码,请求认证服务器申请令牌
4、认证服务器向客户端响应令牌
5、客户端请求資源服务器的资源,资源服务校验令牌合法性,完成授权
6、资源服务器返回受保护资源

授权码模式授权步骤流程:

1.1申请授权码

Get请求:http://localhsot:9001/oauth/authorize?client_id=changgou&response_type=code&scop=app&redirect_uri=http://localhost
参数列表如下:

client_id:客户端id,和授权配置类中设置的客户端id一致。
response_type:授权码模式固定为code
scop:客户端范围,和授权配置类中设置的scop一致。
redirect_uri:跳转uri,当授权码申请成功后会跳转到此地址,并在后边带上code参数(授权码)

首先跳转到登录页面:http://localhost:9001/login
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第2张图片

输入账号和密码,点击Login。
Spring Security接收到请求会调用UserDetailsService接口的 loadUserByUsername方法查询用户正确的密码。 当前导入的基础工程中客户端ID为changgou,秘钥 也为changgou即可认证通过。
下面页面代表密码正确,认证成功。(因为没有配置登陆成功后的页面才会Error)。
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第3张图片

接下来进入授权页面:http://localhost:9001/oauth/authorize?client_id=changgou&response_type=code&scop=app&redirect_uri=http://localhost
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第4张图片
点击Authorize,接下来返回授权码: 认证服务携带授权码跳转redirect_uri,code=k45iLY就是返回的授 权码, 每一个授权码只能使用一次。
下图是已经返回授权码,在路径中显示http://localhost/?code=qWk1Th。(无法访问此网站是因为我们在申请授权码的时候路径中写的重定向的页面除了问题)
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第5张图片

1.2申请令牌

拿到授权码后,申请令牌。需要用POST请求:http://localhost:9001/oauth/token

grant_type:授权类型,填写authorization_code,表示授权码模式
code:授权码,就是刚刚获取的授权码,注意:授权码只使用一次就无效了,需要重新申请。
redirect_uri:申请授权码时的跳转url,一定和申请授权码时用的redirect_uri一致。

此链接需要使用 http Basic认证。 什么是http Basic认证?
http协议定义的一种认证方式,将客户端id和客户端密码按照“客户端ID:客户端密码”的格式拼接,并用 base64编 码,放在header中请求服务端,一个例子:
Authorization:Basic WGNXZWJBcHA6WGNXZWJBcHA=WGNXZWJBcHA6WGNXZWJBcHA= 是用户 名:密码的base64编码。 认证失败服务端返回 401 Unauthorized。
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第6张图片

SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第7张图片

==客户端Id和客户端密码会匹配数据库oauth_client_details表中的客户端id及客户端密码。 ==
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第8张图片
使用BCryptPasswordEncoder().encode();方式加密
需要在注入

  /***
     * 采用BCryptPasswordEncoder对密码进行编码
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

建表语句:

CREATE TABLE `oauth_client_details` (
  `client_id` varchar(48) NOT NULL COMMENT '客户端ID,主要用于标识对应的应用',
  `resource_ids` varchar(256) DEFAULT NULL,
  `client_secret` varchar(256) DEFAULT NULL COMMENT '客户端秘钥,BCryptPasswordEncoder加密算法加密',
  `scope` varchar(256) DEFAULT NULL COMMENT '对应的范围',
  `authorized_grant_types` varchar(256) DEFAULT NULL COMMENT '认证模式',
  `web_server_redirect_uri` varchar(256) DEFAULT NULL COMMENT '认证后重定向地址',
  `authorities` varchar(256) DEFAULT NULL,
  `access_token_validity` int(11) DEFAULT NULL COMMENT '令牌有效期',
  `refresh_token_validity` int(11) DEFAULT NULL COMMENT '令牌刷新周期',
  `additional_information` varchar(4096) DEFAULT NULL,
  `autoapprove` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`client_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

点击发送: 申请令牌成功
返回结果:

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJhcHAiXSwibmFtZSI6bnVsbCwiaWQiOm51bGwsImV4cCI6MjAzNzYwNDQ4OCwianRpIjoiNTcxNDM1NmMtYWU4MC00NjNmLWI5MzktNGFlMTA1YWZjOThkIiwiY2xpZW50X2lkIjoiY2hhbmdnb3UiLCJ1c2VybmFtZSI6ImNoYW5nZ291In0.POGOk6Tm1ioqRmY2q10dNp-dl5mMwu4OR9XBd4xVadUcYYWaYELf2GnYyJYuqzYMvzRKToumn3659toZIbz9eh-XRFHlYtJ-vdS5h5v8CudoNKidMemdB1O7PgtTUt1UZNbE3TJNf_MUAP3evGJ9FyHZYDogkcFDPRUj-PEG7hK07p8OSczhEtjaIX94PpzXQCOm30MXD9bJ487sjbjoYnhzmXl8KnODn30M65rN-rUGVkn-qpIrGwhzgmtcKktjC2D-8vVX9nuHMLwdcG_8lujcIC49XI-l_IBz3DH3XdSLv4cotB-XZ022W5ZHEPsLdLfDyeOcyIxU5isAHIlEqg",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJhcHAiXSwiYXRpIjoiNTcxNDM1NmMtYWU4MC00NjNmLWI5MzktNGFlMTA1YWZjOThkIiwibmFtZSI6bnVsbCwiaWQiOm51bGwsImV4cCI6MjAzNzYwNDQ4OCwianRpIjoiZDk2NmVjYmUtNzZhMi00NjVjLWEyZWQtMDZmNDk1OGJhM2M3IiwiY2xpZW50X2lkIjoiY2hhbmdnb3UiLCJ1c2VybmFtZSI6ImNoYW5nZ291In0.Xitu9p64rRuDJJWcfKBtCkMvVzlIOghUIJaChU-JHOtD4a0jCOMfHA2gcvfDVu_u9z-n1pVFhvk9V3qGhO1FeOb3DJKwz1mdEAaQj-jyvmYFerJ1ZFcxWzqSrYkYcn6nFAaA7ABTShQjgXXb4UdWN0vvXGKqDSX4TMcIFb6qrT6Y4cAeaN9dqc2DvbQRfXUYq5Oy36HQH5jOp1JKTfHda8dofNvLaG-ohvVkBaMVOgP2QZi_K1x1aUy2Ti2f4ou8NxYAsf0B49XqmfaVx0KEzlFuEGRjB1jAHF9seaA3dh2_Fv8rMMERk3DDBvqvRmeLRCKuTIeof-AIgxdVX_euIw",
    "expires_in": 431999999,
    "scope": "app",
    "jti": "5714356c-ae80-463f-b939-4ae105afc98d"
}
  1. access_token:访问令牌,携带此令牌访问资源
  2. token_type:有MAC Token与Bearer Token两种类型,两种的校验算法不同,RFC 6750建议Oauth2采 用 Bearer Token(http://www.rfcreader.com/#rfc6750)。
  3. refresh_token:刷新令牌,使用此令牌可以延长访问令牌的过期时间。
  4. expires_in:过期时间,单位为秒。
  5. scope:范围,与定义的客户端范围一致。
  6. jti:当前token的唯一标识

1.3令牌校验

Spring Security Oauth2提供校验令牌的端点:GET请求
http://localhost:9001/oauth/check_token?token= [access_token]
替换申请令牌时返回的access_token

http://localhost:9001/oauth/check_token?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJhcHAiXSwibmFtZSI6bnVsbCwiaWQiOm51bGwsImV4cCI6MjAzNzYwNDQ4OCwianRpIjoiNTcxNDM1NmMtYWU4MC00NjNmLWI5MzktNGFlMTA1YWZjOThkIiwiY2xpZW50X2lkIjoiY2hhbmdnb3UiLCJ1c2VybmFtZSI6ImNoYW5nZ291In0.POGOk6Tm1ioqRmY2q10dNp-dl5mMwu4OR9XBd4xVadUcYYWaYELf2GnYyJYuqzYMvzRKToumn3659toZIbz9eh-XRFHlYtJ-vdS5h5v8CudoNKidMemdB1O7PgtTUt1UZNbE3TJNf_MUAP3evGJ9FyHZYDogkcFDPRUj-PEG7hK07p8OSczhEtjaIX94PpzXQCOm30MXD9bJ487sjbjoYnhzmXl8KnODn30M65rN-rUGVkn-qpIrGwhzgmtcKktjC2D-8vVX9nuHMLwdcG_8lujcIC49XI-l_IBz3DH3XdSLv4cotB-XZ022W5ZHEPsLdLfDyeOcyIxU5isAHIlEqg

校验成功:
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第9张图片

校验失败:
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第10张图片

1.4刷新令牌

POST请求http://localhost:9100/oauth/token
表单格式
参数:
grant_type: 固定为 refresh_token
refresh_token:刷新令牌(注意不是access_token,而是refresh_token)
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第11张图片

2. 密码模式授权

密码模式(Resource Owner Password Credentials)与授权码模式的区别是申请令牌不再使用授权码,而是直接通过用户名和密码即可申请令牌。

2.1申请令牌

Post请求: http://localhost:9001/oauth/token
携带参数:
grant_type : 密码模式授权填写 password
username: 账号
password: 密码
并且此链接需要使用 http Basic认证。
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第12张图片

通过用户名和密码查询用户表用户名和密码
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第13张图片

3、资源服务授权

资源服务拥有要访问的受保护资源,客户端携带令牌访问资源服务,如果令牌合法则可成功访问资源服务中的资源,如下图:
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第14张图片

  1. 客户端请求认证服务申请令牌
  2. 认证服务生成令牌认证服务采用非对称加密算法,使用私钥生成令牌。
  3. 客户端携带令牌访问资源服务客户端在Http header 中添加: Authorization:Bearer令牌。
  4. 资源服务请求认证服务校验令牌的有效性资源服务接收到令牌,使用公钥校验令牌的合法性。
  5. 令牌有效,资源服务向客户端响应资源信息

四、公钥加密私钥解密

Spring Security提供对WT的支持,本节我们使用 Spring Security提供的 HwtHelper来创建Jwt令牌,校验WT令牌等操作。这里Jwt令牌我们采用非对称算法进行加密,所以我们要先生成公钥和私钥

生成证书

(1)生成密钥证书下边命令生成密钥证书,采用RSA算法每个证书包含公钥和私钥。
创建一个文件夹jks,在该文件夹下执行如下命令行

 keytool -genkeypair -alias changgou -keyalg RSA -keypass changgou -keystore changgou.jks -storepass changgou

Keytool 是一个java提供的证书管理工具

-alias:密钥的别名
-keyalg:使用的hash算法
-keypass:密钥的访问密码 
-keystore:密钥库文件名,changgou.jks保存了生成的证书 
-storepass:密钥库的访问密码

SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第15张图片

SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第16张图片

查询证书信息:

keytool -list -keystore changgou.jks

SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第17张图片

mac下载openssl

openssl是一个加解密工具包,这里使用openssl来导出公钥信息。

安装openssl方式一 使用brew命令

使用brew下载安装openssl

brew install openssl

Mac终端一直卡在Updating Homebrew…解决方法

安装openssl方式二

在官网下载:下载openssl
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第18张图片
使用tar命令解压,查看版本openssl version
在这里插入图片描述

导出公钥

进入jks文件夹下,使用以下命令

keytool -list -rfc --keystore changgou.jks | openssl x509 -inform pem -pubkey

输入密钥库的访问密码
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第19张图片

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoc0Zs7om5mT5K9nZ6Bo9
goH6NXevuJ0twXG2pysE0i4JpzjhmSHRGN1TbgA4qZTvO4887J96YXvBTsVjdH3Q
iF5niSECxe0ThjSeSCfgOUegliLSwMTYiqQDXXA7LfLPaGxto+3ba+bSf2BpnunH
85xAp/ZsSm89yEqa7ib+ReT/fKZNbtNZuqlQeW9oFhw02axcd0m8gxXvePjN84E/
YQLIt2YswVYZ2N5isjVxzGbVaTqxryGZjJPj6T26L3KtkDF1QE9XPw9EMBwlVhql
WPV+pb/3wYyLfp5kObFcDD3MICoaOiB3gBiQr1tCxvGSfh7qjKe7oXwyRsIyAtVU
GQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
MIIDRTCCAi2gAwIBAgIELLsXbzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJj
bjEMMAoGA1UECBMDbHNoMQwwCgYDVQQHEwNsc2gxDDAKBgNVBAoTA2xzaDEMMAoG
A1UECxMDbHNoMQwwCgYDVQQDEwNsc2gwHhcNMjAxMTEzMDk0OTU4WhcNMjEwMjEx
MDk0OTU4WjBTMQswCQYDVQQGEwJjbjEMMAoGA1UECBMDbHNoMQwwCgYDVQQHEwNs
c2gxDDAKBgNVBAoTA2xzaDEMMAoGA1UECxMDbHNoMQwwCgYDVQQDEwNsc2gwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChzRmzuibmZPkr2dnoGj2Cgfo1
d6+4nS3BcbanKwTSLgmnOOGZIdEY3VNuADiplO87jzzsn3phe8FOxWN0fdCIXmeJ
IQLF7ROGNJ5IJ+A5R6CWItLAxNiKpANdcDst8s9obG2j7dtr5tJ/YGme6cfznECn
9mxKbz3ISpruJv5F5P98pk1u01m6qVB5b2gWHDTZrFx3SbyDFe94+M3zgT9hAsi3
ZizBVhnY3mKyNXHMZtVpOrGvIZmMk+PpPbovcq2QMXVAT1c/D0QwHCVWGqVY9X6l
v/fBjIt+nmQ5sVwMPcwgKho6IHeAGJCvW0LG8ZJ+HuqMp7uhfDJGwjIC1VQZAgMB
AAGjITAfMB0GA1UdDgQWBBQnC9d8sSfqijSEreqLWRd5kFy3+jANBgkqhkiG9w0B
AQsFAAOCAQEAMyJilsJ5+hYoyqjEA15j1FQU59xJOkjXqBJm2PeZsAR/ksm7jQIO
/HdpB2QukCA2Knx+KukENigKZhp9TlG+jjUgUH8TF02rULR3/gZT5VLVnl9eY+E2
Zl/w17ML+aIkd+xy0bz+JqhRvK4pQoaKdLC+4w/UaTVW57/VgvY1PtdtulrH9qzO
MlV1bYjVIqtmEz9Uu3eXjFM0EOfjleSeVFTkX/OVo7c/jfKDEwsv/WmO8Ig75B6S
sx+fk3UjTDUdJhF1nK/nkTJmw/F7Wzy2QT+QIVM7p8ReBcOk5ScrqI9kqp/qYUkI
5ZKh7Ri3Upuq9ibZCFX7LT4vPsFGNJ4gRg==
-----END CERTIFICATE-----

将上边的公钥拷贝到文本public.key文件中,合并为一行,可以将它放到需要实现授权认证的工程中。

-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoc0Zs7om5mT5K9nZ6Bo9goH6NXevuJ0twXG2pysE0i4JpzjhmSHRGN1TbgA4qZTvO4887J96YXvBTsVjdH3QiF5niSECxe0ThjSeSCfgOUegliLSwMTYiqQDXXA7LfLPaGxto+3ba+bSf2BpnunH85xAp/ZsSm89yEqa7ib+ReT/fKZNbtNZuqlQeW9oFw02axcd0m8gxXvePjN84E/YQLIt2YswVYZ2N5isjVxzGbVaTqxryGZjJPj6T26L3KtkDF1QE9XPw9EMBwlVhqlWPV+pb/3wYyLfp5kObFcDD3MICoaOiBgBiQr1tCxvGSfh7qjKe7oXwyRsIyAtVUGQIDAQAB-----END PUBLIC KEY-----

基于私钥生成Jwt令牌(使用私钥加盐)

注意:
Jwt使用私钥加盐

/*****
 * @Author: www.itheima
 * @Date: 2019/7/7 13:42
 * @Description: com.changgou.token
 *      创建JWT令牌,使用私钥加密
 ****/
public class CreateJwtTest {

    /***
     * 创建令牌测试
     *
     * 1.加载证书
     * 2.读取证书数据
     * 3.获取私钥
     * 4.创建令牌、需要私钥加盐[RSA算法  非对称加密]
     */
    @Test
    public void testCreateToken(){
        //证书文件路径
        String key_location="changgou.jks";
        //秘钥库密码
        String key_password="changgou";
        //秘钥密码
        String keypwd = "changgou";
        //秘钥别名
        String alias = "changgou";

        //访问证书路径 读取jks的文件
        ClassPathResource resource = new ClassPathResource(key_location);

        //创建秘钥工厂  加载读取证书数据
        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource,key_password.toCharArray());

        //读取秘钥对(公钥、私钥)  获取证书中 的一对秘钥   (别名,密码)
        KeyPair keyPair = keyStoreKeyFactory.getKeyPair(alias,keypwd.toCharArray());

        //获取私钥
        RSAPrivateKey rsaPrivate = (RSAPrivateKey) keyPair.getPrivate();

        //自定义Payload
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("id", "1");
        tokenMap.put("name", "itheima");
        tokenMap.put("roles", "ROLE_VIP,ROLE_USER");

        //生成Jwt令牌   JwtHelper是SpringSecurity提供的类   (载荷,盐(私钥 ))
        Jwt jwt = JwtHelper.encode(JSON.toJSONString(tokenMap), new RsaSigner(rsaPrivate));

        //取出令牌
        String encoded = jwt.getEncoded();
        System.out.println(encoded);
    }
}

使用公钥解析Jwt令牌

/*****
 * @Author: www.itheima
 * @Date: 2019/7/7 13:48
 * @Description: com.changgou.token
 *  使用公钥解密令牌数据
 ****/
public class ParseJwtTest {

    /***
     * 校验令牌
     */
    @Test
    public void testParseToken(){
        //令牌
        String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlcyI6IlJPTEVfVklQLFJPTEVfVVNFUiIsIm5hbWUiOiJpdGhlaW1hIiwiaWQiOiIxIn0.hDDJDNFsX-lrIXJC_k4s01qSlmWb_Pq43G2ZSDrwmf4ugwNC0ViwBztxGIfhJ4K74dZpKj4pqOqo83U_fjUDHT80VsM3sIRuL_nXc43fqSvQUg_WIWqUlX1VYyS413FFn1u_V_9yOnxmQKi1p5bIp644XeGFMSJS3_U3rYLZYQtr6Q8VGbciUaEKimoZQf8ca4kbk1szfyye4llBzixgh3gH4UjKrX-kB-qgo4eDD0dW0UBCxqhpoS-QN4pc3ZtrkndW7xRVrjU0VrIJbNtQmXwk3vE0anOuD1yowh2jY3QmFwR323YcLXPPbGP-KrvPBmJJLC9X2nffCQR61HMJTw";

        //公钥
        String publickey = "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoc0Zs7om5mT5K9nZ6Bo9goH6NXevuJ0twXG2pysE0i4JpzjhmSHRGN1TbgA4qZTvO4887J96YXvBTsVjdH3QiF5niSECxe0ThjSeSCfgOUegliLSwMTYiqQDXXA7LfLPaGxto+3ba+bSf2BpnunH85xAp/ZsSm89yEqa7ib+ReT/fKZNbtNZuqlQeW9oFhw02axcd0m8gxXvePjN84E/YQLIt2YswVYZ2N5isjVxzGbVaTqxryGZjJPj6T26L3KtkDF1QE9XPw9EMBwlVhqlWPV+pb/3wYyLfp5kObFcDD3MICoaOiB3gBiQr1tCxvGSfh7qjKe7oXwyRsIyAtVUGQIDAQAB-----END PUBLIC KEY-----";

        //校验Jwt
        Jwt jwt = JwtHelper.decodeAndVerify(token, new RsaVerifier(publickey));

        //获取Jwt原始内容 载荷
        String claims = jwt.getClaims();
        System.out.println(claims);
        //jwt令牌
        String encoded = jwt.getEncoded();
        System.out.println(encoded);
    }
}

创建令牌
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第20张图片
解析令牌
SpringSecurityOauth2授权模式与使用RSA非对称加密方式生成公钥私钥_第21张图片

你可能感兴趣的:(SpringBoot,java,jwt)