Asp.net web api Asp.Net Core 2.1 WebApi从Angular 6 WebApp发送获取访问令牌的请求时返回400

Asp.net web api Asp.Net Core 2.1 WebApi从Angular 6 WebApp发送获取访问令牌的请求时返回400,asp.net-web-api,angular6,openiddict,Asp.net Web Api,Angular6,Openiddict,我有一个应用程序,它在服务器端由asp.net core 2.1 web api表示,在客户端由angular 6表示。OpenIddict在服务器端用于支持令牌身份验证。主要问题是,当从angular app向服务器发送请求以生成或刷新客户端的access_令牌时,服务器会响应400个错误请求,尽管从Postman发送时,一切正常。添加Cors策略以允许Cors原始请求,因为客户端和服务器端位于不同的端口上,所以从angular到服务器的简单请求可以顺利通过 以下是Startup类: publ

我有一个应用程序,它在服务器端由asp.net core 2.1 web api表示,在客户端由angular 6表示。OpenIddict在服务器端用于支持令牌身份验证。主要问题是,当从angular app向服务器发送请求以生成或刷新客户端的access_令牌时,服务器会响应400个错误请求,尽管从Postman发送时,一切正常。添加Cors策略以允许Cors原始请求,因为客户端和服务器端位于不同的端口上,所以从angular到服务器的简单请求可以顺利通过

以下是Startup类:

public class Startup
{
    public Startup(IConfiguration configuration, IHostingEnvironment env)
    {
        Configuration = configuration;
        hostingEnvironment = env;
    }

    public IConfiguration Configuration { get; }
    private IHostingEnvironment hostingEnvironment { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContextPool<HospitalContext>(options => 
         {
             options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
             options.UseOpenIddict();
         });

        services.AddCors(options => options.AddPolicy("AllowLocalhost4200", builder => 
        { 
            builder
            .WithOrigins("http://localhost:4200")
            .WithHeaders("Authorization", "Content-type")
            .WithMethods("Get", "Post", "Put", "Delete");
        }));

        services.AddCustomIdentity();
        services.AddCustomOpenIddict(hostingEnvironment);

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseCors("AllowLocalhost4200");
        app.UseAuthentication();
        app.UseDefaultFiles();
        app.UseStaticFiles();
        app.UseMvc();
        app.InitilizeDb();
    }
}

实际上,我对基于令牌的身份验证还不熟悉,所以可能在配置或其他方面存在问题。如果您能提供任何解决问题的建议,我们将不胜感激。

首先,请尝试允许所有标题:


稍后,更准确地说,查看angular应用程序发送的所有标题,并在cors策略中允许所有标题。首先,允许application-x-www-form-urlencoded

您的authFormBody方法中似乎有一个输入错误:

body += 'grant_type=password$';
这应写为:

body += 'grant_type=password&';

我发现了一个错误,实际上我从配置中删除了AddPasswordFlow,留下了AllowRefreshTokenFlow和AllowImplicitFlow,并将grant_type=password发送到未配置为接受此类授权的服务器,这是我的错误。它应该是:

services.AddOpenIddict(options =>
    {
        //some configs

        options.AllowPasswordFlow()
               .AllowRefreshTokenFlow()
               .AllowImplicitFlow();

        //some configs
    });

首先,我尝试允许所有的标题,但这并没有改变任何事情。其次,在这种情况下,angular发送一个带有“Content Type”头的请求,仅此而已……Cors策略允许这样做,关于“application-x-www-form-urlencoded”,它是在Conten Type头中指定的请求主体的类型,而不是我所理解的头。所以,很遗憾,这不起作用。你的angular应用程序运行在http://localhost:4200? 不是https,不是其他端口?看起来很正常。我看到的唯一一件事是:尝试使用大写字母作为动词或AllowalMethod抱歉,这只是粘贴时的错误…即使是这样,它至少会到达服务器“/connect/token”上的方法,并且它会向我发送我自己定义的错误请求和描述。
body += 'grant_type=password$';
body += 'grant_type=password&';
services.AddOpenIddict(options =>
    {
        //some configs

        options.AllowPasswordFlow()
               .AllowRefreshTokenFlow()
               .AllowImplicitFlow();

        //some configs
    });