다음을 통해 공유


Checking the SIDs in the WindowsClaimSet

In continuation to my post of SAM vs PP, we concluded that to avoid fractured policy checking we can still check if the user belongs to a particular group by checking the occurence of an SID in the WindowsClaimSet that he submits to the service.

One of the problems that I faced to view the SID of an object was in the SDDL format for direct comparison. The Sid is basically represented as a SDDL string. If someone can point me to some proper tool besides these, it would be greatly helpful. these are the one's i used.
You can use GetSID.exe that is a part of the the support tools that ship with Windows 2003 to find the SID as SDDL string. Or there is another tool PSID from SysInternals that helps you get this string pretty easily and both are command line tools.

Once you get this value you can compare the Claim Set for the occurence of this SID to figure out if the user provided a claim.
 

using System;
using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

using System.IdentityModel.Policy;

using System.Collections.ObjectModel;

using KBE.Service.Diagnostics;

using System.Security.Permissions;

using System.Security.Principal;

using System.IdentityModel.Claims;

using System.Configuration;

public class CustomServiceAuthorizationManager : ServiceAuthorizationManager

{

protected override bool CheckAccessCore(OperationContext operationContext)

{

System.Diagnostics.Debug.WriteLine("CheckAccess -- Started" + Utility.GetUserDetails());
try

        {

foreach (ClaimSet cs in OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets)

            {
if (cs is WindowsClaimSet)
{
foreach (Claim c in cs)
{
if (c.ClaimType == ClaimTypes.Sid)
{

SecurityIdentifier sid = c.Resource as SecurityIdentifier;

                            if (sid != null)
{
// Check if the SID is a claim for the group
if (sid.Value == ConfigurationManager.AppSettings["AuthorizationPermissionRole"])
return true;

}
}
}
}
}
return false;

        }
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("\tException : " + ex.Message);
throw;
}
finally
{
System.Diagnostics.Debug.WriteLine("CheckAccess -- Ended");
}
}

    protected override ReadOnlyCollection<IAuthorizationPolicy> GetAuthorizationPolicies(OperationContext operationContext)
    {
        return base.GetAuthorizationPolicies(operationContext);
    }
}

Configuraiton Entry

<appSettings>

  <add key="AuthorizationPermissionRole" value="Some SID String"/>

</appSettings>

Comments

  • Anonymous
    May 15, 2008
    Not sure exactly what you're having trouble with as far as the SID / SDDL format goes.  If you're trying to figure out if someone's in a group or not, you can use System.DirectoryServices.AccountManagement to do that.  You can get group membership via  GroupPrincipal.  You can determine various properties of a Principal, including finding the Principal by SID, as shown below: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IdentityModel.Claims; using System.Security.Principal; using System.DirectoryServices.AccountManagement; namespace IdentityModelTestForms {    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();            PrincipalContext pc = new PrincipalContext(ContextType.Domain, "domain", "dc=domain,dc=your,dc=org", ContextOptions.Negotiate, "domain\username", "userpassword");            richTextBox1.Text = "";            WindowsClaimSet windows = new WindowsClaimSet(WindowsIdentity.GetCurrent());            List<string[]> lst = new List<string[]>();            foreach (Claim c in windows)            {                SecurityIdentifier sid = c.Resource as SecurityIdentifier;                if (sid != null)                {                    Principal p = Principal.FindByIdentity(pc, IdentityType.Sid, sid.Value);                    string[] sa = { sid.Value, c.Right, c.ClaimType };                    lst.Add(sa);                    if (p != null)                    {                        richTextBox1.Text += p.SamAccountName + " " + sid.Value + " " + c.Right + " " + c.ClaimType + "n";                    }                    else                    {                        richTextBox1.Text += sid.Value + " " + c.Right + " " + c.ClaimType + "n";                    }                }            }            pc.Dispose();        }    } }