'What is the best way to get the current user's SID?
Prerequisite Detail
- Working in .NET 2.0.
- The code is in a common library that could be called from ASP.Net, Windows Forms, or a Console application.
- 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;
}
}
Solution 1:[1]
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);
Solution 2:[2]
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.
Solution 3:[3]
//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);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nissa |
| Solution 2 | Joel Etherton |
| Solution 3 | Walter Verhoeven |
