Are there better (easier) ways to get a specific d

2019-04-29 14:16发布

问题:

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.

回答1:

What you're doing looks like the best option to me. Hardcoding strings is definetely not a good idea.



回答2:

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.