static void

.Net Security

Validate Input

Role Based Security

For legacy reasons, much of this still exists, but you should use claims instead

IIdentity contains the user name; IPrincipal contains identity and roles (IsInRole). Normally it's WindowsIdentity, but can be GenericIdentity or your custom class.

//Set the policy to WindowsPrincipal (because the default is UnauthenticatedPrincipal).
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
 
if (useMethod == 1) //Either get the user -> IPrincipal
{
    WindowsIdentity myIdentity = WindowsIdentity.GetCurrent(); //use GetCurrent static method
    WindowsPrincipal myPrincipal = new WindowsPrincipal(myIdentity); //then get the principal from the Id
    Console.WriteLine(myIdentity.Name + " " + myPrincipal.IsInRole(@"domain\Users"));
}
else //or get the Principal from the thread directly (containing the IIdentity).
{
    // Gets a reference to the current WindowsPrincipal (cast from IPrincipal)
    WindowsPrincipal myPrincipal2 = (WindowsPrincipal)System.Threading.Thread.CurrentPrincipal;
    // Gets the WindowsIdentity of the current principal
    WindowsIdentity myIdentity2 = (WindowsIdentity)myPrincipal2.Identity;
    Console.WriteLine(myIdentity2.Name + " " + myPrincipal2.IsInRole(WindowsBuiltInRole.Administrator));
}

Using strings for role names ("BUILTIN\\Administrators") is dangerous as different Windows locales have different names. There's a short WindowsBuiltInRole enum, and the WellKnownSidType is extensive.

var wi = WindowsIdentity.GetCurrent();
var wp = new WindowsPrincipal(wi);
//NB: UAC makes this always false!
var isAdmin = wp.IsInRole(WindowsBuiltInRole.Administrator);
var si = new SecurityIdentifier(
    WellKnownSidType.BuiltinAdministratorsSid,
    wi.User.AccountDomainSid); //with the domain
var isAdminViaSi = wp.IsInRole(si);
//show string names of all groups, instead of SIDs
foreach (var g in wi.Groups.Translate(typeof(NTAccount)))
{
    Console.WriteLine(g); //group names
}

CAS is obsolete - not available in .net Core

Code Access Security

CAS is based on the evidence- from the assembly (strong name, publisher signature) and from the host (app path, url, site). The assembly is then assigned to a code group (machine level being like IE security zones) which have a permission set.

Enterprise/Machine/User Level

The permissions (FileIO, EventLog, Registry etc) are organised into default permission sets (Internet, Nothing - can't run-, Everything...). Assemblies are put into Code Groups (MyComputer, Trusted, Internet...) which have a permission set.

.Net config msc to view the declarative permissions an assembly demands, and create a new code group/permission set to elevate the permissions (command line caspol to change).

Machine/user level admins can change the enterprise level permissions- unless you use LevelFinal attribute. Cf Exclusive attribute (=only use this permission, ignore everything else- dangerous!).

Eg KB to caspol a network share so it's full trust (eg aspx virtual directory)

NB: MyComputerZone= FullTrust == no CAS (!= Everything == CAS but can do everything)

Assembly Level

NB: SecurityAction.RequestOptional runs even when fails... add combos of different requests if rqd (eg RequestOptimal for a directory, Refuse a subdirectory)

[assembly: FileIOPermission(SecurityAction.RequestOptional, Read=@"C:\temp\")]

Using both RequestOptimal and RequestRefuse - the Optimal refuses everything else anyway, so refuse should only refuse more specific actions in the set allowed by optimal.

To enable debugging add [assembly: UIPermission(SecurityAction.RequestMinimum, Unrestricted= true)] (needed by debugger!!)

Method-Level CAS

NB: The SecurityActions for assemblies are RequestMinimum/Optional/Refuse. Classes and methods have Demand/Assert/Deny etc.

NB: .Assert overrides other permissions in the stack; .Demand requires all callers in the stack have the permission.
Untrusted- Trusted (Assert) - Trusted (Demand) = works
Untrusted- Trusted (Demand) = fails

Partial-trust can't call strong names unless explicitly allows with APTCA

[assembly:AllowPartiallyTrustedCallers]

You can Assert only once in a method- so for multiple permissions, create new PermissionSet()

AppDomain security

Creating a custom domain and execute an assembly in it with custom evidence. (You can increase permissions, so must have SecurityPermission.ControlEvidence). See Create domain example.

//using System.Security;

//using System.Security.Policy;

//create object array

object[] hostEvidence = { new Zone(SecurityZone.Internet) };

//put the array into a new evidence object

Evidence internetEvidence = new Evidence(hostEvidence, null);

//or - Evidence fakeEvidence = new Evidence(); //create empty evidence

// fakeEvidence.AddHost(new Site("www.microsoft.com")); //assign each evidence

//you can put the evidence into the Domain ctor or assembly

AppDomain myDomain = AppDomain.CreateDomain("MyDomain");

myDomain.ExecuteAssembly(@"C:\SpecialAssembly.exe", internetEvidence);

You can create a custom security policy too.

You can also create your own evidence (and MembershipCondition) and permissions.

COM+ Roles (Serviced components)

ACLs

You can control Windows file system access control lists (from .net 2+)