Max Schmeling
Max Schmeling

Reputation: 12509

What is the best way to get the current user's SID?

Prerequisite Detail

  1. Working in .NET 2.0.
  2. The code is in a common library that could be called from ASP.Net, Windows Forms, or a Console application.
  3. Running in a Windows Domain on a corporate network.

The Question

What is the best way to get the current user's SID? I'm not talking about the identity that is executing the application, but the user who is accessing the interface. In background applications and desktop based applications this should be the identity actually executing the application, but in ASP.Net (without impersionation) this should be the HttpContext.Current.User SID.

The Current Method

This is what I've got right now. It just seems... wrong. It's nasty. Is there a better way to do this, or some built in class that does it for you?

public static SecurityIdentifier SID
{
    get
    {
        WindowsIdentity identity = null;

        if (HttpContext.Current == null)
        {
            identity = WindowsIdentity.GetCurrent();
        }
        else
        {
            identity = HttpContext.Current.User.Identity as WindowsIdentity;
        }

        return identity.User;
    }
}

Upvotes: 21

Views: 27976

Answers (4)

Walter Verhoeven
Walter Verhoeven

Reputation: 4421

Returns the current user:

WindowsIdentity.GetCurrent().Owner

Returns the security identifier (SID) in SDDL format you know them as S-1-5-9 :

WindowsIdentity.GetCurrent().Owner.ToString()

Returns the account domain security identifier (SID) If the SID does not represent a Windows account SID, this property returns null:

WindowsIdentity.GetCurrent().Owner.AccountDomainSid

You could use this as:

_pipeSecurity = new PipeSecurity();   
               
var sid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, WindowsIdentity.GetCurrent().Owner);
var audid = new PipeAuditRule(sid, PipeAccessRights.FullControl, AuditFlags.Failure | AuditFlags.Success);
var access = new PipeAccessRule(sid, PipeAccessRights.ReadWrite, AccessControlType.Allow);
            
_pipeSecurity.AddAuditRule(audid);
_pipeSecurity.AddAccessRule(access);

Upvotes: 2

Garric
Garric

Reputation: 724

Without the use of third-party libraries This code will give correct results, if the user changed his user name.

String SID = "";
string currentUserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();

RegistryKey regDir = Registry.LocalMachine;

            using (RegistryKey regKey = regDir.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\SessionData", true))
            {
                if (regKey != null)
                {
                    string[] valueNames = regKey.GetSubKeyNames();
                    for (int i = 0; i < valueNames.Length; i++)
                    {
                        using (RegistryKey key = regKey.OpenSubKey(valueNames[i], true))
                        {
                            string[] names = key.GetValueNames();
                            for (int e = 0; e < names.Length; e++)
                            {
                                if (names[e] == "LoggedOnSAMUser")
                                {
                                    if (key.GetValue(names[e]).ToString() == currentUserName)
                                        SID = key.GetValue("LoggedOnUserSID").ToString();
                                }
                            }
                        }
                    }
                }
            }MessageBox.Show(SID);

Upvotes: 1

Joel Etherton
Joel Etherton

Reputation: 37533

The WindowsIdentity class is the "built in class that does it for you". You've got as simple a solution as you're going to get really, as long as you have a valid WindowsIdentity to work with.

Alternatively, if you have the username of the user in question and you want to get the SID directly from AD, you can build your own library to use the DirectoryServices namespace and retrieve the DirectoryEntry for your user (this is a fairly complicated process as DirectoryServices is tricky). You can even use LDAP to get it if you have a need.

Upvotes: 1

Wyatt Barnett
Wyatt Barnett

Reputation: 15673

I don't think there is a better way at getting at this info--you've got to get at the WindowsPrincipal somehow and .NET's rather clean API abstracts that behind the User object. I'd just leave this nice and wrapped up in a method and call it a day.

Well, ok, there is one thing you should do (unless your web users are always going to be WindowsIdentity), which would be to check for null identity and handle it according to whatever rules you have.

Upvotes: 5

Related Questions