Aurelia Windows 身份验证 - Post 401 未经授权
Aurelia Windows Authentication - Post 401 Unauthorized
我完全坚持为我的一个使用 Aurelia 作为客户端的 .NET Core 应用程序实施 Windows 身份验证。
Aurelia 应用程序托管在 端口:9000 上,.NET WebAPI 托管在 port:9001 上。
我的想法是在应用程序发布后从我的 .NET 应用程序提供静态页面,但现在在开发中我使用 port:9000 因为 Aurelia 提供的 BrowserSync。
当我使用 port:9000 时,一切都很好,我没有任何问题 posting 或 getting。
如果我切换到port:9001我仍然可以得到但不是post。 Post 结果为 401 Unauthorized
。
如果我们查看 headers 的 port:9000 请求..
获取(成功):
Post(失败):
由于某些原因,您可以看到 post 中缺少多个 headers,最重要的是身份验证 cookie..
Base-Repo.js
import {inject} from 'aurelia-framework';
import {HttpClient, json} from 'aurelia-fetch-client';
import {AppSettings} from '../infrastructure/app-settings';
@inject(HttpClient, AppSettings)
export class BaseRepo {
constructor(http, appSettings) {
http.configure(config => {
config
.withDefaults({
credentials: 'include',
headers: {
'Accept': 'application/json'
}
})
.withInterceptor({
request(request) {
console.log(`Requesting ${request.method} ${request.url}`);
return request;
},
response(response) {
console.log(`Received ${response.status} ${response.url}`);
return response;
}
})
});
this.http = http;
this.baseUrl = appSettings.api;
}
get(url) {
console.log('BaseRepo(get): ' + url);
return this.http.fetch(this.baseUrl + url)
.then(response => { return response.json(); })
.then(data => { return data; });
}
post(url, data) {
console.log('BaseRepo(post): ' + url, data);
return this.http.fetch(this.baseUrl + url, {
method: 'post',
body: json(data)
})
.then(response => response.json())
.then(data => { return data; });
}
}
为什么在使用 BrowserSync 端口时 GET 工作但 POST 不工作?
编辑 1
Post(成功)对于 port:9001:
编辑 2
控制台消息 post 错误:
OPTIONS http://localhost:9001/api/MYURLS 401 (Unauthorized)
Fetch API cannot load
http://localhost:9001/api/MYURLS.
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:9000' is therefore not allowed
access. The response had HTTP status code 401. If an opaque response
serves your needs, set the request's mode to 'no-cors' to fetch the
resource with CORS disabled.
编辑 3
Startup.cs
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)
.AddEnvironmentVariables();
Configuration = builder.Build();
env.ConfigureNLog("nlog.config");
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddMemoryCache();
services.AddMvc();
services.InjectWebServices();
services.AddOptions();
//call this in case you need aspnet-user-authtype/aspnet-user-identity
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IConfiguration>(Configuration);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors("CorsPolicy");
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
app.UseDefaultFiles();
app.UseStaticFiles();
//add NLog to ASP.NET Core
loggerFactory.AddNLog();
//add NLog.Web
app.AddNLogWeb();
}
}
您需要启用 CORS in your ASP.NET Core project. There's information on how to do this here: https://docs.microsoft.com/en-us/aspnet/core/security/cors。
您需要在 ConfigureServices
中调用 AddCors
:
services.AddCors();
然后 UseCors
在 Configure
:
// Shows UseCors with CorsPolicyBuilder.
app.UseCors(builder => builder.WithOrigins("http://example.com"));
当您使用端口 9000 时,您与 API 处于不同的来源,但使用 9001 时,您处于同一来源,因此 CORS 将不适用。
OPTIONS 请求称为 "preflighting"。这里有关于这些的更多信息:https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests.
我在项目属性中启用了 "Enable Anonymous Authentication",瞧...
之前我只启用了 "Enable Windows Authenticaiton",现在两个端口都可以了!
部署应用程序时无论如何都不会启用此功能,因为到那时我将使用真正的 IIS。
更新 1
升级到 .net core 2.0 后,我无法再启用 Windows 身份验证和匿名身份验证。
经过一些研究,我发现你必须添加:
services.AddAuthentication(IISDefaults.AuthenticationScheme);
在您的 startup.cs 中以使其正常工作。
可以在 comment section and docs 中找到更多信息。
更新 2
您需要 Microsoft.AspNetCore.Authentication 身份验证生成器包。
我完全坚持为我的一个使用 Aurelia 作为客户端的 .NET Core 应用程序实施 Windows 身份验证。
Aurelia 应用程序托管在 端口:9000 上,.NET WebAPI 托管在 port:9001 上。
我的想法是在应用程序发布后从我的 .NET 应用程序提供静态页面,但现在在开发中我使用 port:9000 因为 Aurelia 提供的 BrowserSync。
当我使用 port:9000 时,一切都很好,我没有任何问题 posting 或 getting。
如果我切换到port:9001我仍然可以得到但不是post。 Post 结果为 401 Unauthorized
。
如果我们查看 headers 的 port:9000 请求..
获取(成功):
Post(失败):
由于某些原因,您可以看到 post 中缺少多个 headers,最重要的是身份验证 cookie..
Base-Repo.js
import {inject} from 'aurelia-framework';
import {HttpClient, json} from 'aurelia-fetch-client';
import {AppSettings} from '../infrastructure/app-settings';
@inject(HttpClient, AppSettings)
export class BaseRepo {
constructor(http, appSettings) {
http.configure(config => {
config
.withDefaults({
credentials: 'include',
headers: {
'Accept': 'application/json'
}
})
.withInterceptor({
request(request) {
console.log(`Requesting ${request.method} ${request.url}`);
return request;
},
response(response) {
console.log(`Received ${response.status} ${response.url}`);
return response;
}
})
});
this.http = http;
this.baseUrl = appSettings.api;
}
get(url) {
console.log('BaseRepo(get): ' + url);
return this.http.fetch(this.baseUrl + url)
.then(response => { return response.json(); })
.then(data => { return data; });
}
post(url, data) {
console.log('BaseRepo(post): ' + url, data);
return this.http.fetch(this.baseUrl + url, {
method: 'post',
body: json(data)
})
.then(response => response.json())
.then(data => { return data; });
}
}
为什么在使用 BrowserSync 端口时 GET 工作但 POST 不工作?
编辑 1
Post(成功)对于 port:9001:
编辑 2 控制台消息 post 错误:
OPTIONS
http://localhost:9001/api/MYURLS 401 (Unauthorized)
Fetch API cannot load http://localhost:9001/api/MYURLS. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. The response had HTTP status code 401. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
编辑 3
Startup.cs
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)
.AddEnvironmentVariables();
Configuration = builder.Build();
env.ConfigureNLog("nlog.config");
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddMemoryCache();
services.AddMvc();
services.InjectWebServices();
services.AddOptions();
//call this in case you need aspnet-user-authtype/aspnet-user-identity
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IConfiguration>(Configuration);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseCors("CorsPolicy");
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
app.UseDefaultFiles();
app.UseStaticFiles();
//add NLog to ASP.NET Core
loggerFactory.AddNLog();
//add NLog.Web
app.AddNLogWeb();
}
}
您需要启用 CORS in your ASP.NET Core project. There's information on how to do this here: https://docs.microsoft.com/en-us/aspnet/core/security/cors。
您需要在 ConfigureServices
中调用 AddCors
:
services.AddCors();
然后 UseCors
在 Configure
:
// Shows UseCors with CorsPolicyBuilder.
app.UseCors(builder => builder.WithOrigins("http://example.com"));
当您使用端口 9000 时,您与 API 处于不同的来源,但使用 9001 时,您处于同一来源,因此 CORS 将不适用。
OPTIONS 请求称为 "preflighting"。这里有关于这些的更多信息:https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests.
我在项目属性中启用了 "Enable Anonymous Authentication",瞧...
之前我只启用了 "Enable Windows Authenticaiton",现在两个端口都可以了!
部署应用程序时无论如何都不会启用此功能,因为到那时我将使用真正的 IIS。
更新 1
升级到 .net core 2.0 后,我无法再启用 Windows 身份验证和匿名身份验证。 经过一些研究,我发现你必须添加:
services.AddAuthentication(IISDefaults.AuthenticationScheme);
在您的 startup.cs 中以使其正常工作。
可以在 comment section and docs 中找到更多信息。
更新 2
您需要 Microsoft.AspNetCore.Authentication 身份验证生成器包。