【问题标题】:Asp.net core, Angular 2. CookieAuth issueAsp.net 核心,Angular 2. CookieAuth 问题
【发布时间】:2016-10-30 18:20:25
【问题描述】:

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

如果用户未登录,一切都会按预期工作。当用户尝试访问受保护的资源时,我会从 web 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 });

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

失败: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0] 执行请求时发生未处理的异常 System.InvalidOperationException: No service for type 'Microsoft.AspNetCore.Identity.ISecurityStampValidator' 已被 注册。 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供者,类型 serviceType) 在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider 提供者)在 Microsoft.AspNetCore.Identity.SecurityStampValidator.ValidatePrincipalAsync(CookieValidatePrincipalContext 上下文)在 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" });
        });
    }
}

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

【问题讨论】:

    标签: c# asp.net asp.net-mvc angular .net-core


    【解决方案1】:

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

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

    public class YourSecurityStampValidator : ISecurityStampValidator
    {
        ....
    }
    
    // Register it 
    
    services.TryAddScoped<ISecurityStampValidator, YourSecurityStampValidator>();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-09
      • 1970-01-01
      • 2019-04-24
      • 1970-01-01
      • 2017-05-20
      • 2017-02-01
      • 1970-01-01
      • 2017-03-18
      相关资源
      最近更新 更多