C# 如何将ActiveDirectoryMembershipProvider与ASP.Net标识一起使用?

C# 如何将ActiveDirectoryMembershipProvider与ASP.Net标识一起使用?,c#,asp.net,asp.net-membership,asp.net-identity,asp.net-identity-2,C#,Asp.net,Asp.net Membership,Asp.net Identity,Asp.net Identity 2,我正在努力学习如何使用ASP.Net标识。我的情况是,我必须对Active Directory进行身份验证。为此,我尝试使用activedirecorymembershipProvider。我要做的是- 根据Active Directory验证用户/密码 检查用户是否存在于我自己的数据库中 我这样做的方式是在web.config中配置使用ActiveDirectoryMembershipProvider作为默认成员资格提供程序。然后,我在我的应用程序SignInManager类(继承SignIn

我正在努力学习如何使用ASP.Net标识。我的情况是,我必须对Active Directory进行身份验证。为此,我尝试使用
activedirecorymembershipProvider
。我要做的是-

  • 根据Active Directory验证用户/密码
  • 检查用户是否存在于我自己的数据库中
  • 我这样做的方式是在
    web.config
    中配置使用
    ActiveDirectoryMembershipProvider
    作为默认成员资格提供程序。然后,我在我的
    应用程序SignInManager
    类(继承
    SignInManager
    )中重写
    PasswordSignInAsync
    方法,如下所示-

    public override Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
    {
        var adok = Membership.Provider.ValidateUser(userName, password);
        if (adok)
        {
            var user = UserManager.FindByName(userName);
            if (user == null)
                return Task.FromResult<SignInStatus>(SignInStatus.Failure);
            else
            {
                base.SignInAsync(user, isPersistent, shouldLockout);
                return Task.FromResult<SignInStatus>(SignInStatus.Success);
            }
        }
        else
            return Task.FromResult<SignInStatus>(SignInStatus.Failure);
    }
    
    IList<UserLoginInfo> loginInfos = await SignInManager.UserManager.GetLoginsAsync(username);
    var valid = false;
    foreach(var info in loginInfos)
    {
        valid = Membership.Providers[info.ProviderKey].ValidateUser(username, password);
        if (valid) break;
    }
    
    根据我得到的答案,我不应该在
    PasswordSignInAsync
    中调用Membership
    Validate
    方法。我同意这一点。事实上,我认为重写该方法也是错误的

    也有人建议我使用
    UserLogins
    ,在那里我会给我的广告提供一个提供者ID。但我能想到的唯一方法是如下-

    public override Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
    {
        var adok = Membership.Provider.ValidateUser(userName, password);
        if (adok)
        {
            var user = UserManager.FindByName(userName);
            if (user == null)
                return Task.FromResult<SignInStatus>(SignInStatus.Failure);
            else
            {
                base.SignInAsync(user, isPersistent, shouldLockout);
                return Task.FromResult<SignInStatus>(SignInStatus.Success);
            }
        }
        else
            return Task.FromResult<SignInStatus>(SignInStatus.Failure);
    }
    
    IList<UserLoginInfo> loginInfos = await SignInManager.UserManager.GetLoginsAsync(username);
    var valid = false;
    foreach(var info in loginInfos)
    {
        valid = Membership.Providers[info.ProviderKey].ValidateUser(username, password);
        if (valid) break;
    }
    
    IList loginInfos=wait SignInManager.UserManager.GetLoginsAsync(用户名);
    var-valid=false;
    foreach(loginInfos中的var信息)
    {
    valid=Membership.Providers[info.ProviderKey].ValidateUser(用户名、密码);
    如果(有效)中断;
    }
    
    因此,如果我想针对多个提供者对用户进行身份验证,我可以为每个提供者创建提供者密钥,并将这些提供者密钥分配给用户。这段代码将根据它们验证用户。但是我应该把这个代码放在哪里呢?我应该遵循什么惯例


    我不喜欢自己编写广告验证代码,因为我认为
    ActiveDirectoryMembershipProvider
    可以比我自己的代码做得更好。另外,对于这两种情况,我都必须添加对
    System.DirectoryServices
    的引用。

    在下面的步骤中尝试一下,可能会对您有所帮助


    您不想将会员资格提供者与身份混淆。您最想做的是,将登录ActiveDirectory与identity对待其他外部登录(如google/facebook)的方式类似

    这基本上归结为将广告用户名存储为登录名:

    userManager.AddLogin(,新用户登录信息(“ActiveDirectory”),“


    否则,您可能只希望在特定的AD登录流中使用此选项,保留现有的本地密码/社交登录功能。

    不要只是拒绝投票,请留下评论,以便我理解您拒绝投票背后的原因。我想您可能被否决了,因为您的帖子似乎没有明显的问题。您的代码是在工作中,但需要其他途径的建议。这更适合于网站的代码审查部分:为什么?我已经在我的问题中明确说明了我想要什么。我可能有可以工作的代码,但这并不意味着它是正确的。看看这个@ozhug,我看到了。它使用windows身份验证。但我需要表单身份验证正如我在问题中提到的,分为两个级别。您提供的链接没有使用。我不知道如何将Active Directory配置为外部登录。您能详细说明一下吗?当创建用户或现有用户希望链接广告登录时,您需要在您的应用程序UI流中公开此内容。也就是说,您将在上面调用AddLogin代码的时候没有魔术配置,你只需要为你的应用程序中的广告选择一个providerID常量。外部登录表已经通过身份设置,你只需要使用该功能。我没有使用内置数据库或EF。使用的数据库是自定义的。所以基本上我是从头开始实现的。我把上面提到的代码放在哪里?那是c通常出现在控制器/页面(应用程序代码)中的ode,而不是标识代码