ASP.Net Role-based Security Chapter 10 (Freeman and Jones) CS795/895 Role-based security: Basics • Roles are often used in financial or business applications to enforce policy. – For example, an application might impose limits on the size of the transaction being processed depending on whether the user making the request is a member of a specified role. – Clerks might have authorization to process transactions that are less than a specified threshold, supervisors might have a higher limit, and vice-presidents might have a still higher limit (or no limit at all). – Role-based security can also be used when an application requires multiple approvals to complete an action. Such a case might be a purchasing system in which any employee can generate a purchase request, but only a purchasing agent can convert that request into a purchase order that can be sent to a supplier. Role-based security (RBS): .Net • • • • • • In .Net, an identity RBS represents the user on whose behalf code is running. (e.g., Windows local user or other non-local users) A principal encapsulates an identity and the roles to which the identity belongs. – If the identity represents Windows user account, the roles will identify the Windows groups to which the user belongs – Otherwise, it could be based on other authentication mechanisms.. .Net runtime uses principal as the primary basis for role-bases security decisions. While Windows security operates at OS level, .Net RBS operates at the application level. – For example, you can allow users who are members of certain roles to call an important method – You may make different menu items visible depending on the roles of the current user. Each thread (not a process) running .Net code has a principal associated with it. Use of .Net RBS is optional; programmer is responsible for deciding what is protected by .Net RBS by expressing in the code. – .NET Framework applications can make authorization decisions based on the principal's identity or role membership, or both. – A role is a named set of principals that have the same privileges with respect to security (such as a teller or a manager). – A principal can be a member of one or more roles. Therefore, applications can use role membership to determine whether a principal is authorized to perform a requested action. Programming Role-based Security • • • • • • http://etutorials.org/Programming/Programming+.net+security/Part+II+.NET+Security/Chapter+10. +Role-Based+Security/10.2+Programming+Role-Based+Security/ Use System.Security.Principal namespace Iidentity represents identity interface – Properties: – AuthenticationType Gets the type of authentication used. – IsAuthenticated Gets a value that indicates whether the user has been authenticated. – Name Gets the name of the current user. Iprincipal represents principal interface. – Property: Identity Gets the identity of the current principal. – Method: IsInRole Determines whether the current principal belongs to the specified role. Note that Iprincipal interface does not allow you to enumerate all possible roles for an identity. Instead, you can only test if it is has a role. Since not all applications use RBS, .Net runtime does not automatically assign an Iprincipal object to every thread (for efficiency). – When an application intends to use RBS, user must either assign an Iprincipal to a threda manually or configure the runtime to create one automatically the first time it is needed.. Programming Role-based Security (cont.) • • • In general, authorization requirements are as follows: – Users should have proper credentials to access a resource – Certain users need to be denied access to particular resources – Only certain users should be allowed to access particular resources If you intend to use RBS, you must either assign an IPrincipal to a thread manually or configure the runtime to create one automatically Use System.AppDomain.SetThreadPrincipal to automatically generate for each thread, or – Set current thread’s IPrincipal manually using System.Threading.Thread.CurrentPrincipal property. Making Role-based Security Demands • Based solely on identity and roles of the active thread’s principal • Imperative role-based security statements: – Commonly used constructor: PrincipalPermission – Each PrincipalPermission can specify only a single role name. “null” means no matching is needed – Public PrincipalPermission(string name, string role) PrincipalPermission p1 = new PrincipalPermission(“John”, “Manager”); p1.Demand(); PrincipalPermission p2 = new PrincipalPermission(null, “Programmer”); p2.Demand(); PrincipalPermission p3 = new PrincipalPermission(“Kevin”, null); p3.Demand(); PrinciplaPermission Explanationhttp://msdn.microsoft.com/enus/library/system.security.permissions.principalpermission.aspx Making Role-based Security Demands (cont.) • Using Declarative role-based security statements: – PrincipalPermissionAttribute may be applied to classes, methods, properties, or events to force declarative demands – This cannot be applied at the assemble level – Demand, LinkDemand, and InheritanceDemand are the only RBS statements allowed [PrincipalPermission(SecurityAction.Demand, Name=“John”, Role=“Manager”)] [PrincipalPermission(SecurityAction.Demand, Role=“Programmer”)] [PrincipalPermission(SecurityAction.Demand, Name=“Kevin”)] Calculation of Permissions • The default permission is to allow access for all users • Upon calculation of a merged rule set, the system checks the rules until it finds a match: either allow or deny • When a deny is encountered, the system throws a 401 error: Unauthorized access • Example: At the application level, include in web.config: <authorization> <allow users=“localhost\user1, \localhost\user2” /> <deny users = “?”/> </authorization> At a particular page level, we can add this to web.config: <location path=“UnAuthorizedFile.aspx”> <system.web> <authorization><deny roles = “users” /> </authorization> </system.web> </location> Denies access to this page to any windows user. Authorization Checks in Code • We can control access even at a button level using checks in the code • If {user1, user2} are made into a single group called validgroup, then: if (Thread.CurrentPrincipal.IsInRole(“localhost\vali dgroup”)) {Response.Write (“You have access”);} else {Response.Redirect(“AuthorizationError.aspx”);} Demanding Credentials try { PrincipalPermission pp = new PrincipalPermission(“user1”, “validgroup”); pp.Demand(); Response.Write(“PrincipalPermission successful”); } Catch (SecurityException se) {Response.Write (“PrincipalPermission Denied”); } Merging PrincipalPermission objects: try {PrincipalPermission pp1 = new PrincipalPermission(“user1”, “validgroup”); {PrincipalPermission pp2 = new PrincipalPermission(“user2”, “validgroup”); {PrincipalPermission pp3 = (PrincipalPermission)p1.Union (p2); pp3.Demand(); Response.Write(“PrincipalPermission successful”); } Catch (SecurityException se) {Response.Write (“PrincipalPermission Denied”); } PrincipalPermissionAttribute: Another way to Authorize • Place the following code above the method declaration: [PrincipalPermissionAttribute(SecurityAction.Demand, Name=“user1”, Role = “validusers”)] Or [PrincipalPermissionAttribute(SecurityAction.Demand, Role = “validusers”)]