【问题标题】:Getting an OAuth2 authentication token in VB.net在 VB.net 中获取 OAuth2 身份验证令牌
【发布时间】:2022-09-28 04:04:23
【问题描述】:

我正在尝试使用 ClientID 和 SecretID 获取 OAuth 令牌。

到目前为止我的代码:

    Dim clientId As String = \"8cd6b80dd822961f362\"
    Dim clientSecret As String = \"5afbd4bb280f29cba5ec1f362\"
    Dim credentials = String.Format(\"{0}:{1}\", clientId, clientSecret)
    Dim headerValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials))

    Dim content = New FormUrlEncodedContent(New Dictionary(Of String, String) From {
                                            {\"client_id\", clientId},
                                            {\"client_secret\", clientSecret},
                                            {\"response_type\", \"code\"},
                                            {\"redirect_uri\", \"https://somesite.com/\"},
                                            {\"grant_type\", \"authorization_code\"}})
    Dim requestMessage = New HttpRequestMessage(HttpMethod.Post, \"https://api.site.com/oauth2/authorize\")
    requestMessage.Headers.Authorization = New AuthenticationHeaderValue(\"Basic\", headerValue)
    requestMessage.Content = content

    Dim client As HttpClient = New HttpClient()
    Dim task = client.SendAsync(requestMessage)
    Dim response = task.Result
    response.EnsureSuccessStatusCode()
    Dim responseBody As String = response.Content.ReadAsStringAsync().Result
    MsgBox(responseBody)

上面的代码返回 redirect_uri 站点的 HTML 而不是令牌。

我错过了什么或做错了什么?

使用邮递员和提供的凭据,我设法获得了令牌。

  • 您能否从邮递员那里执行成功身份验证的网络跟踪,并通过重定向和状态码共享不同的请求?您能否也添加您的 VB 进程停止的点?
  • 当我使用 Postman 获取令牌时,它会打开一个浏览器窗口并提示我在继续之前从商店中选择一个证书。如何在我的代码中复制它?我认为这是我缺少的部分:选择要与请求一起发送的证书。
  • 您使用的是智能卡读卡器之类的东西还是证书存储在哪里?
  • 我有一个安装了证书的数字签名 USB 令牌。

标签: vb.net oauth-2.0 dotnet-httpclient


【解决方案1】:

代码流的第二步使用令牌端点,而不是授权端点。不过,您的有效载荷看起来是正确的。尝试将其发布到此端点:

https://api.site.com/oauth2/token

【讨论】:

  • 当我使用 Postman 获取令牌时,它会打开一个浏览器窗口并提示我在继续之前从商店中选择一个证书。如何在我的代码中复制它?我认为这是我缺少的部分:选择要与请求一起发送的证书。
  • 这没有太多意义。您的代码正在运行代码流的第二步(用户登录),这些从不使用客户端证书。请花一些时间根据您的用例、涉及的组件和要求来更新您的问题,而不仅仅是技术。使用 Postman 时,请随意包含所需的行为。
【解决方案2】:

默认情况下,HttpClient 使用的是AllowAutoRedirect = truedocumentation 说:

Authorization 标头在自动重定向时被清除,并且处理程序会自动尝试重新验证到重定向的位置。没有其他标题被清除。实际上,这意味着如果可能遇到重定向,应用程序不能将自定义身份验证信息放入 Authorization 标头中。

因此,根据服务器的设置,您可能必须创建一个 CookieContainer 并自行进行重定向。

更新:

证书存储的使用是我没有从您的问题中得到的。如果您想像浏览器一样对证书进行类似的处理,您是否必须自己实现此功能。这是一个 C# 示例,说明如何使用专用的 CookieContainerX509 证书处理扩展 WebClient 类。我将它与智能卡读卡器一起使用。它应该在 vb.net 中工作类似。希望它有助于找到正确的 .Net 类以及如何将它们组合在一起:

public class SmartCardClient : WebClient
{
    public CookieContainer Cookies = new CookieContainer();
    public Uri LastResponseUri = null;
    public X509Certificate2 cert = null;
    private string IssuerName = null;

    public SmartCardClient(string issuerName)
    {
        IssuerName = issuerName;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        SelectCertificate();
    }
            
    protected override WebRequest GetWebRequest(Uri uri)
    {
        var request = base.GetWebRequest(uri) as HttpWebRequest;
        LastResponseUri = null;
        
        if (request != null)
        {
            request.CookieContainer = Cookies;
            request.UseDefaultCredentials = true;
            request.AllowAutoRedirect = true;
        }

        return request;
    }
    
    protected override WebResponse GetWebResponse(WebRequest request)
    {
        WebResponse response = base.GetWebResponse(request);
        LastResponseUri = response.ResponseUri;
        return response;
    }
    
    public void SelectCertificate()
    {
        var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    
        store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

        X509Certificate2Collection certs = (X509Certificate2Collection)store.Certificates
            .Find(X509FindType.FindByTimeValid, DateTime.Now, false)
            .Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, false)
            .Find(X509FindType.FindByIssuerName, IssuerName, false);

        if (certs.Count > 1)
            certs = X509Certificate2UI.SelectFromCollection(
                certs, "Select Certificate", "Please select a certificate:",
                X509SelectionFlag.MultiSelection
            );
            
        if (certs.Count > 0)
            cert = certs[0];

        store.Close();
    }
}

【讨论】:

  • 当我使用 Postman 获取令牌时,它会打开一个浏览器窗口并提示我在继续之前从商店中选择一个证书。如何在我的代码中复制它?我认为这是我缺少的部分:选择要与请求一起发送的证书。
猜你喜欢
  • 2016-12-07
  • 2015-11-02
  • 2016-09-15
  • 2018-03-03
  • 2018-09-07
  • 2021-05-12
  • 2020-03-03
  • 2015-06-21
  • 2012-05-26
相关资源
最近更新 更多