OAuth 2.0的一些问题

OAuth2或者OIDC是一个比较复杂的问题,但是很多人用的时候都是一知半解,所以出现一些不正确或者不建议的做法。

应用场景

一个是在什么情况下应该使用OAuth/OIDC的问题。

Figure 1: Cases
Cases

这里有一个很大的误区就是,认为凡是授权都需要OAuth2,譬如第五种情况,的确我们通过OIDC完成认证体系;那么问题是,假设我访问自己的resource,是否需要走一遍OAuth2的流程?试想我们这么做,那么可能会变成这样:

如果client app跟resource server是同一个应用,那么这样相当于我自己去拿一个token,然后我自己验证这个token,然后知道我是否有权限。且不论效率问题,唯一可能的场景就是必须要通过OAuth Server来获取用户的权限,但通常这些规则也必须要进行设置(那为什么要到OAuth中设置?这样通常代价更高)。

如果client app跟resource server不是一个应用,这样做倒是可以实现一个统一的权限管理机制,不过,唯一的问题就是性能问题。

Token相关

Token的存储

Web APP

Native/Mobile app

可以存储在OS提供的安全存储中,例如:

SPA单页应用

跟Web APP一样,如果SPA有对应的后端支持,token应该存储在SPA的后端,但是SPA需要通过某种机制去获取这个token;如果没有对应的后端,那么只能存储在内存中。

id_token可以当access_token使用么

id_token是由授权服务器颁发给client的,比如请求一个id_token的:

https://authorization-server.com/authorize?
  response_type=code
  &client_id=egHuu4oJxgOLeBzPAQ9sXg4i
  &redirect_uri=https://www.oauth.com/playground/oidc.html
  &scope=openid+profile+email+photos
  &state=sRROJ_iPTam39Dc7
  &nonce=eFRvo_n5ecyYU_Sv

最后得到的id_token是这样的:

{
  "sub": "concerned-caracal@example.com",
  "name": "Concerned Caracal",
  "email": "concerned-caracal@example.com",
  "iss": "https://pk-demo.okta.com/oauth2/default",
  "aud": "egHuu4oJxgOLeBzPAQ9sXg4i",
  "iat": 1600674514,
  "exp": 1603266514,
  "amr": [
    "pwd"
  ]
}

这里aud即client的id,是可以被client所信任的。而id_token不是设计给resource server使用的,所以显然不能使用id_token代替access_token。

References: