【问题标题】:How to add the UserManager via Dependency Injection in AspNet.Core 2.1?如何在 AspNet.Core 2.1 中通过依赖注入添加 UserManager?
【发布时间】:2018-07-22 14:17:14
【问题描述】:

我创建了一个 Asp.Net Core 2.1 Web Api,它使用 Identity Server 4 使用 Bearer Token 身份验证。我有两个数据库上下文,一个用于身份,一个用于我的自定义应用程序的数据访问。我希望能够在我的控制器中使用依赖注入在我的 Web Api 中使用 UserManager 和 UserStore。

问题是,一旦我添加了 DI 的“相关”代码,我的控制器方法就会抛出 302 并试图将我重定向到登录 URL。就像我的不记名身份验证被覆盖一样。下面是我的 Startup.cs 的样子。有什么想法应该怎么做?

   public void ConfigureServices(IServiceCollection services)
   {

        string connectionString = Configuration.GetConnectionString("DefaultConnection");
        var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

        services.AddDbContext<CustomContext>(options =>
            options.UseSqlServer(connectionString));

        // start of the stuff that should add the usermanager and userstore
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(connectionString));


        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
        // end of the stuff

        services.AddMvcCore()
            .AddAuthorization()
            .AddJsonFormatters();

        services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "http://authenticate.com";
                options.RequireHttpsMetadata = false;

                options.ApiName = "api1";
            });

        services.AddCors(options =>
        {
            // this defines a CORS policy called "default"
            options.AddPolicy("default", policy =>
            {
                policy.AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials();
            });
        });


    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseAuthentication();
        app.UseCors("default");
        app.UseMvc();
    }

控制器如下所示:

public class PlayerController : BaseApiController
{
    private readonly UserManager<ApplicationUser> userManager;

    public PlayerController(UserManager<ApplicationUser> _userManager)
    {
        userManager = _userManager;
    }
    .....
 }

像这样使用 BaseApiController:

[Route("api/[controller]")]
[Authorize]
public class BaseApiController : Controller
{
    ...
}

【问题讨论】:

  • 您不需要做任何特别的事情,除了将UserManager&lt;T&gt; 添加到您的控制器构造函数中。当您使用 Identity 时,其他一切都已经到位。会不会是您正在使用 MVC 控制器并且您的错误视图/操作需要身份验证?!
  • 另外请记住,建议进行身份验证AFTER CORS 注册。您不希望未登录的用户收到 CORS 错误
  • @Tseng 在我添加新代码之前,如果它抛出错误,它只会向 WebApi 抛出 500(或者如果它在初始化时死掉 502)。所以它不需要身份验证来显示错误消息。目前 CORS 和 Bearer 身份验证没有交互 - 如果我的令牌过期或我没有提供令牌,我会按预期得到 401。我从运行时错误中得到一个 CORS 错误,我目前不认为这是一个问题,因为它已经没有做它应该做的事情。
  • @Tseng 是的,这就是我上面已经说过的。如果我删除了应该添加 DI services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); 的代码一切正常运行,如果我的身份验证不再有效,我会得到 401。添加“DI 代码”会给我一个 302 重定向,这意味着它覆盖了我的承载身份验证。我想在不创建另一层身份验证的情况下添加 UserManager。
  • IdentityServer 和您的 WebAPI 不在同一个应用程序中,对吗?如果它们是单独的应用程序,则在 WebApi 项目中不需要 ASP.NET Core Identity,只需 AddIdentityServerAuthentication 调用。如果是相同的应用程序(不推荐),那么您需要将 ASP.NET Core Identity 与 IdSrv4 集成为 per docs

标签: asp.net-core dependency-injection asp.net-identity asp.net-core-webapi


【解决方案1】:

services.AddIdentity&lt;TUser&gt;() 添加了一个“不必要的”身份验证配置,因为您已经拥有来自 services.AddAuthentication("Bearer").AddIdentityServerAuthentication() 配置的承载方案。看看下面AddIdentity() 的代码。注意还添加了多少方案(包括 cookie 方案)。

public static IdentityBuilder AddIdentity<TUser, TRole>(
        this IServiceCollection services,
        Action<IdentityOptions> setupAction)
        where TUser : class
        where TRole : class
    {
        // Services used by identity
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
            options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
            options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
        })
        .AddCookie(IdentityConstants.ApplicationScheme, o =>
        {
            o.LoginPath = new PathString("/Account/Login");
            o.Events = new CookieAuthenticationEvents
            {
                OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
            };
        })
        .AddCookie(IdentityConstants.ExternalScheme, o =>
        {
            o.Cookie.Name = IdentityConstants.ExternalScheme;
            o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
        })
        .AddCookie(IdentityConstants.TwoFactorRememberMeScheme, o =>
        {
            o.Cookie.Name = IdentityConstants.TwoFactorRememberMeScheme;
            o.Events = new CookieAuthenticationEvents
            {
                OnValidatePrincipal = SecurityStampValidator.ValidateAsync<ITwoFactorSecurityStampValidator>
            };
        })
        .AddCookie(IdentityConstants.TwoFactorUserIdScheme, o =>
        {
            o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;
            o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
        });

        // cut for brevity

        return new IdentityBuilder(typeof(TUser), typeof(TRole), services);
    }

你不需要那个。你需要的是:

services.AddIdentityCore<TUser>()

不添加其他身份验证配置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-02
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 2020-07-19
    相关资源
    最近更新 更多