oauth2 身份验证 c# 代码不起作用

oauth2 authentication c# code is not working

我正在尝试使用授权码使用 oauth2 api。在第一步中,我通过提供客户端 ID 和密码接收了身份验证,现在在第二步中,我需要使用该身份验证代码的访问令牌。 我尝试了下面的 c# 代码

var client1 = new RestClient("https://ant.aliceblueonline.com/oauth2/token");
var request1 = new RestRequest(Method.POST);
request1.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request1.AddParameter("code", "xxxxxxxxxxxxxxxxx");
request1.AddParameter("grant_type", "authorization_code");
request1.AddParameter("redirect_uri", "https://ant.aliceblueonline.com/plugin/callback");
request1.AddParameter("client_id", "MM01418");
request1.AddParameter("client_secret", "xxxxxxxxxxxxxx");
IRestResponse response = client1.Execute(request1);

作为回应,我得到

The OAuth 2.0 Client supports client authentication method "client_secret_basic", but method "client_secret_post" was requested. You must configure the OAuth 2.0 client's "token_endpoint_auth_method" value to accept "client_secret_post

试了很多都解决不了

首先,由于您使用的是 C#,我建议您使用 IdentityModel 与任何 OAuth2 授权服务器或 OpenId Connect 提供程序进行交互。

让我们从客户端的定义开始:客户端是允许请求访问令牌代表的应用程序用户。在您的示例中,运行您发布的代码的服务器是客户端。

为了能够使用 token 端点请求新的 access_token,客户端必须首先能够通过提供 client_idclient_secret(就像客户的用户名和密码)。

两种 方法来提供此客户端凭据,来自IdentityServer4 documentation about secrets

Authentication using a shared secret

You can either send the client id/secret combination as part of the POST body:

POST /connect/token
client_id=client1& client_secret=secret& ...

..or as a basic authentication header:

POST /connect/token
Authorization: Basic xxxxx

在这种情况下,错误响应表明只允许其中一种方法,即 Authentication header

因此,与其在您的请求 body 中传递您的 client_id 和 client_secret:

request1.AddParameter("client_id", "MM01418");
request1.AddParameter("client_secret", "xxxxxxxxxxxxxx");

您需要像 "MM01418:xxxxxxxxxxxxxxxx" 一样使用冒号作为分隔符连接 client_id 和 client_secret 并应用 base64 编码。然后将其作为 header 添加到您的请求中,格式为 Authorization: Basic TU0wMTQxODp4eHh4eHh4eHh4eHh4eHh4。您可以使用以下代码在 c# 中执行此操作:

var credentials = string.Format("{0}:{1}", clientId, clientSecret);
var headerValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials));

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", headerValue);

或者将这些底层细节留给像 IdentityModel Nuget Docs 这样的库,它会根据情况为您实现正确的请求。