Skip to main content

OAuth

Tips

  • JWT 验证
  • Auth 2.0 vs JWT
  • OAuth and OpenID Connect for Microservices
    • OAuth is a scalable delegation protocol
    • OAuth 4 actors
      • Resource Owner (RO)
        • User
      • Authorization Server (AS)
      • Client
        • App/Backend
      • Resource Server (RS)
        • Gmail
    • Client -> AS -> RO(浏览器) -Token-> Client -> RS -> AS -> Client
    • 客户端对用户无感知, 主要用于基于客户端的方式访问用户资源
    • 当有后端服务的时候流程会有所不同
      • 后端服务需要对用户资源发起请求
      • 会对用户有感知
      • 建立了信任关系
      • 基于 Token 进行资源请求
      • Token 例如 JWT, 有用户信息
    • 基于引用的令牌
      • 例如 UUID
      • 不包含任何用户信息
      • 用于外部
    • 基于值的令牌
      • 例如 JWT
      • 包含了所有必要的信息
      • 用于内部
    • 在微服务中由网关将基于引用的令牌转换为基于值的令牌在服务内部使用
  • OpenID Connect / OIDC
    • 是在 OAuth2 之上的协议
  • OAuth2 中会有一个 Token
    • JWT 可以当做是其中一种
  • API 中的的两个主要问题
    • 访问控制
      • 认证/用户标示
      • 授权/权限
    • 数据
      • 文档
      • 一致格式
      • 有效的服务
  • 实现

https://oauth.net/2/grant-types/

  • response_type
    • code

https://auth0.com/docs/api-auth/which-oauth-flow-to-use

OAuth 2.0

强项

  • 快速开发
  • 只需要少量的代码即可实现
  • 减少管理

限制

  • 授权交由第三方

授权类型

  • Guide To OAuth 2.0 Grants
  • Authorisation Code Grant
    • 类似于使用 Facebook 或者 Google 账号登陆
    • 流程#1
      • 客户端重定向用户到 AS
        • response_type=code
        • client_id
        • redirect_uri
          • 该参数可选
          • 指定成功后的重定向地址
          • 如果不指定一般则使用预设的
        • scope
          • 空格分割的请求 scope
        • state
          • CSRF token
          • 该参数可选, 但建议尽量使用, 用于确认是否是正确的回调信息
      • 用户登录,并批准申请的权限
      • 重定向到用户指定的地址
        • code
          • 授权码
        • state
          • 之前的 state, 验证和发起请求前的是否匹配
    • 流程#2
      • 客户端对 AS 发起 POST 请求
        • grant_type=authorization_code
        • client_id
        • client_secret
        • redirect_uri
        • code
          • 之前重定向时拿到的授权码
      • 服务器返回 JSON
        • token_type
          • 一般为 Bearer
        • expires_in
          • access_token 的 ttl
        • access_token
        • refresh_token
          • 如果请求了
          • 用于刷新 access_token 的 token
  • Implicit grant
    • 类似于授权码授权
    • 主要用于基于用户代理客户端的模式(例如: 单页应用),客户端不应持有 client_secret 的情况,因为客户端存储不安全
    • 不同于 authorization_code 返回授权码再去请求 access_token 的形式, implicit 直接返回 access_token
    • 流程
      • 客户端重定向用户到 AS
        • response_type=token
        • client_id
        • redirect_uri
        • scope
        • state
      • 重定向到指定的地址
        • token_type=Bearer
        • expires_in
        • access_token
        • state
  • Resource owner credentials grant
    • 主要用于可信任的客户端授权
    • 流程
      • 客户端向用户索要授权凭证,一般为账号密码
      • 客户端发送 POST 请求到 AS
        • grant_type=password
        • client_id
        • client_secret
        • scope
        • username
        • password
      • AS 返回 JSON
        • token_type=Bearer
        • expires_in
        • access_token
        • refresh_token
  • Client credentials grant
    • OAuth2 中最简单的授权
    • 主要用于后端到后端的授权, 不需要使用用户权限的情况
    • 流程
      • 客户端发送 POST 到 AS
        • grant_type=client_credentials
        • client_id
        • client_secret
        • scope
      • AS 返回 JSON
        • token_type=Bearer
        • expires_in
        • access_token
  • Refresh token grant
    • 授权令牌最终会失效, 如果客户端请求了 refresh_token, 则可以在不需要重定向用户的前提下更新授权令牌
    • 流程
      • 客户端发送一个 POST 请求到 AS
        • grant_type=refresh_token
        • refresh_token
        • client_id
        • client_secret
        • scope
          • 可选
          • 如果没有则使用之前的
          • 可以设置为之前 scope 的子集
      • AS 返回 JSON
        • token_type=Bearer
        • expires_in
        • access_token
        • refresh_token
  • Extension Grants
    • 客户端可以指定 grant_type 为 AS 定义的绝对 URI 来使用自定义的授权方式
      • grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer
        • 使用 OAuth-SMAL2

OICD

JWT

强项

  • 快速开发
  • 不需要 Cookie
  • JSON 相对友好
  • 不依赖社交登陆
  • 概念简单易于理解

限制

  • Token 有大小限制
  • Token 不能被回收
  • 需要 Token 有个较短的失效周期
字段全称含义
issIssuer发出者
subSubject一般为用户 id
audAudience接受者
expExpiration time失效时间
nbfNot before在这之前不生效
iatIssued at发出时间
jtiJWT ID
typType类型,由用户扩展

常见算法

  • HMAC + SHA256
  • RSASSA-PKCS1-v1_5 + SHA256
  • ECDSA + P-256 + SHA256
  • RSA vs ECDSA
    • 同等安全度下
      • RSA 更长, 签名验证更快
      • ECDSA 更短, 生成签名和密钥时快得多

示例

{
"iss": "http://example.org",
"aud": "http://example.com",
"iat": 1356999524,
"nbf": 1357000000
}
{
"iss": "https://oidc.my.com",
"x5t": "AAAAAAAAAAAAAAAAAAAA"
"typ": "JWT"
"alg": "RS265"
}

{
"sub": "wener"
"name": "Wener"
"email": "wener@wener.me"
"phone_number": "1852159826715"
"aud": "https://otheremail.com"
"iss": "https://oidc.my.com"
"nbf": 1497868409096
"jti": "ANpzy7AyyANx0Cn8WMP5N7bG3E8awOhB"
"exp": 1497868509096
"nbf": 1497868409096
}

PAST

  • https://github.com/paragonie/past
  • Platform-Agnostic Security Tokens
  • 目的
    • JWT 的 alg 不太安全, 因为有一些加密算法安全性本身不高, 甚至可以使用 none
v2.local.wvbu1sWg-Td2nDxn7vyAVAEzTGqtzn_zfzaiGjAkQzfa5-l2PaAK1QA0IZjrWdKP8Xqi7DHHlu6F8E5BXoarTSfmrgkMEOeiasRhuZ3GWDUtmD2K027gjgalkjMZJE7lNfkOSdKr65Fo0_8.UGFyYWdvbiBJbml0aWF0aXZlIEVudGVycHJpc2Vz
  • 版本: v2
  • 目的: local
  • 内容
c2f6eed6c5a0f937769c3c67eefc805401334c6aadce7ff37f36a21a30244337
dae7e9763da00ad500342198eb59d28ff17aa2ec31c796ee85f04e415e86ab4d
27e6ae090c10e7a26ac461b99dc658352d983d8ad36ee08e06a5923319244ee5
35f90e49d2abeb9168d3ff
  • Nonce: c2f6eed6c5a0f937769c3c67eefc805401334c6aadce7ff3
  • Authentication tag: 3319244ee535f90e49d2abeb9168d3ff
  • 解码后的内容
{
"data": "this is a signed message",
"exp": "2039-01-01T00:00:00"
}
  • Key: 707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f

GitHub

curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com/users/wenerme -I
HTTP/1.1 401 Unauthorized
Date: Tue, 02 Jan 2018 05:08:34 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 93
Server: GitHub.com
Status: 401 Unauthorized
X-GitHub-Media-Type: github.v3; format=json
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1514873228
Access-Control-Expose-Headers: ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
Access-Control-Allow-Origin: *
Content-Security-Policy: default-src 'none'
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-XSS-Protection: 1; mode=block
X-Runtime-rack: 0.011490
X-GitHub-Request-Id: C390:1E82:97CD8EB:B8B4F1D:5A4B13D1

Auth0

NOTES

  • 客户端

    • 名字
    • 域名
    • Client ID
    • Client Secret
    • 描述
    • Logo - 150x150
    • 类型
      • 原生
      • 非交互应用
      • 一般网页应用
      • 单页应用
    • Token Endpoint Authentication Method
      • Basic
      • Post
    • Allowed Callback URLs
    • Allowed Web Origins
    • Allowed Logout URLs
    • Allowed Origins (CORS)
    • JWT Expiration = 36000
    • Use Auth0 instead of the IdP to do Single Sign On
    • 高级设置
      • 应用元数据
      • 移动设置
        • IOS
          • Team ID
          • App bundle identifier
        • Android
          • App Package Name
          • Key Hashes
      • OAuth
      • Allowed APPs / APIs
      • JsonWebToken Signature Algorithm
        • HS256
        • RS256
      • OIDC 适配
      • Cross-Origin Verification Fallback
      • 授权类型
        • Implicit
        • Authorization Code
        • Refresh Token
        • Client Credentials
        • Password
        • MFA
        • Legacy: RO
        • Legacy: RO jwt-bearer
        • Legacy: Delegation Refresh Token
        • Legacy: Delegation ID Token
        • Legacy: Access Token
      • WS-Federation
      • Certificates
      • Endpoints
  • 链接

    • 实际存储用户
    • 提供
      • 用户导入
      • 社交
      • 企业
  • 用户

  • 数据库

    • 用户策略
      • 是否需要用户名
        • 长度限制
      • 是否允许注册
    • 密码策略
      • 密码强度
        • Low
          • 6 位
        • Fair
          • 8 位
          • 至少包含 小写字母, 大写字母, 数字
        • Good
          • 8 位
          • 至少包含三类: 小写, 大写, 数字, 特殊字符
        • Excellent
          • 10 位
          • 至少包含三类: 小写, 大写, 数字, 特殊字符
          • 最多 128
          • 连续相同字符不能超过两位
      • 密码历史
        • 历史大小
          • 最多 24
      • 密码字典
      • 个人数据
        • 不允许使用包含在其他字段的信息
    • 自定义数据库
      • 模板
        • ASP.NET Membership Provider MVC3 - Universal Providers
        • ASP.NET Membership Provider MVC4 - Simple Membership
        • MongoDB
        • MySQL
        • Oracle
        • PostgreSQL
        • SqlServer
        • Windows Azure SQL Database
        • Request with Basic Auth
        • Storm Path
      • 操作
        • 登陆 - email, password
        • 创建 - user{password, email}
        • 验证 - email
          • 注册, 邮箱验证, 密码重置, 删除用户
        • 修改密码 - email, newPassword
        • 获取用户 - email
          • {user_id, nickname, email, name, given_name, family_name}
        • 删除 - id
      • 使用 bcrypt/10 加密
      • nodejs
      • 配置 SQL 语句
      • 支持配置属性
  • 社交

    • Google
      • https://console.developers.google.com/projectselector/apis/credentials
      • Client ID
      • Client Secret
      • Allowed Mobile Client IDs
      • Attributes
        • Basic Profile
          • 邮箱和邮箱验证标识
        • Extended Profile
          • 必选
      • 权限
        • Contacts
        • Blogger
        • Calendar
        • Gmail
        • Google+
        • Orkut
        • Picasa Web
        • Tasks
        • YouTube
        • Adsense Management
        • Google Affiliate Network
        • Analytics
        • Google Books
        • Google Cloud Storage
        • Content API for Shopping
        • Chrome Web Store
        • Document List
        • Google Drive
        • Google Drive Files
        • Latitude (Best)
        • Latitude (City)
        • Moderator
        • Sites
        • Spreadsheets
        • URL Shortener
        • Webmaster Tools
        • Coordinate
        • Coordinate (read only)
    • Facebook
    • GitHub
      • Client ID
      • Client Secret
      • Attributes
        • Basic Profile
        • Email address
      • 权限
    • 新浪微博
      • App Key
      • App Secret
      • Attributes
        • Basic Profile
        • Email, 默认未选中
      • 权限
        • direct_messages_write
        • direct_messages_read
        • friendships_groups_write
        • friendships_groups_read
        • invitation_write
    • 百度
      • API Key
      • Secret Key
      • Attributes
        • Basic Profile
    • Twitter
      • https://apps.twitter.com/
      • Consumer Key
      • Consumer Secret
      • Attributes
        • Basic Profile
          • name, picture, signup date, twitter description, language, location, twitter screen name, time zone, URL, timezone and verified account.
          • 目前不提供用户邮箱
  • 企业

    • AD/LDAP
    • ADFS
    • IP
    • PingFederate
    • SAMLP Identity Provider
    • SharePoint Apps
    • Google Apps
    • Office 365
    • Microsoft Azure AD
  • 无密码

    • 短信
      • Twilio SID
      • Twilio AuthToken
      • SMS Source
        • Copilot
          • Copilot SID
        • From
          • 好嘛
      • 语法
        • Liquid
        • Markdown
    • 邮箱
    • TouchID
  • 托管页面

    • 登陆
    • 密码重置
  • 邮件

    • 模板
      • 验证
      • 欢迎
      • 注册
      • 修改密码
      • 密码修改提示
      • 禁用提示
    • 提供商
      • MANDRILL
      • AWS
      • SendGrid
      • SMTP
        • From
        • Host
        • Port
        • Username
        • Password
  • Logs

    • 概况
      • 时间
      • 描述
      • 日期
      • 链接
      • 客户端
      • 应用
      • 用户
    • 元数据
    • 上下文数据
      • 应该为 Referer

元数据

{
"date": "2018-01-02T07:59:06.836Z",
"type": "f",
"description": "the connection was disabled",
"connection": "wener",
"connection_id": "con_lXyPhu5jR9BjYNg6",
"client_id": "bm4susnnbqtysjSoTuWMqgqhkFQa8dBg",
"ip": "47.89.37.179",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36",
"details": {
"body": {},
"qs": {
"client_id": "bm4susnnbqtysjSoTuWMqgqhkFQa8dBg",
"response_type": "code",
"connection": "wener",
"prompt": "consent",
"redirect_uri": "https://manage.auth0.com/tester/callback?connection=wener",
"scope": "openid profile"
},
"connection": "wener",
"error": {
"message": "the connection was disabled",
"oauthError": "invalid_request",
"type": "request-error"
}
},
"log_id": "49574419589858254662358307566469418022270857965582942242"
}

上下文数据

{
"body": {},
"qs": {
"client_id": "bm4susnnbqtysjSoTuWMqgqhkFQa8dBg",
"response_type": "code",
"connection": "wener",
"prompt": "consent",
"redirect_uri": "https://manage.auth0.com/tester/callback?connection=wener",
"scope": "openid profile"
},
"connection": "wener",
"error": {
"message": "the connection was disabled",
"oauthError": "invalid_request",
"type": "request-error"
}
}

Hydra