我在web API .net5 (.net core)中编写了一个服务,我使用Windows authentication=true,因为我需要当前用户的详细信息。但是,当"windowsAuthentication"没错,"anonymousAuthentication"假的,我的angular应用无法访问该服务,它返回了未授权错误:401未授权的选项和控制台中:
Access to XMLHttpRequest at 'https://localhost:44343/api/smooss' from origin 'http://localhost:4200' has been blocked by 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 );
}}
i have interceptor that adds withCredentials=true:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
debugger;
request = request.clone({
withCredentials: true
});
return next.handle(request);
}
in server:
startup.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();
}
in controller:
[EnableCors("MyPolicy")]
[Authorize(Policy = "AppSmooss")]
[Route("api/smooss")]
[ApiController]
public class SmoossApi : ControllerBase
this is the method:
[HttpGet]
public async Task<List<Smooss>> Get()
{
return await SmoosRepository.GetFlights();
}
所以最后我找到了解决方案,感谢Rena对这篇文章的评论: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'
})
};