| File: System\Security\Principal\WindowsPrincipal.cs | Web Access |
| Project: src\runtime\src\libraries\System.Security.Principal.Windows\src\System.Security.Principal.Windows.csproj (System.Security.Principal.Windows) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.ComponentModel; using System.Runtime.InteropServices; using System.Security.Claims; using Microsoft.Win32.SafeHandles; namespace System.Security.Principal { public enum WindowsBuiltInRole { Administrator = 0x220, User = 0x221, Guest = 0x222, PowerUser = 0x223, AccountOperator = 0x224, SystemOperator = 0x225, PrintOperator = 0x226, BackupOperator = 0x227, Replicator = 0x228 } public class WindowsPrincipal : ClaimsPrincipal { private readonly WindowsIdentity _identity; // // Constructors. // public WindowsPrincipal(WindowsIdentity ntIdentity) : base(ntIdentity) { ArgumentNullException.ThrowIfNull(ntIdentity); _identity = ntIdentity; } // // Properties. // public override IIdentity Identity => _identity; // // Public methods. // public override bool IsInRole(string role) { if (string.IsNullOrEmpty(role)) return false; NTAccount ntAccount = new NTAccount(role); IdentityReferenceCollection source = new IdentityReferenceCollection(1); source.Add(ntAccount); IdentityReferenceCollection target = NTAccount.Translate(source, typeof(SecurityIdentifier), false); if (target[0] is SecurityIdentifier sid) { if (IsInRole(sid)) { return true; } } // possible that identity has other role claims that match return base.IsInRole(role); } // <summary // Returns all of the claims from all of the identities that are windows user claims // found in the NT token. // </summary> public virtual IEnumerable<Claim> UserClaims { get { foreach (ClaimsIdentity identity in Identities) { if (identity is WindowsIdentity wi) { foreach (Claim claim in wi.UserClaims) { yield return claim; } } } } } // <summary // Returns all of the claims from all of the identities that are windows device claims // found in the NT token. // </summary> public virtual IEnumerable<Claim> DeviceClaims { get { foreach (ClaimsIdentity identity in Identities) { if (identity is WindowsIdentity wi) { foreach (Claim claim in wi.DeviceClaims) { yield return claim; } } } } } public virtual bool IsInRole(WindowsBuiltInRole role) { if (role < WindowsBuiltInRole.Administrator || role > WindowsBuiltInRole.Replicator) throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)role), nameof(role)); return IsInRole((int)role); } public virtual bool IsInRole(int rid) { return IsInRole( new SecurityIdentifier( IdentifierAuthority.NTAuthority, stackalloc int[] { Interop.SecurityIdentifier.SECURITY_BUILTIN_DOMAIN_RID, rid } ) ); } // This method (with a SID parameter) is more general than the 2 overloads that accept a WindowsBuiltInRole or // a rid (as an int). It is also better from a performance standpoint than the overload that accepts a string. // The aforementioned overloads remain in this class since we do not want to introduce a // breaking change. However, this method should be used in all new applications. public virtual bool IsInRole(SecurityIdentifier sid) { ArgumentNullException.ThrowIfNull(sid); // special case the anonymous identity. if (_identity.AccessToken.IsInvalid) return false; // CheckTokenMembership expects an impersonation token using SafeAccessTokenHandle invalidHandle = SafeAccessTokenHandle.InvalidHandle; SafeAccessTokenHandle token = invalidHandle; try { if (_identity.ImpersonationLevel == TokenImpersonationLevel.None) { if (!Interop.Advapi32.DuplicateTokenEx(_identity.AccessToken, (uint)TokenAccessLevels.Query, IntPtr.Zero, (uint)TokenImpersonationLevel.Identification, (uint)TokenType.TokenImpersonation, ref token)) { throw new SecurityException(Marshal.GetLastPInvokeErrorMessage()); } } bool isMember = false; // CheckTokenMembership will check if the SID is both present and enabled in the access token. if (!Interop.Advapi32.CheckTokenMembership((_identity.ImpersonationLevel != TokenImpersonationLevel.None ? _identity.AccessToken : token), sid.BinaryForm, ref isMember)) { throw new SecurityException(Marshal.GetLastPInvokeErrorMessage()); } return isMember; } finally { token.Dispose(); } } // This is called by AppDomain.GetThreadPrincipal() via reflection. private static WindowsPrincipal GetDefaultInstance() => new WindowsPrincipal(WindowsIdentity.GetCurrent()); } }