zoukankan      html  css  js  c++  java
  • 基于Identity Server4的OAuth 2.0授权总结(4)- PKCE in Authorization Code mode

    授权码模式的过程大致是如下图所示:

     在获取token的时候需要提供如下信息:

    1. code

    2. redirect_url,

    3. client_id,client secret

    第二项和第三项其实是用来对通过code获取token的client的合法性进行验证。其中最核心的应该是client secret。通过他可以解决如下问题:

    对获取token的client进行合法性验证。secret是在Authorization Server上注册client的时候设置的,只有client自己知道,因此可以对client进行验证。

    这样的话,即使code因为某种原因泄露了,没有secret也无法获取到token。从而提升了安全性。在传统的Web应用中,token的获取是发生在后端,因此secret也是保存在后端。这样是可行的。但是对于现在比较流行的SPA应用,token的获取是发生在浏览器端,是一个公开的环境。这个方法就不可行了,因为secret不可能保存在一个公开的环境中。

    在这个场景下,就需要用PKCE(Proof Key for Code Exchange)来保证整个过程的安全性了。

    PKCE主要是通过在授权的过程中增加了code_challenge和code_verifier两个元素来对整个流程进行验证,防止code被第三方截取的情况。具体流程如下:

    这里面最核心的其实就是在authorize请求中增加了code_challenge参数,在token请求中增加了code_verifier参数。这两个参数最终都是依赖于一个client生成的随机字符串。

    Random String: 是一个Client端生成的随机字符串(由字母,数字,- ,. ,_ ,~  组成)
    code_verifier:Random String
    code_challenge参数的生成算法为:BASE64URL-ENCODE(SHA256(ASCII(Random String)))。
    过程解析:

    1. 在申请授权时(authorize请求),client,生成随机字符串并基于它生成code_challenge传给authorization server.(这个过程中random string 在网络中不会被暴露,因为对其进行了hash)。

    2. authorization server生成授权码后,会将code_challenge保存起来,并与授权码关联。

    3. 在通过授权码获取token的过程中,client会将随机字符串(code_verifier)传给authorization server

    4. authorization server会将code_verifier进行与第一步相同算法进行计算得到新的code_challenge

    5. authorization server将第四步中的code_challenge与第一步中的原始code_challenge进行比较,如果相同则认为申请授权的源与用code获取token的源为同一来源。(即code没有被第三方截取而冒用)

    实现:
    服务端

    Identity Server 4默认支持PKCE模式,但是是可选的(就是说client也可以不使用该方式)。如需强制client使用PKCE,只需在定义Client时将Client配置成RequirePkce即可。

    new Client
                    {
                        ClientId = "js",
                        RequireConsent = false,
                        AllowedGrantTypes = GrantTypes.Code,
                        RequireClientSecret = false,
                        RequirePkce = true,
                        AllowAccessTokensViaBrowser = false,
                        AlwaysIncludeUserClaimsInIdToken = true,
                        RedirectUris = new List<string>{"http://localhost:3000/callback.html"},
                        AllowedScopes = new List<string>{"api", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Email, "profile"},
                        PostLogoutRedirectUris = new List<string>{ "http://localhost:3000" }
                    },

    客户端

    客户端oidc-client库默认会采用PKCE,也不需要额外的配置。

    总结
    1. 传统Web应用的client secret是保存在后端,不会被泄露。因而可以用于验证client,保护code被冒用的情况。对于public client(SPA),用于传统Web应用的secret方式不再有效。

    2. PKCE通过在每个授权请求过程中添加一个随机secret,达到了了防止授权码被冒用,同时secret不被泄露。

    3. 对于public client, PKCE目前是推荐的认证模式。

  • 相关阅读:
    杂题之求1-100连续不重复整数中的缺少的一个数
    C语言之位运算
    程序员的激情其实是一种痛苦
    主机windwo7+虚拟机centos如何配置虚拟机可以上网,且与主机互ping通
    MyEclipse Servers视窗出现“Could not create the view: An unexpected exception was thrown”错误解决办法
    一个web项目在myeclipse中add deployment时无法被识别出来的原因
    Hibernate中,将session绑定到线程时,在保存和查询数据的代码里,要正确的关闭session
    springframwork历史版本下载地址
    在web项目中使用cxf开发webservice,包含spring支持
    [转] Spring Security(01)——初体验
  • 原文地址:https://www.cnblogs.com/Code-life/p/13452827.html
Copyright © 2011-2022 走看看