在开始之前,首先介绍一下认证和授权。
身份认证
用户访问系统资源时,系统要求验证用户的身份信息,身份合法则方可继续访问。常见的用户身份认证的表现形式有:
用户授权
用户认证通过后去访问系统的资源,系统会判断当前用户是否拥有访问资源的权限,只允许访问有权限的资源,没有权限的资源无法访问。
单点登陆是指用户在一个系统中登陆之后,就可以访问所有相互信任的应用系统。分布式系统要实现单点登陆,通常是将认证系统独立 抽取出来。
OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问它们存储在另外的服务提供者上的信息,而不需要将用户名和 密码提供给第三方移动应用或分享它们数据的所有内容。
Spring Security Oauth 2.0的两种常用的认证模式:
授权码授权模式认证的流程如下图所示。
请求认证服务获取授权码:
GET请求
:http://localhost:9988/oauth/authorize?client_id=changgou&response_type=code&scop=app&redirect_uri=http://localhost
参数介绍:
请求后跳转到如下界面
输入客户端id和密钥,登陆
点击Authorize
获取授权码。
拿到授权码后,接下来就可以申请令牌了:
POST请求
:http://localhost:9988/oauth/token
请求数据为:
grant_type
:授权类型,填写authorization_code
表示是授权码模式;
code
:上一步操作获取的授权码ykF4gQ
,注意,授权码只能使用一次;
redirect_uri
:申请授权码时要跳转的uri,一定要和申请授权码时用的redirect_uri保持一致http://localhost。
同时,设置Authorization
为Basic Auth
,输入客户端id和客户端密钥。
获取到的令牌如下:
{
"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的唯一标识
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
刷新令牌是当令牌快过期时重新生成一个令牌,刷新令牌只需要一个刷新令牌、客户端id和客户端密码。
POST请求
:http://localhost:9988/oauth/token
请求数据为:
grant_type
:固定为refresh_token
;
refresh_token
:刷新令牌。
同样地,设置Authorization
为Basic Auth
,输入客户端id和客户端密钥。
不再使用授权码获取令牌,而是直接通过用户名和密码即可申请令牌。
测试:
POST请求
:http://localhost:9988/oauth/token
请求数据为:
grant_type
:固定为password
;
username
:用户账号;
password
:用户密码;
设置Authorization
为Basic Auth
,输入客户端id和客户端密钥。