title: Active Directory Group Membership Checking in .Net 4.5
body: <p>I have an ASP.Net MVC application using Windows Authentication, and I am checking group membership for security on controller actions. </p>
  
  <p>Simple as it sounds, I've found no other Question that can resolve the problem I am experiencing.</p>
  
  <h3>First Attempt: [Authorize]</h3>
  
  <p>The classic method is to simply slap an <code>Authorize</code> data annotation attribute on the controller action and go to town:</p>
  
  <pre><code>[Authorize(Roles = @"domain\groupName1")]
  </code></pre>
  
  <p>No dice. I am prompted for credentials. Usually this means something is wrong with the Windows Authentication configuration but it's setup fine: (1) <code>HttpContext.User</code> is a <code>WindowsPrincipal</code> object, and (2) I confirmed another known group name works.</p>
  
  <h3>Second Attempt: IsInRole()</h3>
  
  <p>The next step taken was to go a more old fashioned route and use <code>IPrincipal.IsInRole()</code>, and again, one returns <code>false</code>, the other <code>true</code>.</p>
  
  <pre><code>var wp = (WindowsPrincipal)User;
  
  // false
  var inGroup1 = wp.IsInRole(@"domain\groupName1");
  // true
  var inGroup2 = wp.IsInRole(@"domain\groupName2");
  </code></pre>
  
  <p>Stumped... so I hit up my systems nerds and we double check everything. User is a group member? Yes. Group name is spelled correctly? Yes. The next step was to snag the SID.</p>
  
  <h3>Third Attempt: Search Identity's Group Collection</h3>
  
  <p>In my controller I check the <code>WindowsIdentity</code> and look through the group collection for the SID of the troublesome group:</p>
  
  <pre><code>var wi = (WindowsIdentity)wp.Identity;
  var group = wi.Groups.SingleOrDefault(g =&gt; g.Value == "group1-sidValue");
  </code></pre>
  
  <p>The <code>group</code> variable is the <code>SecurityIdentifier</code> object. Because it is not null, we can be certain that this current user is a member of the group that both the <code>[Authorize()]</code> or <code>IsInRole()</code> attempts fail to confirm.</p>
  
  <h3>Fourth Attempt: DirectoryServices.AccountManagement</h3>
  
  <p>At this point, I'm going nuts and add reference to the AccountManagement APIs. I search the domain context for the <code>GroupPrincipal</code> by both name and SID:</p>
  
  <pre><code>   var pc = new PrincipalContext(ContextType.Domain, "domain");
     var gp1byName = GroupPrincipal.FindByIdentity(pc, "groupName1")
     var gp1bySid = GroupPrincipal.FindByIdentity(pc, IdentityType.Sid, "group1-sidValue");
  </code></pre>
  
  <p>Both group principal variables are ripe with the same object, and I verified through a watch variable that the principal's <code>Members</code> collection contains a <code>UserPrincipal</code> object with the same SID as the current <code>WindowsPrincipal</code> on <code>HttpContext</code>.</p>
  
  <h3>Question:</h3>
  
  <p>What in the hell have I missed here? Why would both role checking methodologies fail when it is plain and clear through object exploration that the user is a valid member of this given group? </p>
  
  <p>The fact that one group checks fine and the other does not seems the most strange part at this point.</p>