我正在使用开发计算机上的localhost对Web Core API服务器进行Ajax调用。 这是进行呼叫的代码;
<chat-home/>
但是,我收到401未经授权的用户异常。 在我的启动Configure方法中,我按如下所示设置了CORS
addDataToDatabase = function (callback, errorCallback, url, data) {
$.ajax({
async: true,
url: url,
contentType: "application/json",
dataType: "text",
data: data,
type: "POST",
xhrFields: { withCredentials: true }
})
.done(function (data) {
callback(data);
})
.fail(function (data) {
errorCallback(data);
});
在我的appSettings文件中,设置orginUrl:
var url = Configuration["originUrl"];
app.UseCors(
options => options.WithOrigins(url).AllowAnyHeader().AllowAnyMethod().AllowCredentials()
);
所有这些都适用于GET类型的调用,但不适用于POST。 我需要解决什么?
编辑-根据要求,这是完整的启动代码;
"originUrl": "http://localhost:12345"
这是引发401异常的POST方法;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
namespace Properties.API
{
using Domain;
using Domain.Interfaces;
using Domain.Repo;
using EF6;
using Helper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Config;
using NLog.Extensions.Logging;
using NLog.Web;
using Sir.EF6;
using Sir.EF6.Interfaces;
using Sir.EF6.Repo;
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appSettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appSettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public static IConfigurationRoot Configuration;
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
var manager = new ApplicationPartManager();
manager.ApplicationParts.Add(new AssemblyPart(typeof(Startup).Assembly));
services.AddSingleton(manager);
services.AddCors();
services.AddMvcCore().AddJsonFormatters();
services.Configure<IISOptions>(options => new IISOptions
{
AutomaticAuthentication = true,
ForwardClientCertificate = false,
ForwardWindowsAuthentication = false
});
var connectionStringMSurveyV2 = Configuration.GetConnectionString("MSurveyV2Db");
services.AddScoped<MSurveyV2Db>(_ => new MSurveyV2Db(connectionStringMSurveyV2));
var connectionStringSir = Configuration.GetConnectionString("SirDb");
services.AddScoped<SirDb>(_ => new SirDb(connectionStringSir));
services.AddScoped<IPropertiesRepo, PropertiesRepo>();
services.AddScoped<ISirUoW, SirUoW>();
services.AddScoped<IPropertyUoW, PropertyUoW>();
services.AddScoped<Services.IMailService, Services.MailService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
loggerFactory.AddDebug();
loggerFactory.AddNLog();
LogManager.Configuration = new XmlLoggingConfiguration(@"nlog.config");
var connectionString = Configuration.GetConnectionString("SirNLogDb");
LogManager.Configuration.Variables["SirNLogDb"] = connectionString;
app.AddNLogWeb();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler();
}
var url = Configuration["originUrl"];
app.UseCors(
options => options.WithOrigins(url).AllowAnyHeader().AllowAnyMethod().AllowCredentials()
);
app.UseMvc();
AutomapperInit.Set();
var logger = LogManager.GetCurrentClassLogger();
logger.Info("Started Properties Web API");
logger.Info($"Origin url = {url}");
}
}
}
这是一个可以正常工作的GET方法
[HttpPost("add")]
public async Task<IActionResult> Add([FromBody] InspectionVisitInputDto inspectionVisitDto)
{
this.NLogger.Info("api/inspectionVisit/add".ToPrefix());
if (inspectionVisitDto == null)
{
NLogger.Error("No data sent");
return BadRequest(ModelState);
}
if (inspectionVisitDto.InspectionId < 1)
{
NLogger.Error($"Invalid InspectionId < 1 (actual value is {inspectionVisitDto.InspectionId}");
return BadRequest(ModelState);
}
var inspectionVisit = Mapper.Map<InspectionVisit>(inspectionVisitDto);
var dateOfVisit = inspectionVisit.DateOfVisit.Date;
try
{
var existingInspectionVisit = this.SirUoW.InspectionVisit.GetItem(
x => x.InspectionId == inspectionVisit.InspectionId &&
DbFunctions.TruncateTime(x.DateOfVisit) == dateOfVisit &&
x.ContractSubcontractorId == inspectionVisit.ContractSubcontractorId &&
x.SelectedInspectorUsername == inspectionVisit.SelectedInspectorUsername &&
x.WorkPhaseId == inspectionVisit.WorkPhaseId);
if (existingInspectionVisit?.InspectionVisitId > 0)
{
NLogger.Info($"Inspection Visit Id = {existingInspectionVisit.InspectionVisitId} already exists.");
return Ok(existingInspectionVisit.InspectionVisitId);
}
}
catch (Exception e)
{
var message = "Cannot get inspection visit";
await ReportException(e, message);
var status = OperationStatus.CreateFromException(message, e);
return BadRequest(status);
}
NLogger.Info("Add New Inspection Visit");
try
{
this.SirUoW.InspectionVisit.Add(inspectionVisit);
await SirUoW.LoggedInSaveChangesAsync(this.LoggedInUser);
NLogger.Info("New Inspection Visit Saved, id = " + inspectionVisit.InspectionVisitId);
if (inspectionVisit.ContractSubcontractorId != null)
{
await SaveContractSubcontractorIdForInspection(inspectionVisitDto);
}
return Ok(inspectionVisit.InspectionVisitId);
}
catch (Exception e)
{
var message = "Cannot save " + inspectionVisitDto;
await ReportException(e, message);
var status = OperationStatus.CreateFromException(message, e);
return BadRequest(status);
}
}
答案 0 :(得分:0)
您的方案正在组合 IIS Windows Authenticaiton 和 CORS ,因为预检请求选项将不包含任何安全标头,它将出现错误 401 。
请尝试以下解决方法:
在anonymousAuthentication
中启用appsettings.json
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": true
}
}
要启用身份验证,请尝试Filter
禁用匿名访问。
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});