OAuth2.0 获取授权
OAuth是一个开放的授权协议
- Authorization Code Grant(RP在授权过程中不知道这个过程,用户在授权端点登陆,授权码post给后台,后台拿到code后获取access_token和userinfo,用户转入RP主页)
- Implicit Grant(适用于无后台应用,如js网站,用户在授权端点登陆,RP直接拿到accsess_token,会暴露给资源所有者或其他应用,因为token是jwt,payload 包含了用户profile)
- Resource Owner Password Credentials Grant(需要用户输入username和password,RP不得保存,仅在1,2授权不可用的情况下)
- Client Credentials Grant(用于机器对机器,没有用户参与,如后台维护工作)
OpenID Connect
OpenID Connect将身份验证实现为OAuth 2.0授权过程的扩展
- Authorisation code flow - 代码流,跳转到授权页面,allow后OP发送code到RP指定的url,RP 后台通过code 再向OP获取id_token和access_token,通过id_token访问UserInfo端点,获取授权码必须走TLS
注意: scope中必须包含openid范围值
- Implicit flow - 隐式流,比如js网站,无后台,授权后直接返回id_token和access_token给RP,易暴露
- Hybrid flow - 混合流,一些令牌是由授权端点返回的,而其他令牌是从令牌端点返回的
ID token
- sub-subject, 用户身份
- iss-issuing authority,发行机构
- aud-audience, client ,受众
- nonce-随机数(避免重放攻击)
- auth-time-何时认证
- acr-强度
- iat-issue at ,发行时间
- exp-expiration time, 过期时间
- name & email address
- 数字签名
- 加密(JWE)
例子
GET /authorize?
response_type=code
&scope=openid%20profile%20email
&client_id=s6BhdRkqt3
&state=af0ifjsldkj
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
Host: server.example.com
HTTP/1.1 302 Found
Location: https://client.example.org/cb?
code=SplxlOBeZQQYbYS6WxSbIA
&state=af0ifjsldkj
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"refresh_token": "8xLOxBtZp8",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5
NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ
fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz
AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q
Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ
NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd
QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS
K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4
XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"
}
Payload
{
"sub" : "alice",
"iss" : "https://openid.c2id.com",
"aud" : "client-12345",
"nonce" : "n-0S6_WzA2Mj",
"auth_time" : 1311280969,
"acr" : "c2id.loa.hisec",
"iat" : 1311280970,
"exp" : 1311281970
}
其他
JWS:JSON Web Signature,Digital signature/HMAC specification(签名)
Authorisation response 中包含了三个部分,header,payload,signature
signature:可以通过JWS签名,保证数据完整,没有被篡改,返回响应中的header包含了alg(加密方式,如HS256)利用服务端的密钥secret通过哈希256(SHA256)HMACSHA256(base64UrlEncode(header)+ “.” + base64UrlEncode(payload),secret(公钥)) 加密取最左128bit,通过jwt网站了解 https://jwt.io/
JWE:JSON Web Encryption,Encryption specification(加密)
加密和解密方采用同一个密钥。采用这种模式的算法就叫做对称加密算法。
加密和解密方采用不同的密钥。采用这种模式的算法就叫做非对称加密算法。
JWK:JSON Web Key,Public key specification
JWA:JSON Web Algorithms,Algorithms and identifiers specification(算法)
JWT:JSON Web Token
获取授权码:
- response_type=code
- client_id 获取授权码不需要client_secret
- scope
- state 防 csrf 攻击
后台服务利用授权码获取token
grant_type=authorization_code
- 带
client_secret
OpenID 连接
OpenID Connect 1.0 是 OAuth 2.0 协议之上的简单身份层。
客户端使用 OAuth 代表用户请求访问 API,但 OAuth 协议中没有任何内容告诉客户端用户信息。 OpenID Connect 使客户端能够访问有关用户的其他信息,例如用户的真实姓名、电子邮件地址、出生日期或其他个人资料信息。
用户的 SSO 体验是通过将 ID 令牌从授权服务器传递到客户端来实现的。
请求中scope=openid
JSON Web Token 结构是什么?
- Header
- Payload
- Signature
因此,JWT 通常如下所示。
xxxxx.yyyyy.zzzzz