我在ASP Net Core 2.2堆栈上基于令牌实现了自己的身份验证。 我正确配置了cors策略,因为在我的方案中,我使用了另一个域中的react应用程序的webapi。所有的http请求均有效,但获取令牌的请求无效。它已被Cors阻止。
这是我的Startup.cs:
public void Configure(IApplicationBuilder app){
app.UseAuthentication();
app.UseMiddleware<MyMiddleware>();
app.UseCors("MyPolicy");
app.Map(basePath, a => a.UseOwin());
}
public void ConfigureServices(IServiceCollection services)
{
services
.AddAuthentication()
.AddMyAuth(o => { });
services.AddCors(options => options
.AddPolicy(PolicyName,
builder => builder
.SetIsOriginAllowed((host) => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.Build()));
}
这是我的身份验证中间件:
internal class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
HttpRequest request = context.Request;
bool isTokenEndpoint = request.Path.Equals("/auth/token");
if (!isTokenEndpoint)
return _next(context);
// Request must be POST with Content-Type: application/x-www-form-urlencoded
if (!request.Method.Equals("POST") || !request.HasFormContentType)
{
const int statusCode = (int)HttpStatusCode.MethodNotAllowed;
if (context.Response.StatusCode != statusCode)
context.Response.StatusCode = statusCode;
return context.Response.WriteAsync("Method not allowed.");
}
return GenerateTokenAsync(context, isADTokenEndpoint);
}
private static async Task GenerateTokenAsync(HttpContext ctx, bool isActiveDirectory)
{
...
}
}
这是我的打字稿/反应代码,在这里我称为“获取令牌” webapi
const url = `http://localhost:9080/auth/token`;
axios.post(url, data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then((response: any) => {
res = response;
console.log(response);
})
.catch(error => {
console.log(error);
});
我的react应用程序在localhost:3000上运行,并在localhost:9080 / auth / token调用我的webapi。使用此代码,我在控制台浏览器中看到此错误:
CORS策略已阻止从来源“ http://localhost:9080/auth/token”访问“ http://localhost:3000”处的XMLHttpRequest:请求的资源上没有“ Access-Control-Allow-Origin”标头。
错误日志很清楚,但是我不明白为什么其他的webapi不需要这些标头。
如果我这样拨打电话:
const url = `http://localhost:9080/auth/token`;
axios.post(url, data, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'content-type',
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then((response: any) => {
res = response;
console.log(response);
})
.catch(error => {
console.log(error);
});
我收到这个新错误:
选项http://localhost:9080/auth/token 405(不允许使用方法) 从源“ http://localhost:9080/auth/token”对“ http://localhost:3000”处XMLHttpRequest的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:无“ Access-Control-Allow-Origin”标头存在于请求的资源上。
当然,这种新的调用不是一个简单的请求,因此浏览器需要OPTIONS调用,而我尚未实现。 我尝试在检查请求方法的中间件中添加此代码:
if (request.Method.Equals("OPTIONS"))
{
const int statusCode = (int)HttpStatusCode.NoContent;
context.Response.StatusCode = statusCode;
context.Request.Headers.Add("Access-Control-Allow-Origin", "*");
context.Request.Headers.Add("Access-Control-Allow-Methods", "POST");
context.Request.Headers.Add("Access-Control-Allow-Headers", "content-type");
return context.Response.WriteAsync("OPTIONS");
}
此后,我在OPTIONS调用上没有405错误了。.但是我得到了一个新的错误:
从原点“ http://localhost:9080/auth/token”到“ http://localhost:3000”处对XMLHttpRequest的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:否'Access-Control-Allow-来源的标头出现在请求的资源上。
似乎我的OPTIONS响应与通话不匹配。 我没主意了...有什么建议吗?