如何在 ASP.NET Core 3.1 的另一个应用程序中包含用户管理器

Posted

技术标签:

【中文标题】如何在 ASP.NET Core 3.1 的另一个应用程序中包含用户管理器【英文标题】:How to include a user manager to another application for ASP.NET Core 3.1 【发布时间】:2020-07-20 00:07:25 【问题描述】:

我正在开发两个不同的应用程序,我将它们命名为 A 和 B。

A 是一个互联网平台,只有拥有有效用户帐户才能登录。 B 是一个 Intranet 平台,用户可以在其中通过 Active Directory 进行身份验证。使用应用程序 B 的管理员应该能够为应用程序 A 创建新的用户帐户。

创建新用户帐户后,我希望能够实现不同的功能,例如向注册的邮件地址发送电子邮件,以便新用户可以更改默认密码。

我想要实现的所有功能都可以由 UserManager 完成(请参阅以下链接中的“使用其他应用程序添加用户”部分:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-3.1&tabs=visual-studio#disable-register-page)。

基于此我实现了以下代码:

public class ControllerClass : Controller

    private readonly HelperClass _helper;
    private readonly UserManager<IdentityUser> _userManager;

    public ControllerClass (UserManager<IdentityUser> userManager)
    
        _userManager = userManager;
        _helper= new HelperClass (userManager);
    


public class HelperClass 

    private readonly DbContext _db;
    private readonly UserManager<IdentityUser> _userManager;

    public HelperClass (UserManager<IdentityUser> userManager)
    
        _db = new DbContext ();
        _userManager = userManager;
    

    private async Task<string> EnsureUser(string userName, string userPassword)
    
        var user = await _userManager.FindByNameAsync(userName);

        if (user == null)
        
            user = new IdentityUser()
            
                UserName = userName                    
            ;
            await _userManager.CreateAsync(user, userPassword);
        

        return user.Id;
    


    internal async void CreateUser(UserVM uvm, int id)
    
        var userId = await EnsureUser(uvm.userName, uvm.userPassword);

        // TODO ...
    


很遗憾,我没有设法将 UserManager 包含到我的应用程序 B 中。我收到以下错误消息:“处理请求时发生未处理的异常。 InvalidOperationException:尝试激活“ControllerClass”时,无法解析“Microsoft.AspNetCore.Identity.UserManager`1[IdentityUser]”类型的服务。”

您知道如何添加 UserManager 来管理另一个应用程序的用户吗?

【问题讨论】:

【参考方案1】:

嗯,你得到的具体错误仅仅是因为UserManager&lt;TUser&gt; 没有在服务集合中注册。为了注入anything,你必须先注册它。在您实际面向用户的应用程序中,这是由services.AddIdentity() 完成的。然而,这不仅仅是注册UserManager&lt;TUser&gt;,所以你不应该只是跑掉并在你的第二个应用程序中添加相同的命令。

您可以专门为其添加注册:

services.AddScoped<UserManager<ApplicationUser>>();

然而,它实际上有大量的依赖,每一个都需要被注册。如果您查看constructor,则有七个 服务未注册开箱即用,其中许多都有自己的依赖关系树。久而久之,痛不欲生。这里还有关注点分离的问题。这需要从其他应用添加整个数据层。

最好的办法是简单地在 Identity 应用上公开一个 API(当然,将其锁定)。这样,与用户合作的所有逻辑都与该逻辑的其余部分保持一致。然后,管理应用程序可以调用 API 来添加、更新、删除等用户,而无需知道实际是如何完成的。

【讨论】:

非常感谢,这很有意义。在当前解决方案中,我通过实体框架手动添加(或编辑)用户帐户。现在,我正在考虑按照您的回答将所有内容移至 API。我希望解决问题会更容易。 我正在与 schmityv 一起工作:我们发现我们已经在 Appl B 的启动类中有 services.AddDefaultIdentity。因此,如果我们将构造函数从 UserManager 更改为标准 UserManager 并使“OurIdentityClass”继承自“IdentityUser”,注入按预期工作。然而,userManager 不工作(内部没有用户)并且查找用户的任务超时......对此有任何输入吗? 可能是连接字符串问题。没有点击正确的或任何数据库。

以上是关于如何在 ASP.NET Core 3.1 的另一个应用程序中包含用户管理器的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UserManager 注入 ASP.NET Core 2.0 中的另一个服务

如何在 ASP.NET Core 3.1 中使用 Java?

阻止对 ASP.NET Core 3.1 API 的服务器到服务器或 Postman 调用

如何在 ASP.NET Core 3.1 中逐行迭代列表

如何从数据库中读取加密值并将其与 ASP.NET Core 中的另一个值进行比较?

如何使用 C# 在 ASP.NET Core 3.1 MVC 中使用会话变量