Want to look up an AD Group's SID without using samAccountName or DirectoryServices.AccountManagement
active-directory, asp.net-mvc, authentication, authorization, c#
Solution
You can do this pretty easily - set up a domain context, find the group, get the `Sid` property - something like this:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find your group - by group name, group DN, SAM Account Name - whatever you like!
// This is **NOT** limited to just SAM AccountName!
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, groupSamAccountName);
if(group != null)
{
// this gives you the variable of type "SecurityIdentifier" to be used in your
// call to "IsInRole" ....
SecurityIdentifier groupSid = group.Sid;
string groupSidSDDL = groupSid.Value;
}
Also: I don't understand your aversion towards using the `samAccountName` - it's a mandatory and unique property for each group - so it would be a perfect match to uniquely identify your groups!
You should check out the `System.DirectoryServices.AccountManagement` (S.DS.AM) namespace. Read all about it here:
- Managing Directory Security Principals in the .NET Framework 3.5
- MSDN docs on System.DirectoryServices.AccountManagement
The new S.DS.AM makes it really easy to play around with users and groups in AD!
Problem
Question: In C#, is there a way to look up an Active Directory Group SID without using `DirectoryServices.AccountManagement` library or icky-ugly LDAP? [UPDATED] -- Why I'm asking: The `[Authorize]` attribute and the underlying `WindowsPrincipal.IsInRole(string role)` only check against the `samAccountName` in AD. Not only is this a legacy identifier that Microsoft suggests avoiding when checking roles: ``` // It is also better from a performance standpoint than the overload that accepts a string. // The aformentioned overloads remain in this class since we do not want to introduce a // breaking change. However, this method should be used in all new applications and we should document this. public virtual bool IsInRole (SecurityIdentifier sid) {} ``` but I also don't have control over AD, and cannot ensure the samAccountName remains in sync with the "user friendly" names we request be setup. This is the reason the issue came up in the first place, passing a pluralized (Name) rather than a singular (samAccountName) string... the values were not the same. Also, the samAccountName and the SID may change - for example, if an AD admin deletes the account and re-creates it, the SID will for sure be different, and the samAccountName another spot for human error, but they will always restore the Name/UPN values as requested. Eventually I want to write a clean authorize attribute of my own to check against group membership without having to hard code SAMs or SIDs. I know I can do this with DirectoryServices.AccountManagement: ``` // get group principal var pc = new PrincipalContext(ContextType.Domain, "domainName"); var gp = GroupPrincipal.FindByIdentity(pc, IdentityType.Name, "groupName"); // check if user is in group. var up = UserPrincipal.Current; var usersGroups = up.GetGroups(); var inGroup = usersGroups.Contains(gp); ``` I just wanted to know if there was an easier, less dependent, non legacy way to do this to keep the attribute-to-be-programmed, lean as possible. My prior, related question: Active Directory Group Membership Checking in .Net 4.5