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目前是推荐的认证模式。

  • 相关阅读:
    Eclipse安装Hadoop插件
    (转)Ubuntu14.0.4中hadoop2.4.0伪分布模式配置
    Hadoop--DataNode无法启动
    启动与关闭hadoop
    hadoop中执行命令时发生错误
    strings命令
    Deriving data from ElasticSearch Engine
    elasticsearch data importing
    reading words in your computer and changing to female voice, linux festival text2wave saving wav files
    DDNS client on a Linux machine
  • 原文地址:https://www.cnblogs.com/Code-life/p/13452827.html
Copyright © 2011-2022 走看看