1

I'm trying to allow all users in the Administrators group access through WCF.

internal sealed class AuthorizationManager : ServiceAuthorizationManager
{
    public override bool CheckAccess(OperationContext operationContext)
    {
        base.CheckAccess(operationContext);

        ReadOnlyCollection<ClaimSet> claimSets = operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets;
        ClaimSet claimSet = claimSets[0];

        foreach (var claim in claimSet.FindClaims(ClaimTypes.Sid, Rights.Identity))
        {
            SecurityIdentifier sid = (SecurityIdentifier)claim.Resource;
            NTAccount ntAccount = (NTAccount)sid.Translate(typeof(NTAccount));

            //This line throws an error.  How can i convert a SecurityIdentifier to a WindowsIdentity?
            WindowsIdentity user = new WindowsIdentity(ntAccount.Value);

            WindowsPrincipal principal = new WindowsPrincipal(user);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }
    }
}
ChrisF
  • 134,786
  • 31
  • 255
  • 325

3 Answers3

3

You have to authenticate. You have an identifier that identifies an account, it's isomorphic with an account name i.e. SID: S-1-5-domain-500 <=> DOMAIN\Administrator. A WindowsIdentity is a user that has been authenticated.

That said, I think the user you're trying to get has already been authenticated and is providing a claim of his/her account identity (SID).

JP Alioto
  • 44,864
  • 6
  • 88
  • 112
1

JP is correct. The claims provided include the SID of all user groups the user is a member of. Here is our solution.

internal sealed class AuthorizationManager : ServiceAuthorizationManager
{
    public override bool CheckAccess(OperationContext operationContext)
    {
        base.CheckAccess(operationContext);

        ReadOnlyCollection<ClaimSet> claimSets = operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets;
        ClaimSet claimSet = claimSets[0];

            //is this a member of the local admins group
            SecurityIdentifier adminsSid = new SecurityIdentifier("S-1-5-32-544");
            foreach (var claim in claimSet.FindClaims(ClaimTypes.Sid, Rights.PossessProperty))
            {
                if (adminsSid.Equals(claim.Resource))
                {
                    return true;
                }
            }
    }
}
0

We are using a code we found here to create a WindowsIdentity based on the login name. With a minor modification you can create a similar method that returns a WindowsIdentity based on the SID:

public static WindowsIdentity GetWindowsIdentityBySid(string sid)
{
    using (var user =
        UserPrincipal.FindByIdentity(
        UserPrincipal.Current.Context,
        IdentityType.Sid,
        sid
        ))
    {
        return user == null
            ? null
            : new WindowsIdentity(user.UserPrincipalName);
    }
}
pholpar
  • 1,725
  • 2
  • 14
  • 23