You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解析POST请求响应获取OAuth访问密钥的技术疑问

问题描述

我发送了一个看似成功的POST HttpWebRequest,收到了15个包含数据的响应头(result.Headers.Count - 1)。其中result.Headers(13)的内容为:

fpc=Arg8nm0VqblMnu3rWck9GCw; expires=Wed, 05-Jun-2024 15:59:45 GMT; path=/; secure; HttpOnly; SameSite=None,esctx=PAQABBwEAAADnfolhJpSnRYB1SVj-Hgd8jINyVhrdWcuTdgm378vqo8Qo9ZgPGeuBNHyLhH1nZC8AfCBrfkJjbWVgfmt1yGtOCMmbLDUwDm4pPKp2qiUmCJHs5cnVcv--Oc4Q9LsQLS9m0znPAPGdAojpzBNGZ6tQPQTnroP24HSg4I53tNhF4j-u2orVUJBod72dh620NqggAA; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None,x-ms-gateway-slice=estsfd; path=/; secure; httponly,stsservicecookie=estsfd; path=/; secure; httponly

在该响应头中我看到了esctx=PAQABBwEAAADnfolhJpSnRYB1SVj-Hgd8jINyVhrdWcuTdgm378vqo8Qo9ZgPGeuBNHyLhH1nZC8AfCBrfkJjbWVgfmt1yGtOCMmbLDUwDm4pPKp2qiUmCJHs5cnVcv--Oc4Q9LsQLS9m0znPAPGdAojpzBNGZ6tQPQTnroP24HSg4I53tNhF4j-u2orVUJBod72dh620NqggAA;。请问这是不是我需要的OAuth响应访问密钥?如果是的话,我该如何将其解析出来?

以下是实际的POST请求代码:

Private Sub RunRequest()
  Dim s As HttpWebRequest
  Dim enc As UTF8Encoding
  Dim postdata As String
  Dim postdatabytes As Byte()
  Dim url As String = ("https://login.microsoftonline.com/ca4f5969-c10f-40d4-8127-e74b691f95de/v2.0/.well-known/openid-configuration")
  'Dim url As String = ("https://login.microsoftonline.com/ca4f5969-c10f-40d4-8127-e74b691f95de/oauth2/v2.0/token")
  s = HttpWebRequest.Create(url)
  enc = New System.Text.UTF8Encoding()
  postdata = "client_id=4e502cbc-a55f-4341-a498-69cfbe19ee7b&client_secret=0Ag8Q~QgsWJ55mz9SWG6hf22b_7mZ2m~.nInpagc&grant_type=client_credentials&scope=https://tffproduction.onmicrosoft.com/04cc9749-dbe5-4914-b262-d866b907756b/.default"
  postdatabytes = enc.GetBytes(postdata)
  s.Method = "POST"
  s.ContentType = "application/x-www-form-urlencoded"
  s.ContentLength = postdatabytes.Length

  Using stream = s.GetRequestStream()
      stream.Write(postdatabytes, 0, postdatabytes.Length)
  End Using

  Dim result As WebResponse

  Try
      result = s.GetResponse()
      Dim breakpoint As String = Nothing
  Catch ex As Exception
      Dim errmsg As String = ex.Message
  End Try
  Dim sb As New StringBuilder
  Dim hdkey As String

  For I As Int32 = 0 To result.Headers.Count - 1
      hdkey = result.Headers(I)
      sb.Append(result.Headers(I))
      sb.AppendLine()

  Next
  Dim Hdrs As String = sb.ToString
End Sub
解答

1. esctx不是OAuth访问密钥

esctx是Azure AD生成的会话上下文Cookie,用于跟踪应用的认证会话状态,和OAuth 2.0的access_token(访问密钥)完全不是一回事。真正的访问令牌会在请求token端点的响应体中返回,格式为JSON。

2. 请求的核心错误修正

你当前请求的URL是OpenID配置发现端点(/.well-known/openid-configuration),这个端点仅接受GET请求,用于获取Azure AD的认证元数据,不会处理POST类型的token请求。你需要改用代码中被注释掉的token端点URL:https://login.microsoftonline.com/ca4f5969-c10f-40d4-8127-e74b691f95de/oauth2/v2.0/token。

3. 获取并解析真正的访问令牌

修改URL后,请求的响应体是JSON格式,包含access_token、token_type、expires_in等核心字段。你需要读取响应体并解析JSON,示例代码如下:

Private Sub RunRequest()
    Dim s As HttpWebRequest
    Dim enc As UTF8Encoding
    Dim postdata As String
    Dim postdatabytes As Byte()
    ' 使用正确的token端点
    Dim url As String = ("https://login.microsoftonline.com/ca4f5969-c10f-40d4-8127-e74b691f95de/oauth2/v2.0/token")
    s = HttpWebRequest.Create(url)
    enc = New System.Text.UTF8Encoding()
    postdata = "client_id=4e502cbc-a55f-4341-a498-69cfbe19ee7b&client_secret=0Ag8Q~QgsWJ55mz9SWG6hf22b_7mZ2m~.nInpagc&grant_type=client_credentials&scope=https://tffproduction.onmicrosoft.com/04cc9749-dbe5-4914-b262-d866b907756b/.default"
    postdatabytes = enc.GetBytes(postdata)
    s.Method = "POST"
    s.ContentType = "application/x-www-form-urlencoded"
    s.ContentLength = postdatabytes.Length

    Using stream = s.GetRequestStream()
        stream.Write(postdatabytes, 0, postdatabytes.Length)
    End Using

    Dim result As WebResponse
    Try
        result = s.GetResponse()
        ' 读取响应体
        Using reader As New StreamReader(result.GetResponseStream())
            Dim responseJson As String = reader.ReadToEnd()
            ' 解析JSON(示例使用System.Text.Json)
            Dim tokenObj = JsonSerializer.Deserialize(Of Dictionary(Of String, Object))(responseJson)
            If tokenObj.ContainsKey("access_token") Then
                Dim accessToken As String = tokenObj("access_token").ToString()
                ' 此处获取到真正的访问令牌
            End If
        End Using
    Catch ex As Exception
        Dim errmsg As String = ex.Message
    End Try
End Sub

4. 若需解析esctx的值

虽然它不是访问密钥,但如果需要提取该字段的值,可以通过字符串拆分实现:

' 假设headers13是拿到的result.Headers(13)内容
Dim headers13 As String = "fpc=Arg8nm0VqblMnu3rWck9GCw; expires=Wed, 05-Jun-2024 15:59:45 GMT; path=/; secure; HttpOnly; SameSite=None,esctx=PAQABBwEAAADnfolhJpSnRYB1SVj-Hgd8jINyVhrdWcuTdgm378vqo8Qo9ZgPGeuBNHyLhH1nZC8AfCBrfkJjbWVgfmt1yGtOCMmbLDUwDm4pPKp2qiUmCJHs5cnVcv--Oc4Q9LsQLS9m0znPAPGdAojpzBNGZ6tQPQTnroP24HSg4I53tNhF4j-u2orVUJBod72dh620NqggAA; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=None,x-ms-gateway-slice=estsfd; path=/; secure; httponly,stsservicecookie=estsfd; path=/; secure; httponly"

' 按逗号拆分多个Cookie项
Dim cookies = headers13.Split(","c)
For Each cookie In cookies
    If cookie.Trim().StartsWith("esctx=") Then
        ' 拆分键值对,提取等号后内容并去除末尾分号
        Dim esctxValue = cookie.Trim().Split("="c)(1).TrimEnd(";"c)
        ' esctxValue即为目标内容
        Exit For
    End If
Next

内容的提问来源于stack exchange,提问作者dashley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 10:14:54