CORS ajax在chrome上从.NET Api返回401(未授权)

时间:2017-07-11 13:14:59

标签: ajax asp.net-web-api cors windows-authentication unauthorized

我正在开发一个简单的预订平台,需要从jQuery向运行在.NET Core MVC上的Web API发送CORS(Cross origin Requests)。

AJAX调用

我经常发送两个ajax请求,一个要删除,一个要添加到使用Entity Framework的数据库:

var deleteReservation = function (reservationID) {
    var u = $.ajax({
        url: url+"/api/booking/del",
        method: "POST",
        async: true,
        xhrFields: {
            withCredentials: true
        },
        data: { "id": reservationID }
    }).done(function (data) {
        refresh();
    });
};

var book = function (reservation) {
    var u = $.ajax({
        url: url + "/api/booking/new",
        method: "POST",
        async: true,
        xhrFields: {
            withcredentials: true
        },
        data: { "reservation": JSON.stringify(reservation) }
    }).done(function (data) {
        console.log(data);
        refresh();
    });
};

实施Windows身份验证

我需要通过Windows身份验证来授权这些请求。我在API上设置了CORS以允许它来自我在appsettings.json中"CORSOrigin"键下指定的地址:

public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddCors();
        services.AddRouting();
        services.AddEntityFrameworkSqlServer();

        services.AddDbContext<BookingContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddMvc();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, BookingContext context)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseCors(builder =>
        builder.WithOrigins($"{Configuration["CORSOrigin"]}").AllowAnyHeader().AllowCredentials());

        app.UseMvc();

        DbInitializer.Initialize(context);
    }

API控制器

最后,我的BookingController.cs中的两个方法是在reguest上调用的:

[Route("api/[controller]")]
[Authorize]
public class BookingController : Controller
{
    private readonly BookingContext context;

    public BookingController(BookingContext context)
    {
        this.context = context;
    }   

    [HttpPost("new")]
    public IActionResult book(String reservation) {
        var r = JsonConvert.DeserializeObject<Reservation>(reservation);
        context.Reservations.Add(new Reservation(r.SeatID, r.User, r.Date));
       context.SaveChanges();
        return Ok();
    }

    [HttpPost("del")]
    public IActionResult deleteReservation(int id) {
        var r = context.Reservations.SingleOrDefault(x => x.ID == id);
        if (r == null) return NotFound("Can't found requested reservation.");

        context.Reservations.Remove(r);
        context.SaveChanges();
        return Ok();

    }
}

问题:使用IE浏览器而非Chrome浏览器

现在的问题是所有请求都在Internet Explorer中完美运行,我可以使用Windows身份验证,但是,当我在Chrome或Opera中运行这些请求时,deleteReservation(reservationID) ajax获得授权,但对于book(reservation)我一直收到401(未经授权)。

研究

我在这个问题上玩了几个小时,并且认为它可能是由不正确的预检请求引起的。我尝试从这些帖子中实现了很多解决方案:

另一方面,Somu用户报告说它可以在Chrome中运行:

结论

关于我的问题的专长在于它在一个控制器方法中工作但在另一个控制器方法中不工作。这两者的区别仅在于它们与数据库一起使用的方式(添加和删除)。

如果我对某些.NET术语不准确,请纠正我。我只和它一起工作了一个月。感谢任何人的时间和乐于助人。

1 个答案:

答案 0 :(得分:1)

这是一个错字导致了这个问题。在没有在chrome中工作的AJAX调用中,它表示withcredentials拼写没有camelCase。 Internet Explorer没问题,其他浏览器没有。