OAuth2为什么不能用来进行认证1使用OpenID Connect进行用户认证刨根问底协议ContentsOAuth2为什么不能用来进行认证 .................................................................... 1认证()和授权()的区别的问题与的区别在哪OpenID Connect授权流程 ........................................................................... 3其他 .................................................................................................... 4结构作为一个广泛使用的授权标准,已经基本上普及了,但是其协议本身是比较复杂的,如果不仔细研究还是会一知半解。一个常见的错误用法就是用来进行认证()。不是为解决认证的问题的协议,也没有定义认证的流程;但是,在的基础上,加以扩展得到的确是为解决这个问题而生的。OAuth2为什么不能用来进行认证认证(Authentication)和 授权(Authorization)的区别与是有区别的。::OAuth Login的问题在的使用场景中,一种比较常见的攻击场景是,即使用得到的来登陆到应用中,通常在中会存在这样的威胁。如上所示,客户端认为可以拿到用户的信息(通过,那么操作的主体就是用户本人,于是很简单就实现了微信登陆的功能。这里的问题在于,攻击者可以自己申请一个合法的,然后诱导用户请求同样的的,在这个例子中,也就是获取微信用户信息,然后按照的流 OAuth2为什么不能用来进行认证2程,授权服务器会调用一个来返回给其一个,这个是绑定到了登陆的用户的。攻击者这时可以利用这个,然后去调用的回调接口,模拟从的认证服务器回调。这时候会拿着这个去换取,然后获取用户信息,然后就登陆成功了。当然这个其实很好解决:一定要绑定到上,也就是说一个只能由申请它的去换取,这个检测是由完成的那么,既然已经解决了这个问题,是不是就用来做认证了呢?答案还是否定的,原因很简单,因为即便你可以解决这些问题,中并没有定义一个标准的做法来实现认证。的access_token的实质是将用户的一些访问权限()代理给客户端。通过客户端可以获取一个access_token,代表一个用户授权进行某些操作的凭证。客户端可以通过的来获取元数据,例如用户名等。虽然在协议中,这个本身是给验证使用的,但实际上并没有限制说只有可以访问。那么是否可以用来做认证呢?但设计的本意是给资源服务器使用的。资源服务器根据其判断是否有权限访问资源,而并不关心程序是谁。因此实际上代表的是代理的用户权限,而不是用户本身。另外如果是的授权流程的话。就根本没有用户存在了。在的规范中也提到了:OpenID Connect与OAuth2的区别在哪实际上在上的核心区别在于,最终会生成一个而不是,借此来对用户进行认证。 OpenID Connect授权流程3OpenID Connect授权流程中定义了几种授权流程:实际上,尽管有多种授权流程可用,但推荐的做法是使用(,以保证最佳的安全性。Authorization Code Flow的流程跟的流程差别不大,流程为:发起认证请求到授权服务器上授权服务器认证终端用户授权服务器提示用户并得到用户的授权授权服务器重定向到,并带一个通过换取(和验证,认证完成首先是客户端生成授权的: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这里比的流程多了一个nonce的随机字符串。这是用来防止攻击的,相当于对的一个额外的验证,而设计师为了防止的。然后跳转到授权服务器登陆成功后,会并附带一些参数:?state=sRROJ_iPTam39Dc7 &code=MsxVU0nqVYeg0BdPMV59atYOUSCZKzpbcDbCrBXwVVNt2Xw7然后拿这个去换取POST https://authorization-server.com/tokengrant_type=authorization_code&client_id=egHuu4oJxgOLeBzPAQ9sXg4i&client_secret=p4NlH7i7o2JQJ9xpGdhG95eXWgX1I8teWYZo8pH5-vILSZXv&redirect_uri=https://www.oauth.com/playground/oidc.html&code=MsxVU0nqVYeg0BdPMV59atYOUSCZKzpbcDbCrBXwVVNt2Xw7最终可以拿到以及{ "token_type": "Bearer", "expires_in": 86400, "access_token": "B1dETMtgNOPBHD8CfgkcM4PEhZxOt748pUeejk_6gfUVMpfIhObdfhLigQKLQ7MVjNj4zDmb", 其他4 "scope": "openid profile email photo", "id_token": "eyJraWQiOiJzMTZ0cVNtODhwREo4VGZCXzdrSEtQUkFQRjg1d1VEVGxteW85SUxUZTdzIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJjb25jZXJuZWQtY2FyYWNhbEBleGFtcGxlLmNvbSIsIm5hbWUiOiJDb25jZXJuZWQgQ2FyYWNhbCIsImVtYWlsIjoiY29uY2VybmVkLWNhcmFjYWxAZXhhbXBsZS5jb20iLCJpc3MiOiJodHRwczovL3BrLWRlbW8ub2t0YS5jb20vb2F1dGgyL2RlZmF1bHQiLCJhdWQiOiJlZ0h1dTRvSnhnT0xlQnpQQVE5c1hnNGkiLCJpYXQiOjE2MDA2NzQ1MTQsImV4cCI6MTYwMzI2NjUxNCwiYW1yIjpbInB3ZCJdfQ.ZoPvZPaomdOnnz2GFRGbgaW7PPWIMFDqSBp0gbN4An4a9F-Bc-4_T9EBGV8aGetyjZYAON0gjNV0p0NGFiwettePWKuxBzusuGCEd9iXWWUO9-WTF5e2AGr3_jkg34dbxfiFXy3KgH7m0czm809cMaiZ_ofLYgJHVD8lqMQoWifhoNhpjPqa19Svc3nCHzSYHUgTXQWvA56NmQvyVPh_OM7GMpc6zHopmihJqt3eREof8N-bOd7FL39jeam2-k1TFSDogyJE513aC0OssRADr_TWvtL8xoaPkXM_7bXYs9_7erXmzF9la0hvmOuasieetpLhOvFeoiOJWCU9xhxj4Q"}简而言之,是给做认证用的,可能包含一些用户敏感的信息是给用的Implicit flow这种授权流程的步骤如下:发起认证请求到授权服务器上授权服务器认证用户授权服务器得到用户的授权授权服务器直接将以及如果请求了的话到上校验,完成认证跟的区别在于,授权服务器认证用户完成之后直接将发给了而不是发送一个。这种流程设计是本身是针对运行在浏览器上的的,已经不被建议使用。其他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" ]}中包含了一些必须的信息:证书的签发者对应的主体(也就是到底认证的是谁了)的标识,通常就是用户名证书的受众,必须包含。过期时间签发时间 其他5: