OAuth {"error":"invalid_client"} 授权类型 "client credential" - C# ASP.Net Web API

OAuth {"error":"invalid_client"} grant type "client credential" - C# ASP.Net Web API

我在尝试使用 postman 或 curl 从我的本地端点请求令牌时不断收到无效的客户端。它只是一个启用了 WebAPI 的 ASP.NET MVC 项目(创建项目时的复选框)。我有一个 class MyAuthorizationServerProvider.cs,它有以下代码

using System;
using System.Configuration;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Owin.Security.OAuth;

namespace OAuth2App.Provider
{
    public class OAuthProvider : OAuthAuthorizationServerProvider
    {
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            string clientId;
            string clientSecret;
            Guid clientIdGuid;
            if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
            {
                context.TryGetFormCredentials(out clientId, out clientSecret);
            }
            if (null == context.ClientId || null == clientSecret || !Guid.TryParse(clientId, out clientIdGuid))
            {
                context.SetError("invalid_credentials", "A valid client_Id and client_Secret must be provided.");
                context.Rejected();
                return;
            }
            //validate aginstdb or config: GetClient(clientIdGuid, clientSecret);  
            bool isValidClient = ConfigurationManager.AppSettings["ClientId"] == clientId && ConfigurationManager.AppSettings["ClientSecret"] == clientSecret;
            if (!isValidClient)
            {
                context.SetError("invalid_credentials", "A valid client_Id and client_Secret must be provided.");
                context.Rejected();
                return;
            }
            await Task.Run(() => context.Validated(clientId));
        }
        public override async Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
        {
            Guid clientId;
            Guid.TryParse(context.ClientId, out clientId);
            //validate aginstdb or config: GetByClientId(clientId);  
            bool client = ConfigurationManager.AppSettings["ClientId"] == clientId.ToString().ToUpper();
            if (!client)
            {
                context.SetError("invalid_grant", "Invaild client.");
                context.Rejected();
                return;
            }
            var claimsIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
            claimsIdentity.AddClaim(new Claim("LoggedOn", DateTime.Now.ToString()));
            await Task.Run(() => context.Validated(claimsIdentity));
        }
        public override Task TokenEndpoint(OAuthTokenEndpointContext context)
        {
            if (context.TokenIssued)
            {
                context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddSeconds(3600);
            }
            return Task.FromResult<object>(null);
        }
    }
}

我有另一个 OWIN 启动 class 如下

using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;
using OAuth2App.Provider;
using Owin;
using System;
[assembly: OwinStartup(typeof(OAuth2App.Startup))]
namespace OAuth2App
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
        public void ConfigureAuth(IAppBuilder app)
        {
            var oAuthOptions = new OAuthAuthorizationServerOptions {
                AllowInsecureHttp = true, // need set to false in PROD  
                    TokenEndpointPath = new PathString("/oauth2/token"),
                    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(60), //token expiration time  
                    Provider = new OAuthProvider(),
            };            
            app.UseOAuthAuthorizationServer(oAuthOptions);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        }
    }
}

我的 web.config 应用设置部分如下

<appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="clientId" value="XXXXXXXXXXXXXXXXXXXXXX" />
    <add key="clientSecret" value="XXXXXXXXXXXXXXXXXXXXXXXXX" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>

当我尝试发出 post 请求时,下面是我在 postman 中得到的内容。调试时,我看到上下文对象的 clientID 字段始终为空。有人可以指出我错了什么吗?

public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)

已编辑 (我错过了你退而求其次的部分 TryGetFormCredentials

您似乎需要将表单数据发送为 application/x-www-form-urlencoded。见 RFC

问题出在下面的代码上,存在错误。我基本上将其更改为 if 语句并删除了 context.rejected

bool isValidClient = ConfigurationManager.AppSettings["ClientId"] == clientId && ConfigurationManager.AppSettings["ClientSecret"] == clientSecret;
        if (!isValidClient)
        {
            context.SetError("invalid_credentials", "A valid client_Id and client_Secret must be provided.");
            context.Rejected();
            return;
        }

// 改为

If(ConfigurationManager.AppSettings["ClientId"] == clientId && ConfigurationManager.AppSettings["ClientSecret"] == clientSecret)
    {
context.SetError("invalid_credentials", "A valid client_Id and client_Secret must be provided.");
            
}