对预检请求的响应未通过访问控制检查所请求的资源上不存在“ Access-Control-Allow-Origin”标头

时间:2019-06-20 18:44:30

标签: iis asp.net-core .net-core

我在IIS上托管了.NET Core WebAPI,并已在startup.cs中启用了CORS。

当我从Angular应用向API请求时,请求失败,并且出现此错误

  

“从起源'https://test-api.contractorconnection.com/ERCore_Service/api/LandingPage/Authenticate/Austin.Born/ERCore'到'https://test-apps2.contractorconnection.com'处对XMLHttpRequest的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:否'Access-Control-Allow -“ Origin”标头出现在所请求的资源上。”

直接从浏览器或邮递员发出请求时,请求完成,我得到了数据。

我尝试了许多答案,修改了 web.config ,并在 Startup.cs

中指定了允许的来源

我在这里想念什么或做错了什么?

下面的Startup.cs

public void ConfigureServices(IServiceCollection services) {
    //  //For JWT Auth
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options => {
        options.TokenValidationParameters = new TokenValidationParameters {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = Configuration["Jwt:Issuer"],
            ValidAudience = Configuration["Jwt:Issuer"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
        };
    });
    services.AddScoped<ILandingPage, DAL_LandingPage>();
    services.AddScoped<IDetails, DAL_EstimateDetailPage>();
    services.AddScoped<IQueueDetailsPage, DAL_QueueDetails>();
    services.AddScoped<IAdminDetailPage, DAL_AdminDetailPage>();
    services.AddScoped<IAdminCatSelTab, DAL_AdminCatSel>();
    services.AddScoped<IApplicationSecurityTab, DAL_ApplicationSecurityTab>();

    //services.AddCors();
    services.AddCors(o => o.AddPolicy("MyPolicy", builder => {
        builder.AllowAnyHeader()
            .AllowAnyMethod()
            .WithOrigins("https://test-apps2.contractorconnection.com", "https://test-apps2.contractorconnection.com/ERCore", "http://localhost:54807/")
            .AllowCredentials();
    }));

    services.AddMvc().AddJsonOptions(options => {
        options.SerializerSettings.ContractResolver
            = new Newtonsoft.Json.Serialization.DefaultContractResolver();
    });
    services.AddDbContext<PrismDataContext1>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));



}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
    if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
    }
    //app.UseCors(builder => builder.WithOrigins("http://localhost:4200", "https://cc-er-dev-api.primussoft.com", "https://test-apps2.contractorconnection.com", "https://apps2.contractorconnection.com").AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
    app.UseCors("MyPolicy");
    app.UseOptions();
    //For JWT Auth
    app.UseAuthentication();
    app.UseMvc();
}

控制器端点

[HttpGet]
[Route("api/LandingPage/Authenticate/{webLogin}/{appName}")]
[HttpOptions]
public JsonResult AuthenticateUser(string webLogin, string appName) {
    string connectionString = _config.GetSection("ConnectionStrings").GetSection("DefaultConnection").Value;
    Auth auth = new Auth(connectionString);
    User obj = new User();
    try {
        bool hasAccess = auth.Load(webLogin, appName);
        obj.Name = auth.Name;
        obj.ResourceTypeName = auth.ResourceTypeName;
        obj.ClassificationName = auth.ClassificationName;
        obj.Login = auth.Login;
        obj.ResourceID = auth.ResourceID;
        obj.DetailID = auth.DetailID;
        obj.ApplicationID = auth.ApplicationID;
        obj.ResourceTypeID = auth.ResourceTypeID;
        obj.ClassificationID = auth.ClassificationID;
        obj.SecurityFeatures = auth.FeatureAccess;
        obj.CurrentLanguageDescription = auth.CurrentLanguageDescription;
        obj.CurrentLanguageID = auth.CurrentLanguageID;
        var tokenString = BuildToken(obj);
        obj.Token = tokenString;

        Response.Headers.Add("Access-Control-Allow-Origin", "https://test-apps2.contractorconnection.com");

        return Json(obj);
    } catch (Exception ex) {
        string ac = ex.Message;
        return Json(obj);
    }
}

Web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <cors enabled="true" failUnlistedOrigins="false">
        <add origin="*" allowed="true" />
    </cors>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
    </handlers>
    <aspNetCore processPath=".\ERCore_Service.exe" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*"/>
        <add name="Access-Control-Allow-Headers" value="Content-Type"/>
        <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

1 个答案:

答案 0 :(得分:0)

该问题与名为Netscaler的第三方软件有关。这阻止了由angular发送的OPTIONS飞行前请求。

NetScaler为服务器执行CORs配置,因此您不需要在.NET Core API中配置CORs。

如果在.NET Core API中启用了COR,则对于在Allow-Access-Control-Headers中命名的多个URL,您将收到CORs错误。

我从我的API中删除了CORs配置,而我的合作伙伴DEV通过Netscaler配置了COR。

这完全解决了问题。