简体   繁体   English

使用ASP.NET身份验证和LDAP的身份验证/授权

[英]Authentication/Authorization using ASP.NET authentication and LDAP

I have an existing ASP.NET application that uses LDAP for authentication and ASP.NET membership for authentication and authorization. 我有一个现有的ASP.NET应用程序,它使用LDAP进行身份验证,并使用ASP.NET成员身份进行身份验证和授权。

So an LDAP user could choose to authenticate either using his LDAP credentials, or ASP.NET membership credentials. 因此,LDAP用户可以选择使用其LDAP凭据或ASP.NET成员身份凭据进行身份验证。 A non LDAP user can only authenticate using LDAP credentials. 非LDAP用户只能使用LDAP凭据进行身份验证。

I now want to create a Web API project that uses a similar approach for authentication and authorization. 我现在想创建一个Web API项目,该项目使用类似的身份验证和授权方法。

Using VS 2013, I created a new Web API project that uses the Individual Accounts option for authentication. 使用VS 2013,我创建了一个新的Web API项目,该项目使用“个人帐户”选项进行身份验证。

I've modified the GrantResourceOwnerCredentials method in the Providers\\ApplicationOAuthProvider.cs file. 我已经在Providers \\ ApplicationOAuthProvider.cs文件中修改了GrantResourceOwnerCredentials方法。

Before 之前

...
IdentityUser user = await userManager.FindAsync(context.UserName, context.Password);

if (user == null)
{
    context.SetError("invalid_grant", "The user name or password is incorrect.");
    return;
}
...

After

...
IdentityUser user;

if (AuthenticateActiveDirectory(context.UserName, context.Password, "MyADDomain"))
{
    user = await userManager.FindByNameAsync(context.UserName);
}
else
{
    user = await userManager.FindAsync(context.UserName, context.Password);
}

if (user == null)
{
    context.SetError("invalid_grant", "The user name or password is incorrect.");
    return;
}
...

And the AuthenticateActiveDirectory method is: AuthenticateActiveDirectory方法是:

   private bool AuthenticateActiveDirectory(string userName, string password, string domain)
   {
     bool validation;
     try
     {
        var lcon = new LdapConnection(new LdapDirectoryIdentifier((string)null, false, false));
        var nc = new NetworkCredential(userName, password, domain);
        lcon.Credential = nc;
        lcon.AuthType = AuthType.Negotiate;
        lcon.Bind(nc);
        validation = true;
     }
     catch (LdapException)
     {
        validation = false;
     }
     return validation;
   }

This works, but is it the best way of doing it or is there a better way? 这行得通,但这是最好的方法还是有更好的方法?

It's fine. 没关系。 Couple things come to mind: 几件事想到:

  • If you have multiple domains in your forest (or ever will support that), username isn't unique across the forest - just the domain. 如果您的目录林中有多个域(或曾经支持),则用户名在整个目录林中不是唯一的-只是域。 Looks like you're keying on username today. 看来您今天要输入使用者名称。
  • For your LdapConnection , I assume the null server name is just for show here? 对于您的LdapConnection ,我认为空服务器名称仅用于此处显示? Rather than hardcoding one, you can use the S.DS.AD namespace to find a domain controller for you. 您可以使用S.DS.AD命名空间为您找到一个域控制器,而不是对其进行硬编码。
  • You'd probably want AuthType.Basic rather than Negotiate here. 您可能需要AuthType.Basic而不是在此处进行协商。 You'll want to make sure your connection is LDAP/S since the creds will be cleartext. 您将要确保您的连接是LDAP / S,因为凭据将是明文形式的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM