OAuth2是一个授权框架, 可以使一个应用程序获取其他HTTP服务, 比如Facebook, 的用户账号的部分权限。 当一个第三方应用程序想要访问用户账号时, OAuth2会把验证的过程委托给含有用户账号信息的应用程序。OAuth2提供了Web, Desktop applications, mobile devices的授权流。
OAuth定义了四种角色:
Resource Owner(资源拥有者):User
资源拥有者, 即授权应用程序访问他们账号的用户。 应用程序对用户账号的权限为授权后的token中scope字段指定的范围。
Resource / Authorization Server(资源提供者/授权服务器): API
资源提供者提供被保护的用户账号的信息, 授权服务器验证用户(资源拥有者)的身份信息, 然后签发access token给应用程序。
Client(客户端): Application
Client即想要访问用户账号的应用程序。 在应用程序访问用户账号之前, 必须获得用户的授权。
在使用OAuth之前, 必须向Authorization Server注册应用程序(application), 注册时需要提供Application name, Application Website, Redirect URI or Callback URL.
应用程序注册完成后, Authorization Server会生成客户端账号信息(client identifier和client secret)。 Client ID是一个公共的字符串被service用来唯一区别应用程序, 以及被用来构建authorization URL; Client secret被用来当应用程序请求访问用户账号时验证应用程序的身份, client secret不能被公开。
OAuth2定义了四种授权类型:
Authorization Code
授权类型authorization code是使用最广泛的因为它是面向服务端应用, 并且源代码不会公开, 因此不会暴露client secret。 它是基于重定向的, 表明应用程序必须可以和用户代理交互并接受通过用户代理展示的授权码。
授权过程如下:
https://cloud.digitalocean.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
https://dropletbook.com/callback?code=AUTHORIZATION_CODE
https://cloud.digitalocean.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL
{"access_token":"ACCESS_TOKEN","token_type":"bearer","expires_in":2592000,"refresh_token":"REFRESH_TOKEN","scope":"read","uid":100101,"info":{"name":"Mark E. Mark","email":"mark@thefunkybunch.com"}}
接下来应用程序就已经被授权了, 应用程序访问被保护用户账号时必须携带access token, 所具有的的权限限定于scope指定的范围。
如果同时返回的还有refresh token, 则当access token过期时可以请求生成新的access token。
Implicit
适用于手机应用或web应用(运行于浏览器中的应用), 这个场景下client secret的安全性得不到保障。这个也是基于重定向的。 这个过程不会验证应用程序的身份, 而是依赖重定向URL验证应用程序的身份。
这个授权方式不支持refresh token。
授权过程:
https://cloud.digitalocean.com/v1/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read
https://dropletbook.com/callback#token=ACCESS_TOKEN
Resource Owner Password Credentials
用户直接提供被保护的用户账号的账号密码给应用程序, 应用程序使用这个账号信息去获取access token。这种授权方式应当仅在其他方式不能使用的时候使用。 并且应该只在可信的应用程序中使用, 比如Authorization server中的程序。
授权链接通常如下:
https://oauth.example.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID
Client Credentials
这种授权方式使得应用程序可以访问它自己的服务账号, 在应用程序需要更新注册信息时有用, 比如描述信息或重定向URI,或者其他信息。
应用程序向authorization server请求access token并携带client id和client secret。
连接通常如下:
https://oauth.example.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET
Access token使用案例:
curl -X POST -H "Authorization: Bearer ACCESS_TOKEN""https://api.digitalocean.com/v2/$OBJECT"
Refresh token使用案例:
https://cloud.digitalocean.com/v1/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
OAuth Scopes
就是授权页面上app请求的权限,这是开发者写死的权限。
示例access_token:
{ "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3", "token_type":"bearer", // token类型 "expires_in":3600,// 如果token有过期时间,则应该在过期时间内使用token "refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk", // 获取新的access_token所用,但是implicit grant没有refresh token "scope":"create"}
https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/
OpenID Connect1.0是基于OAuth2.0协议的简单身份层,允许客户端确定已被Authorization Server验证过的终端用户的身份,以及可以以Restful方式获取终端用户的基本资料(basic profile information).
OpenID Connect允许所有类型的客户端,包括Web, mobile, JavaScript客户端。
OpenID Connect和OpenID2.0做了很多相似的工作,但是OpenID Connect是以一种API友好的方式。
AUth1.0a和OpenID2.0集成需要扩展,而OAuth2.0的功能是集成在OpenID Connect协议中的。
一个完整的Open ID Connect的过程如下:
ID token类似于身份证, 是一个标准的JWT格式的由OpenID Provider(OP)提供的字符串。
ID token中包含的内容:
ID token由header, body, signature三部分组成, 以点(.)分隔,每部分都经base 64转码过。
OpenID Connect授权流:
OpenID Authorisation code flow详解
分为两步: 1, 验证用户, 请求用户同意, 获取授权码, 2, 可选地验证客户端, 使用授权码获取token
一、
重定向用户到OAuth2.0的授权端点(authorisation endpoint)验证用户。 OpenID验证请求实际上是OAuth2.0的获取用户信息的授权请求, 通过在scope中包含openid字段。
HTTP/1.1 302 FoundLocation: https://openid.c2id.com/login? response_type=code &scope=openid &client_id=s6BhdRkqt3 &state=af0ifjsldkj &redirect_uri=https://client.example.org/cb
在OP端检查用户是否已登录, 未登录则提示登录
然后OP会调用客户端应用的redirect_uri并返回authorisation code或者error code
Authorisation code是一个中间码, 客户端应用需要提交这个code到OP获取ID token, 这个可以直接通过后台请求完成, 以避免暴露私密信息和token。
用code交换id token发生在OP的token端点。
Client ID和client secret通过Authorization头部传递, OpenID Connect也支持通过JWT验证。
Token请求通常如下:
POST /token HTTP/1.1Host: openid.c2id.comContent-Type: application/x-www-form-urlencodedAuthorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWgrant_type=authorization_code &code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https://client.example.org/c
如果请求成功, 结果通常是包括ID token, access token和可选的refresh token的json对象。
对于一个基础的OpenID验证请求, 通常只有ID token是需要的, access token可以被忽略, 不过access token也可以用来获取用户的信息, 通过UserInfo端点。
ID token的用途:
OpenID well known endpoint
OIDC providers可以支持’well known’端点, 这是一个包含可以让客户端自行配置的json对象, 有些内容不会变化, 有些会定期变化。
https://xxxx.com/.well-known/openid-configuration
一般情况下, 可以使用OpenId Connect替代OAuth2.
https://connect2id.com/learn/openid-connect#example-auth-code-flow-step-1
https://www.onelogin.com/blog/openid-connect-explained-in-plain-english
https://connect2id.com/learn/openid-connect#example-auth-code-flow-step-1
验证ID Token和Access Token
ID Token验证
Access Token验证
在使用Authorization Code Flow时,如果ID Token包含at_hash
字段,则客户端必须用它取校验Access Token,验证过程和Implicit Flow使用的一样,但是使用的是从Token Endpoint返回的ID Token和Access Token。
验证ID Token和Access Token
验证过程和Authorization Code Flow相同
当使用Hybrid Flow验证流程时,Authorization Endpoint的使用和Authorization Code Flow相同,除了一个参数例外:
response_type
: Oauth2.0 response_type决定了将使用的验证流程。当使用Hybrid Flow时,response_type值可能为code id_token
, code token
或者code id_token token
.
Hybrid Flow Authorization Endpoint返回的值包括以下这些:
access_token
: OAuth2.0 Access Token,当response_type是code token
, code id_token token
时
id_token
: ID Token,当response_type是code id_token
或者code id_token token
时
code
: Authorization Code, Hybrid Flow总是返回这个。
示例:
GET /authorize?response_type=code id_token&client_id=s6BhdRkqt3&redirect_uri=https://client.example.org/cb&scope=openid profile email&nonce=n-0S6_WzA2Mj&state=af0ifjsldkj HTTP/1.1Host: server.example.com
HTTP/1.1 302 Found Location: https://client.example.org/cb# code=SplxlOBeZQQYbYS6WxSbIA &id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso &state=af0ifjsldkj
想必看到这里大家也明白了Hybrid混合的意思。即可以返回多个token和code, code还可以用来向token Endpoint请求access_token。
Id_token和access_token的验证方式和上文一样。
code
校验流程:
https://openid.net/specs/openid-connect-core-1_0.htm
来源:https://www.icode9.com/content-4-786201.html联系客服