2016-10-30 3 views
0

У меня есть приложение asp.net-core и Angular 2, которое использует CookieAuthentication.Ядро Asp.net, Угловое 2. Ошибка CookieAuth

Все работает как ожидалось, если пользователь не выполнил вход. Я получаю код состояния 401 обратно из веб-api, когда пользователи пытаются получить доступ к защищенному ресурсу.

[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" }); 
     }); 
    } 
} 

Надеюсь, это имеет смысл. Пожалуйста, дайте мне знать, если мне нужно предоставить дополнительную информацию. Любая помощь при разрешении этой ошибки будет принята с благодарностью.

ответ

0

Проблема возникает из OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync. SecurityStampValidator.ValidatePrincipalAsync - метод расширения, и для этого требуется ISecurityStampValidator. Поскольку вы не используете идентификатор aspnet, нет зарегистрированной реализации для ISecurityStampValidator.

Удалить этот код или реализовать собственный ISecurityStampValidator и зарегистрировать его с помощью инъекции зависимостей:

public class YourSecurityStampValidator : ISecurityStampValidator 
{ 
    .... 
} 

// Register it 

services.TryAddScoped<ISecurityStampValidator, YourSecurityStampValidator>(); 
+0

Это прекрасно! Благодаря Adem. Задача решена. –

Смежные вопросы