简易概述
- 读本文需要有 OAuth 2.0 基础
- 借鉴 OAuth2.0 与 CAS(也叫做野鸡方案)
- 目前只有:授权码模式(Authorization Code)
- 不支持确认授权和 scope,因为理论上内部的权限有独立的 UPMS 控制,这里只要单纯的做好认证即可。
主要参考资料
- https://tools.ietf.org/html/rfc6749
- https://oauth.net/2/
- https://www.oauth.com/
- https://developer.okta.com/docs/api/resources/oidc
要点
整个环节组成部分
- 一个:认证系统(登录系统)
- N 个:应用系统(业务系统、client 系统)
- 认证系统全程 HTTPS
- 限流
- 分布式缓存
- 支持横向扩展
client 系统注册需要填写
- 客户端名称
- 客户端描述
- 客户端应用根域名
- 客户端回调地址
下文 demo 账号
- client_id = sso_client_test
- client_secret = cccllliieeennnttsssseeecccrreeettt
- 业务系统域名:https://www.gitnavi.com
授权码模式流程
用户未认证,业务系统触发授权码第一步
- GET 请求(业务系统重定向)
- 请求地址: https://sso.youmeek.com/oauth/authorize
- URL 参数说明
response_type=code client_id=sso_client_test redirect_uri=https://www.gitnavi.com/oauth/callback/aaaaaaaaaaa state=SSSTTTAAAATTEEE
https://www.gitnavi.com/oauth/callback/aaaaaaaaaaa
用户提交用户名和密码
https://www.gitnavi.com/oauth/callback/aaaaaaaaaaaaaaaaaa?code=CCCCOOOODDDDEEEE&state=SSSTTTAAAATTEEE
业务系统回调地址端点,触发授权码第二步
- POST 请求
- 请求地址: https://sso.youmeek.com/oauth/token
- application/x-www-form-urlencoded 参数(原生表单参数)
grant_type=authorization_code code=CCCCOOOODDDDEEEE redirect_uri=https://www.gitnavi.com/oauth/callback client_id=sso_client_test client_secret=cccllliieeennnttsssseeecccrreeettt
请求参数合法,认证系统返回
- 状态码 200
- JSON 数据
{ "access_token":"aaaaccccceeessssstttttoookkkeeennn", "token_type":"bearer", "expires_in":3600, "refresh_token":"rrrreeefffrrreeeessshhhtttoookkkeeennnn" }
请求参数不合法,认证系统返回
- 状态码 400
- JSON 数据
{ "error": "invalid_request", "error_description": "Request was missing the 'redirect_uri' parameter.", "error_uri": "See the full API docs at https://authorization-server.com/docs/access_token" }
业务系统拿到 access_token
Authorization: Bearer aaaaccccceeessssstttttoookkkeeennn
invalid_request (HTTP 400) – The request is missing a parameter, or is otherwise malformed. invalid_token (HTTP 401) – The access token is expired, revoked, malformed, or invalid for other reasons. The client can obtain a new access token and try again.
通过 refresh_token,获取新的 access_token
- POST 请求
- 请求地址: https://sso.youmeek.com/oauth/token
- application/x-www-form-urlencoded 参数(原生表单参数)
grant_type=refresh_token refresh_token=rrrreeefffrrreeeessshhhtttoookkkeeennnn client_id=sso_client_test client_secret=cccllliieeennnttsssseeecccrreeettt
请求参数合法,认证系统返回
- 状态码 200
- JSON 数据
- 这里一个细节:不会有 refresh_token,但是旧的 refresh_token 是依旧有效的,所以客户端要自己保持好用户的 refresh_token
{ "access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3", "token_type":"bearer", "expires_in":3600 }
请求参数不合法,认证系统返回
- 状态码 400
- JSON 数据
{ "error": "invalid_request", "error_description": "Request was missing the 'redirect_uri' parameter.", "error_uri": "See the full API docs at https://authorization-server.com/docs/access_token" }
验证 access_token / refresh_token 有效性
- POST 请求
- 请求地址: https://sso.youmeek.com/oauth/introspect
- application/x-www-form-urlencoded 参数(原生表单参数)
client_id=sso_client_test client_secret=cccllliieeennnttsssseeecccrreeettt token=aaaaccccceeessssstttttoookkkeeennn token_type_hint=access_token
-
token_type_hint,可选值
access_token refresh_token
请求参数合法,并且是 access_token 类型,认证系统返回
- 状态码 200
- JSON 数据
{ "active" : true, "token_type" : "bearer", "client_id" : "sso_client_test", "username" : "john.doe@example.com", "exp" : 1451606400,( token 过期时间,Unix 时间戳格式) "iat" : 1451602800(token 创建时间, Unix 时间戳格式。所以剩余多少时间,客户端要自己算) }
请求参数合法,并且是 refresh_token 类型,认证系统返回
{ "active" : true, "token_type" : "bearer", "client_id" : "sso_client_test", "username" : "john.doe@example.com", "exp" : 1451606400,( token 过期时间,Unix 时间戳格式) "iat" : 1451602800(token 创建时间, Unix 时间戳格式。所以剩余多少时间,客户端要自己算) }
请求参数不合法,认证系统返回
- 状态码 401
- JSON 数据
{ "error" : "invalid_client", "error_description" : "No client credentials found." }
获取 access_token 对应的用户信息
- GET 请求
- 支持多种请求参数方式
- 请求地址: https://sso.youmeek.com/oauth/userinfo
-
参数方式(两种方式都用,则以请求头的为准):
Authorization: Bearer aaaaccccceeessssstttttoookkkeeennn ?access_token=aaaaccccceeessssstttttoookkkeeennn
请求参数合法,认证系统返回
- 状态码 200
- JSON 数据
{ "sub": "00uid4BxXw6I6TV4m0g3", "name" :"John Doe", "nickname":"Jimmy", "given_name":"John", "middle_name":"James", "family_name":"Doe", "profile":"https://example.com/john.doe", "zoneinfo":"America/Los_Angeles", "locale":"en-US", "updated_at":1311280970, "email":"john.doe@example.com", "email_verified":true, "address" : { "street_address":"123 Hollywood Blvd.", "locality":"Los Angeles", "region":"CA", "postal_code":"90210", "country":"US" }, "phone_number":"+1 (425) 555-1212" }
请求参数不合法,认证系统返回
- 状态码 401
- JSON 数据
{ "error" : "invalid_client", "error_description" : "No client credentials found." }
业务系统触发登出
- 不考虑单点登出的场景
- GET 请求
- 请求地址: https://sso.youmeek.com/logout?redirect_uri=http://www.gitnavi.com/u/judasn
- 认证系统删除当前浏览器用户下 sso_token 的 cookie
- 业务系统删除自己的用户信息缓存
第三方接入,以 grafana 为例
[auth.generic_oauth] enabled = true client_id = sso_client_test client_secret = cccllliieeennnttsssseeecccrreeettt scopes = auth_url = https://sso.youmeek.com/oauth/authorize token_url = https://sso.youmeek.com/oauth/token api_url = https://sso.youmeek.com/oauth/userinfo allowed_domains = http://www.gitnavi.com allow_sign_up = true
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。