I've been assigned to modify a WinForms application to basically check that the logged on user belongs to a specific domain.
This is what I've come up with so far:
byte[] domainSid;
var directoryContext =
new DirectoryContext(DirectoryContextType.Domain, "domain.se");
using (var domain = Domain.GetDomain(directoryContext))
using (var directoryEntry = domain.GetDirectoryEntry())
domainSid = (byte[])directoryEntry.Properties["objectSid"].Value;
var sid = new SecurityIdentifier(domainSid, 0);
bool validUser = UserPrincipal.Current.Sid.IsEqualDomainSid(sid);
Is there a better/easier way to do this?
To me it seems like the domainSid would be accessible in some way using the PrincipalContext or some other class in System.Security.Principal.
I've considered using a hardcoded SID-string, but I don't know how "correct" that would be.
What you're doing looks like the best option to me. Hardcoding strings is definetely not a good idea.
Each domain has a build in account domainName\administrator, so you can create an account with this name, translate it to the SecurityIdentifier and read the AccountDomainSid property.
An example of this way is:
public static class SecurityEx
{
public static SecurityIdentifier DomainSId
{
get
{
var administratorAcount = new NTAccount(GetDomainName(), "administrator");
var administratorSId = (SecurityIdentifier) administratorAcount.Translate(typeof (SecurityIdentifier));
return administratorSId.AccountDomainSid;
}
}
internal static string GetDomainName()
{
//could be other way to get the domain name through Environment.UserDomainName etc...
return IPGlobalProperties.GetIPGlobalProperties().DomainName;
}
}
Also you can find other solutions to achieve the same result via WMI or Lsa. This one seems the most elegant way for me.