开发者

ADAM and Azman with ASP.Net forms authentication

开发者 https://www.devze.com 2023-03-30 10:40 出处:网络
Has anyone been able to make ADAM/Azman work with ASP.Net forms authentication. The default ADAM role provider works only with AD Domain users. And every single article I have read says that you need

Has anyone been able to make ADAM/Azman work with ASP.Net forms authentication. The default ADAM role provider works only with AD Domain users. And every single article I have read says that you need to write a custom role provider for it.

I have also found out bits and pieces of custom role provider code here and there, but nothing concrete. If someone can share the roleprovider needed for this, that will be great.

I have followed following articles so far :

  1. Custom Role provider (doesn't work) - http://www.codeproject.com/KB/aspnet/active_directory_roles.aspx
  2. Partial Custom Role provider code - http://blogs.msdn.com/b/azman/archive/2006/05/06/591230.aspx
  3. Partial Custom Role provider code again - http://blog.avanadeadvisor.com/blogs/johanr/archive/2009/01/20/12373.aspx
  4. MS Article steps to setup ADAM and use it with ASP.Net (windows auth)
  5. Getting started with ADAM for authentication (no roles) - http://www.开发者_开发问答alexthissen.nl/blogs/main/archive/2007/07/26/getting-started-with-adam-and-asp-net-2-0.aspx


I have a hacked version, and I seriously mean hacked. I don't need to modify roles in my app, so I only implemented 2 methods. I had to send a username and password to query the directory. Someday I'd like to figure out how to use the ActiveDirectoryMembershipProvider's connection string, but I did not spend a lot of time with it, that would simplify things.

 public class ActiveDirectoryFormsRoleProvider : RoleProvider
{
    public string DomainController { get; set; }
    public string ConnectionLDAPSuffix { get; set; }
    public string ConnectionUserName { get; set; }
    public string ConnectionPassword { get; set; }
    public override string ApplicationName { get; set; }

    public override bool IsUserInRole(string username, string roleName)
    {
        var roles = GetRolesForUser(username);
        return roles.Contains(roleName);
    }

    public override string[] GetRolesForUser(string username)
    {
        var results = new List<string>();
        using (var context = new PrincipalContext(ContextType.Domain, DomainController,ConnectionLDAPSuffix,ConnectionUserName,ConnectionPassword))
        {
            try
            {
                var p = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);

                //looping twice because I was getting AppDomainUnloadedException on 50% of the first attempts
                for (var i = 0; i < 2; i++)
                {
                    try
                    {
                        var groups = p.GetAuthorizationGroups();
                        foreach (GroupPrincipal group in groups)
                        {
                            var name = group.SamAccountName;
                            if (!string.IsNullOrWhiteSpace(name))
                                results.Add(group.SamAccountName);
                        }
                        break;
                    }
                    catch (AppDomainUnloadedException)
                    {

                    }
                }
            }
            catch (Exception ex)
            {
                throw new ProviderException("Unable to query Active Directory.", ex);
            }
        }

        return results.ToArray();
    }

...

For some reason on my production server, I have to make 2 attempts of GetAuthorizationGroups() because 50% of the time the first attempt failed by throwing AppDomainUnloadedException. You might be able to remove that for loop.

And here is my web.config element:

<roleManager enabled="true" defaultProvider="ActiveDirectoryFormsRoleProvider">
      <providers>
        <clear />
       <add name="ActiveDirectoryFormsRoleProvider"
          type="myapp.ActiveDirectoryFormsRoleProvider" 
          applicationName="myapp"
          DomainController="domaincontroller.testdomain.corp"
          ConnectionLDAPSuffix="DC=testdomain,DC=corp"
          ConnectionUsername="username"
          ConnectionPassword="password"
        />
      </providers>
    </roleManager>
0

精彩评论

暂无评论...
验证码 换一张
取 消