我在.NET Core Web API中编写了一个服务,我使用windowsauthentication=true,因为我需要当前用户的详细信息。但当
"windowsAuthentication": true,
"anonymousAuthentication": false,
我的 Angular 应用程序无法访问该服务,并且返回未授权错误: 401 未授权选项和控制台:
从源“http://localhost:4200”访问“https://localhost:44343/api/smooss”处的 XMLHttpRequest 已被 CORS 阻止
当我设置
"anonymousAuthentication": true
时它确实有效,但我没有用户的详细信息
我的代码看起来像这样:
客户:
public CheckISAuthorized() {
const requestOptions = {
headers: new HttpHeaders({
'Authorization': "my-request-token",
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
})
};
return this.http.get(`${baseUrl}smooss`,requestOptions );
}}
我有一个拦截器,可以添加
withCredentials=true
:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
debugger;
request = request.clone({
withCredentials: true
});
return next.handle(request);
}
在服务器中:
启动.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<SMOOSSContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SmoosDB")));
services.AddControllers();
services.AddScoped<ISmooseRepository, SmoosRepository>();
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.WithOrigins("http://localhost:4200")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
}));
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Smoos", Version = "v1" });
});
services.AddSingleton<IAuthorizationHandler, AppSmoossRequirement>();
services.AddAuthorization(options =>
{
options.AddPolicy("AppSmooss", policy => policy.Requirements.Add(new AppSmoossRequirement()));
});
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Smoos v1"));
}
app.UseRouting();
app.UseAuthentication();
app.UseCors("MyPolicy");
app.UseHttpsRedirection();
app.UseAuthorization();
}
在控制器中:
[EnableCors("MyPolicy")]
[Authorize(Policy = "AppSmooss")]
[Route("api/smooss")]
[ApiController]
public class SmoossApi : ControllerBase
方法是这样的:
[HttpGet]
public async Task<List<Smooss>> Get()
{
return await SmoosRepository.GetFlights();
}
所以最后我找到了解决方案,感谢 瑞娜对这篇文章的评论: github.com/aspnet/CORS/issues/60 问题在于,来自浏览器的选项调用未与凭据一起发送,这就是其未经授权的原因。 解决方案是添加一个中间件来处理选项请求 并允许 Windows 和匿名身份验证,以便选项请求成功
中间件:
public async Task Invoke(HttpContext context)
{
if (context.Request.Method != "OPTIONS" &&
!context.User.Identity.IsAuthenticated)
{
context.Response.StatusCode = 401;
return; //Stop pipeline and return immediately.
}
await _next(context);
}
在 launchSettings.json 中:
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": true ,
我还必须删除客户端中的授权标头:
const requestOptions = {
headers: new HttpHeaders({
//this line is not needed
// 'Authorization': "my-request-token",
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
})
};
我们必须在startup.cs中哪里添加Invoke中间件? 谢谢