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();

然后 UseCorsConfigure:

// 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 身份验证生成器包。