Spring Security Oauth 2.0第三方授权认证

在开始之前,首先介绍一下认证和授权。

身份认证

用户访问系统资源时,系统要求验证用户的身份信息,身份合法则方可继续访问。常见的用户身份认证的表现形式有:

  • 用户名密码登陆
  • 指纹打卡

用户授权

用户认证通过后去访问系统的资源,系统会判断当前用户是否拥有访问资源的权限,只允许访问有权限的资源,没有权限的资源无法访问。

1. 单点登陆

单点登陆是指用户在一个系统中登陆之后,就可以访问所有相互信任的应用系统。分布式系统要实现单点登陆,通常是将认证系统独立 抽取出来。

Spring Security Oauth 2.0第三方授权认证_第1张图片

2. Oauth 2.0

OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问它们存储在另外的服务提供者上的信息,而不需要将用户名和 密码提供给第三方移动应用或分享它们数据的所有内容。

Spring Security Oauth 2.0的两种常用的认证模式:

  • 授权码授权模式;
  • 密码授权模式。

2.1 授权码授权

授权码授权模式认证的流程如下图所示。

Spring Security Oauth 2.0第三方授权认证_第2张图片

2.1.1 申请授权码

请求认证服务获取授权码:

GET请求http://localhost:9988/oauth/authorize?client_id=changgou&response_type=code&scop=app&redirect_uri=http://localhost

参数介绍:

  • client_id: 客户端id,和授权配置类中设置的客户端id一致;
  • response_type: 授权码模式固定为code;
  • scope: 客户端范围,和授权配置类中设置的scop一致;
  • redirect_uri: 授权成功后要跳转的uri地址,uri后边将会带上code参数(授权码)

请求后跳转到如下界面

Spring Security Oauth 2.0第三方授权认证_第3张图片

输入客户端id和密钥,登陆

Spring Security Oauth 2.0第三方授权认证_第4张图片

点击Authorize获取授权码。

Spring Security Oauth 2.0第三方授权认证_第5张图片

2.1.2 获取令牌

拿到授权码后,接下来就可以申请令牌了:

POST请求http://localhost:9988/oauth/token

请求数据为:

grant_type:授权类型,填写authorization_code表示是授权码模式;
code:上一步操作获取的授权码ykF4gQ,注意,授权码只能使用一次;
redirect_uri:申请授权码时要跳转的uri,一定要和申请授权码时用的redirect_uri保持一致http://localhost。

同时,设置AuthorizationBasic Auth,输入客户端id和客户端密钥。

Spring Security Oauth 2.0第三方授权认证_第6张图片

获取到的令牌如下:

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJhcHAiXSwibmFtZSI6bnVsbCwiaWQiOm51bGwsImV4cCI6MTU5Nzk5NjUwNiwianRpIjoiY2QzOTkyMjktZTcwYi00NDZmLWFiMGEtNDYzYjMxYjcxM2MzIiwiY2xpZW50X2lkIjoiY2hhbmdnb3UiLCJ1c2VybmFtZSI6ImNoYW5nZ291In0.af-BdA4KA5RPJPJRhyPdumSZRVH8LNQlAxw50XNHCpAhCkfsjW5A12it9RQxvyUv6RQ-Vq2Gi6bvO2Alc29HXEJdyZ9S-Wwv85Uzrt4rYNPKecFM9TOqih3NiD6GBbKnkktqIFxQ43oUgblyyYyDHLl9XE0oY9aucXD6kVFtWgyG1TMkA-_aO7uESmHFp8PmQ9T6p1OVC66JEqlpQ6aeD_O834ydyTb5eJ52XXgiwxLSmfIkXsWqdveAz159bqXlB1fMvnyvwzmlFRsMjkhw2CRmIjUJddD5KiE061Ay4UN7eY-mQQ5Hj37igKTmECQ_I_twEv-4Banh_vg_3otghQ",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJhcHAiXSwiYXRpIjoiY2QzOTkyMjktZTcwYi00NDZmLWFiMGEtNDYzYjMxYjcxM2MzIiwibmFtZSI6bnVsbCwiaWQiOm51bGwsImV4cCI6MTU5Nzk5NjUwNiwianRpIjoiODA3Y2VmODItYzE5Yi00ZDlkLThkY2YtMzMzMjQyYjNjNGU5IiwiY2xpZW50X2lkIjoiY2hhbmdnb3UiLCJ1c2VybmFtZSI6ImNoYW5nZ291In0.pXb6vD9ZXYrz3bBHfrvbxfQTsjMFTx_5MIIVZaxFMV0U_3wXI_XHnS_zyaOhG-kdHff-T-PjLy32DT72gK44wUfswVlpy8P67ya4ciNedkmJQioxrnyBdoMvSES7eeo2pDyitZYg9wAX017qWwD7J-H5PxLyQjEhwgCaivGTCk4An1MyidqXhhMRWTk78vvuNSFhrb1b-IUpVIdnRyGeLZFUDLESTor2FuRgCrFDSr6S3cgFae1_qoOYoSsR9eiHwViohP0rVqzodwaxyU5W7yWFuBRoKe-BpDbxW5HiWCaQkyaQhvCKsLWFXWyZIjw4MWiA1zCnoD8oQN1KOt-C-A",
    "expires_in": 3599,
    "scope": "app",
    "jti": "cd399229-e70b-446f-ab0a-463b31b713c3"
}

access_token:访问令牌;
token_type:有MAC Token和Bearer Token两种,建议后者;
refresh_token:刷新令牌,使用此令牌可以演唱访问令牌的过期时间;
expires_in:过期时间;
scope范围;
jti当前token的唯一标识

2.1.3 校验令牌

Spring Security Oauth2.0提供了校验令牌的端点:

GET请求http://localhost:9988/oauth/check_token?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJhcHAiXSwibmFtZSI6bnVsbCwiaWQiOm51bGwsImV4cCI6MTU5Nzk5NjUwNiwianRpIjoiY2QzOTkyMjktZTcwYi00NDZmLWFiMGEtNDYzYjMxYjcxM2MzIiwiY2xpZW50X2lkIjoiY2hhbmdnb3UiLCJ1c2VybmFtZSI6ImNoYW5nZ291In0.af-BdA4KA5RPJPJRhyPdumSZRVH8LNQlAxw50XNHCpAhCkfsjW5A12it9RQxvyUv6RQ-Vq2Gi6bvO2Alc29HXEJdyZ9S-Wwv85Uzrt4rYNPKecFM9TOqih3NiD6GBbKnkktqIFxQ43oUgblyyYyDHLl9XE0oY9aucXD6kVFtWgyG1TMkA-_aO7uESmHFp8PmQ9T6p1OVC66JEqlpQ6aeD_O834ydyTb5eJ52XXgiwxLSmfIkXsWqdveAz159bqXlB1fMvnyvwzmlFRsMjkhw2CRmIjUJddD5KiE061Ay4UN7eY-mQQ5Hj37igKTmECQ_I_twEv-4Banh_vg_3otghQ

2.1.4 刷新令牌

刷新令牌是当令牌快过期时重新生成一个令牌,刷新令牌只需要一个刷新令牌、客户端id和客户端密码。

POST请求http://localhost:9988/oauth/token

请求数据为:

grant_type:固定为refresh_token
refresh_token:刷新令牌。

同样地,设置AuthorizationBasic Auth,输入客户端id和客户端密钥。

Spring Security Oauth 2.0第三方授权认证_第7张图片

2.2 密码授权

不再使用授权码获取令牌,而是直接通过用户名和密码即可申请令牌。

测试:

POST请求http://localhost:9988/oauth/token

请求数据为:

grant_type:固定为password
username:用户账号;
password:用户密码;

设置AuthorizationBasic Auth,输入客户端id和客户端密钥。

Spring Security Oauth 2.0第三方授权认证_第8张图片

你可能感兴趣的:(Spring,Cloud,分布式技术,SpringBoot)