Asp.net 核心,Angular 2. CookieAuth 问题

Asp.net core, Angular 2. CookieAuth issue

我有一个使用 CookieAuthentication 的 asp.net-core 和 Angular 2 应用程序。

如果用户未登录,一切都按预期工作。当用户尝试访问受保护的资源时,我从网络 api 收到 401 状态代码。

    [HttpGet("[action]")]
    [Authorize(Policy = "AdminOnly")]
    public IEnumerable<WeatherForecast> WeatherForecasts()
    {

    }

当身份验证通过时,我 运行 SignInAsync 方法:

        var claims = new[] {new Claim(ClaimTypes.Role, "Admin")};
        var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
        HttpContext.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
                                               new ClaimsPrincipal(identity),
                                               new AuthenticationProperties() { IsPersistent = false });

那是我得到以下错误的时候:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0] An unhandled exception has occurred while executing the request System.InvalidOperationException: No service for type 'Microsoft.AspNetCore.Identity.ISecurityStampValidator' has been registered. at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.AspNetCore.Identity.SecurityStampValidator.ValidatePrincipalAsync(CookieValidatePrincipalContext context) at Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler.d__12.MoveNext()

我的startup.cs配置为:

    public class Startup
    {
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }
    public IConfigurationRoot Configuration { get; }
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication();
        // Polices
        services.AddAuthorization(options =>
        {
            // inline policies
            options.AddPolicy("AdminOnly", policy =>
            {
                policy.RequireClaim(ClaimTypes.Role, "Admin");
            });
        });
        // Add framework services.
        services.AddMvc();
    }
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
        app.UseStaticFiles();
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
            {
                HotModuleReplacement = true
            });
        }
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            //Don't redirect to /Account/Login.
            Events = new CookieAuthenticationEvents
            {
                OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync,
                OnRedirectToLogin = ctx =>
                {
                    // If request comming from web api
                    // always return Unauthorized (401)
                    if (ctx.Request.Path.StartsWithSegments("/api") &&
                        ctx.Response.StatusCode == (int)HttpStatusCode.OK)
                    {
                        ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    }
                    else
                    {
                        ctx.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    }
                    return Task.FromResult(0);
                }
            },
            CookieHttpOnly = true
        });
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
            routes.MapSpaFallbackRoute(
                name: "spa-fallback",
                defaults: new { controller = "Home", action = "Index" });
        });
    }
}

我希望这是有道理的。 如果我需要提供任何其他信息,请告诉我。 将不胜感激解决此错误的任何帮助。

问题是由OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync引起的。 SecurityStampValidator.ValidatePrincipalAsync 是一种扩展方法,它需要 ISecurityStampValidator。由于您不使用 aspnet 标识,因此没有 ISecurityStampValidator.

的注册实现

删除此代码或实现自己的 ISecurityStampValidator 并通过依赖注入注册它:

public class YourSecurityStampValidator : ISecurityStampValidator
{
    ....
}

// Register it 

services.TryAddScoped<ISecurityStampValidator, YourSecurityStampValidator>();