OAuth2.0 实现单点登录(四种授权方式)

本文详细解释了OAuth2.0的四种主要授权模式:客户端模式、密码模式、隐式授权模式和授权码模式,强调了每种模式的适用场景、流程以及安全性考虑。特别关注了如何处理用户凭据、令牌管理和安全风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、四种授权模式
1、客户端模式(Client Credentials)

指客户端以自己的名义,而不是以用户的名,向“服务提供商”进行认证。严格的说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求“服务提供商”提供服务,其实不存在授权问题。

流程:

操作步骤说明:

【步骤1】【步骤2】客户端向授权服务器进行身份认证,并申请访问令牌(access_token)

【步骤3】授权认证服务器验证通过后,向客户端提供访问令牌(access_token)

【步骤4】客户端向资源服务器发出请求资源的请求

【客户端5】【客户端6】服务提供商的资源服务器返回数据给客户端使用

客户端发出的HTTP请求,包含一下参数:

参数

说明

client_id

客户端ID,必选项

client_secret

客户端秘钥,必选项

grant_type

使用的授权模式,必选项,此处的值固定为“client_credentials”

举例:

https://oauth.example.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

客户端模式说明:

服务提供者验证通过以后,直接返回令牌。这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。因此这就要求我们对client完全的信任,而client本身也是安全的。所以这种模式一般用来提供给我们完全信任的服务器端服务。比如,合作方系统对接,拉去一组用户信息。客户端模式适用于没有用户参加的,完全信任的一方或合作方服务器端程序接入。

2、密码模式(Resource Owner Password Credentials)

使用用户名/密码作为授权方式从授权服务器上获取令牌,一般不支持刷新令牌。这种方式风险很大,用户向客户端提供自己 的用户名和密码。客户端使用这些信息,向“服务提供商”索要授权。这种方式通常用于可信任的应用程序,比如用户拥有自己的资源服务器并且信任应用程序直接使用其凭据。

流程:

操作步骤说明:

【步骤1】【步骤2】用户向第三方客户端提供,其在服务提供商那里注册的用户名和密码

【步骤3】客户端将用户名和密码发送给授权服务器,向授权服务器请求访问令牌(access_token)

【步骤4】授权认证服务器确认身份无误后,向客户端提供访问令牌(access_token)

【步骤5】客户端携带access_token向资源服务器发出请求资源的请求

【步骤6】【步骤7】服务提供商的资源服务器返回数据给客户端使用

客户端拿着资源拥有者的用户名、密码向授权服务器请求令牌(access_token),包含如下参数:

参数

说明

client_id

客户端ID,必选项

client_secret

客户端秘钥,必选项

grant_type

使用的授权模式,必选项,此处的值固定为“password”

username

资源拥有者的用户名,必选项

password

资源拥有者的密码,必选项

举例:

https://oauth.example.com/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=password&username=USERNAME&password=PASSWORD

密码模式说明:

密码模式的优点是他的实现相对简单,适用于那些已经具有高度信任度的应用程序,例如移动应用程序或第一方Web应用程序。然而,密码模式也存在一些安全风险,因为他要求客户端直接处理用户的凭据,这可能会增加密码泄露的风险。因此,在使用密码模式时,必须非常小心的保护客户端的安全性,例如使用安全的存储和传输机制来处理用户凭据。

3、隐式授权模式(Implicit Grant)

首先用户访问页面时,会重定向到认证服务器,接着认证服务器给用户一个认证页面,等待用户授权,用户填写信息完成授权后,认证服务器返回token。

流程:

操作步骤说明:

【步骤1】【步骤2】用户访问客户端,需要使用服务提供商的数据(用户信息),客户端通过重定向跳转到服务提供商的页面

【步骤3】用户选择是否给予 客户端授权访问 服务提供商(用户信息)数据的权限

【步骤4】用户给予授权后,授权系统通过重定向(redirect_ui)并携带 访问令牌(access_token)跳转回客户端。

【步骤5】客户端携带access_token向资源服务器发出请求资源的请求

【步骤6】【步骤7】服务提供商的资源服务器返回数据给客户端使用

关键步骤:

步骤2:客户端申请认证的url,包含一下参数:

参数

说明

client_id

客户端ID,第三方应用注册的ID,用于身份认证,必选项

response_type

授权类型,必选项,此处的值固定为“token”

redirect_uri

重定向URI,接受或拒绝请求后的跳转网址,可选项

scope

申请的授权范围,可选项

state

客户端的当前状态,可以指定任意值,认证服务器会原封不动的返回这个值

示例:A网站提供一个链接,用户点击后就会跳转到B网站,授权用户数据给A网站使用。下面就是A网站跳转B网站的一个示意链接:

https://b.com/oauth/authorize?client_id=p2pweb&response_type=token&scope=app&redirect_uri=http://xx.xx/notify

步骤3:用户跳转后,B网站会要求用户登录,然后询问是否同意给予A网站授权(此过程也可以自动授权,用户无感知)

步骤4:授权服务器将授权码将令牌(access_token)以Hash的形式存放在重定向uri的fargment中发送给浏览器。认证服务器回应客户端的URI,包含一下参数:

参数

说明

access_token

访问令牌,必选项

token_type

令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型

expires_in

过期时间,单位为秒,如果省略该参数,必须使用其他方式设置过期时间

scope

权限范围,如果与客户端申请的范围一致,此项可省略

state

如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数

示例:

https://server.example.com/cb#access_token=ACCESS_TOKEN&state=xyz&token_type=example&expires_in=3600

https://a.com/callback#token=ACCESS_TOKEN

拓展:

1、Bearer Token(持有者令牌):Bearer类型的令牌是OAtuth2.0中最常见的一种类型。当客户端获得了Bearer令牌后,可以将其附和在请求的Authorization头部中,格式为“Bearer”,然后发送给资源服务器,以获取对受保护资源的访问。Bearer令牌通常以明文形式传输,因此在传输过程中需要采取适当的安全措施,如使用HTTPS

2、MAC Token(消息身份验证代码令牌):MAC类型的令牌也是一种用于访问受保护资源的令牌类型。MAC令牌采用了基于消息身份验证代码(Message Authentication Code ,MAC)的机制来验证客户端的请求,相比Bearer令牌更加安全。MAC令牌将访问令牌与秘钥相关联,并使用该秘钥进行签名,以确保请求的完整性和真实性。MAC令牌通常用于对安全性要求更高的场景。

3、在隐式授权模式中,当用户进行身份验证并授权后,授权服务器会将访问令牌直接返回给客户端。为了安全考虑,OAuth2.0规范建议将令牌放在URL锚点中,而不是放在查询字符串中。URL锚点是URL的一部分,用于标识页面中的特定位置,例如http://example.com/page#section.在浏览器发起HTTP请求时,锚点部分不会包含在请求中发送到服务器,这意味着在客户端和服务器之间传输时不会将令牌暴露给潜在的中间人(例如网络监听器或代理服务器)。因此,及时通过HTTP协议传输,也可以减少泄露令牌的风险。相比之下,查询字符串是URL中的一部分,用于传输参数给服务器,例如https://example.com/page?token=abc123.查询字符串中的参数会在HTTP请求中明文传输到服务器,存在被拦截和窃取的风险。因此,将访问令牌作为URL锚点的一部分返回给客户端,是为了增加安全。

4、授权码模式(Authrization Code)

第三方应用先申请一个授权码code,然后通过code获取令牌Access Token

授权码模式是功能最完全,流程最严密安全的授权模式。他的特点就是通过客户端的后台服务器,与“服务提供商”的认证服务器进行互动,access_token不会经过浏览器或移动端的App,而是直接从服务端去校验,这样就最大限度的减少了令牌泄露的风险。

流程:

操作步骤说明:

【步骤1】【步骤2】用户访问客户端,需要使用服务提供商的数据(用户信息),客户端通过重定向跳转到服务提供商页面。

【步骤3】用户选择是否给予客户端授权访问服务提供商(用户信息)数据的权限

【步骤4】用户给予授权。权限系统通过重定向(redirect_uri)并携带 授权凭证(code)跳转回客户端。

【步骤5】【步骤6】客户端将授权凭证(code)发送给客户端服务器,客户端服务器携带授权码(code)、客户端id(client_id)和秘钥(client_secret)向认证服务器请求访问令牌(access_token)

【步骤7】【步骤8】认证服务器核对授权码信息,确认无误后,向客户端服务器发送访问令牌(access_token)和更新令牌(refresh_token),然后这些信息在由客户端服务器发送给客户端

【步骤9】【步骤10】客户端持有访问令牌(access_token)和需要请求的参数向客户端服务器发起资源请求,然后客户端服务器在向服务提供商的资源服务器请求资源

【步骤11】【步骤12】【步骤13】服务提供商的资源服务器返回数据给客户端服务器,然后在回传给客户端使用

上述流程:只有第二步需要用户手动进行授权,之后的流程都是客户端的后台和认证服务器后台之间进行“静默”操作,对于用户来说是无感知的

关键步骤:

步骤2:客户端申请认证url,包含一下参数

参数

说明

client_id

客户端ID,第三方应用注册的ID,用于身份认证,必选项

response_type

授权类型,必选项,此处的值固定为“code”

redirect_uri

重定向URI,接受或拒绝请求后的跳转网址,可选项

scope

申请的授权范围,可选项

state

客户端的当前状态,可以指定任意值,认证服务器会原封不动的返回这个值

示例:A 网站提供一个链接,用户点击后就会跳转到 B 网站,授权用户数据给 A 网站使用。下面就是 A 网站跳转 B 网站的一个示意链接:

https://b.com/oauth/authorize?client_id=p2pweb&response_type=token&scope=app&redirect_uri=http://xx.xx/notify

response_type参数表示要求返回授权码(code)

client_id参数让B网站知道是谁在请求

redirect_uri参数是B网站接受或拒绝请求后的跳转网址

scope参数表示要求的授权范围

步骤3:用户跳转后,B网站会要求用户登录,然后询问是否同意给予A网址授权(此过程也可以自动授权,用户无感知)

步骤4:服务器回应客户端的url,包含一下参数:

参数

说明

code

授权码,必选项。该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应的关系

state

如果客户端的请求中包含这个参数,认证服务器的回应也应该一模一样包含这个参数

示例:在第2步用户同意之后,这时B网站就会跳回redirect_uri参数指定的网址。跳转时,会传回一个授权码,就像下面一样。

https://a.com/callback?code=AUTHORIZATION_CODE

步骤6:客户端向认证服务器申请令牌

参数

说明

client_id

客户端ID,必选项

client_secret

客户端秘钥,必选项

grant_type

使用的授权模式,必选项,此处的值固定位“authorization_code"

code

授权码,就是刚刚获取的授权码,必选项。

注意:授权码只使用一次就无效了,需要重新申请

redirect_uri

重定向uri,必选项。且必须和申请授权码时用的redirect_uri一致

示例:在第6步骤中,A网站拿到授权码以后,就可以在后端,向B网站请求令牌

https://b.com/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

client_id参数和client_secret参数哟用来让B确认A的身份(client_secret参数是保密的,因此只能在后端发起请求)

grant_type参数的值是authorization_code,表示采用的授权方式是授权码

code参数是上一步拿到的授权码

redirect_uri参数是令牌颁发后的回调地址。

步骤7:认证服务器发送的HTTP回复,包含以下参数:

参数

说明

access_token

访问令牌,必选项

token_type

令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型

expires_in

过期时间,单位为秒,如果省略该参数,必须使用其他方式设置过期时间

refresh_token

更新令牌,用来获取下一次的访问令牌,可选项。

scope

权限范围,如果与客户端申请的范围一致,此项可省略

示例:在第7步骤中,B网站收到请求后,就会颁发令牌。具体做法是向 redirect_uri 指定的网址,发送一段JSON数据:

HTTP/1.1 200 OK

Content-Type: application/json;charset=UTF-8

Cache-Control: no-store

Pragma: no-cache

{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read","uid":100101,"info":{...}

上面JSON数据中,access_token字段就是令牌。注意:HTTP头信息中明确指定不得缓存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值