|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionThe buzz word ‘Security’ strikes me all the time when I think of designing an application. According to me, paramount importance should be given to security of any application, as hackers are always on the move. Security is something an application should possess and not be a feature. Microsoft.NET as a technology, has given various models/patterns, towards implementing security. The patterns can be customized to suit our requirement and hence is extensible in nature. Microsoft.NET framework provides certain objects in the name ‘Principal’ and ‘Identity’ objects which would be our primary area of thought. This article mainly focuses on security model by adopting ‘Principal’ and ‘Identity’ objects and proposes a security model for a .NET application. What are Principal and Identity objects?Before we proceed any further, it is important for us understand that the very intent of Principal and Identity objects is to authenticate and authorize the end user. In simple terms, authentication is the process by which the identity of the user is verified and authorization is the process by which access to an application/feature is granted based on the identity. Identity:This object stores information about the user. This object encapsulates the name of the user being authenticated. We can relate this object to a data store which stores information (User Name) about a user. Identity objects are of two types.
We shall be discussing more in detail about this at a later stage in this article. Principal:This object represents the security context for the running process or the
Principal objects are of two types:
Implementing role based security with Principal objectsThe above theory can be well understood by considering a few of the real time scenarios. Scenario A: Windows authentication (Identity) with roles available from databaseAssumptionIn this scenario, if roles are found for a user in the database, then the user is a valid user. If a role does not exist for a user in the database, then the user is anonymous and hence should not get access to any feature in the system. Also, there would be an entry for a user in the database only if role(s) are allocated. In most cases, for an intranet/Windows based application, Windows
authentication is preferred with roles being application specific and existing
in a data store. Under such circumstances, we would be creating a Meaning, we would retrieve the Windows identity, get the user name from the
identity object, and query the data store for roles of the user. Once we get the
user roles we can construct a Now the obvious question would be, who would access the context and how does authorization happen? Let’s consider a hypothetical case wherein we need to grant access to a feature in the application based on the user role. AuthenticationThis would be a seamless login from the user’s point of view. The user’s identity can be retrieved with the help of the following code: Windows application
Imports System.Security.Principal
Module SecurityModule
Sub Main()
Dim winIdent As WindowsIdentity = WindowsIdentity.GetCurrent()
Console.WriteLine(winIdent.Name())
End Sub
End Module
Web applicationBy doing the following the identity of the Windows user is obtained
<!--Web.Config File Data-->
<authentication mode="Windows"/>
<authorization>
<deny users="?" /> <!--Deny anonymous users -->
<allow users="*" /> <!--Allow all users -->
<authorization/>
Global.asax code: The below event is triggered for every request made on the web application. Sub WindowsAuthentication_OnAuthenticate(ByVal Source As Object, _
ByVal e As WindowsAuthenticationEventArgs)
Dim userIdentity As String
userIdentity = e.Identity.Name()
End Sub
AuthorizationTo authorize the users, we got to have roles associated with the identities and hence build the principal object. For the identity obtained from the above global.asax event, query the database and retrieve the roles. Authorization check would be performed in each page of the web application to grant or deny access to a particular feature/page in the application. The below code explains the complete cycle involved in authorizing a user in accessing an application Windows applicationDuring application start-up (wherever applicable), for the identity, get the roles from the database accordingly. With the roles and the identity, the principal object needs to be created which would be accessed throughout the application. The below code explains the entire process. Module SecurityModule
Public genPrincipal As GenericPrincipal
Sub Main()
Dim ident As WindowsIdentity = WindowsIdentity.GetCurrent()
Dim roles() As String
roles = <retrieve from database>
genPrincipal = New GenericPrincipal(ident, roles)
End Sub
End Module
The above generic principal object would be accessed in each of the Windows forms in deciding whether to grant or deny access to the requested feature, as shown below: Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load If genPrincipal.IsInRole("Managers") = False Then MessageBox.Show("You do not have access to this form") End If End Sub Web applicationFor a web application, before we proceed with authentication check, we got to build the principal object. And, for the web page to access this principal object, the same has to be persisted in the HTTP context. The code below explains this process: In Sub WindowsAuthentication_OnAuthenticate(ByVal Source As Object, _
ByVal e As WindowsAuthenticationEventArgs)
'Note that since IIS has already performed
'authentication, the provided identity is used.
Dim userIdentity As String
Dim userRoles As String
Dim formsAuthTicket As FormsAuthenticationTicket
Dim httpcook As HttpCookie
Dim encryptedTicket As String
userIdentity = e.Identity.Name()
useRoles =<Retrieve from Database>
formsAuthTicket = New FormsAuthenticationTicket(1, _
e.Identity.Name(), _
DateTime.Now,DateTime.Now.AddMinutes(60), _
False, userRoles)
encryptedTicket = FormsAuthentication.Encrypt(formsAuthTicket)
httpcook = New HttpCookie("authCookie", encryptedTicket)
Response.Cookies.Add(httpcook)
End SubSub Application_AuthenticateRequest(ByVal sender As Object, _
ByVal e As EventArgs)
' Fires upon attempting to authenticate the user
Dim formsAuthTicket As FormsAuthenticationTicket
Dim httpcook As HttpCookie
Dim genIdentity As GenericIdentity
Dim roles() As String
Dim genPrincipal As GenericPrincipal
httpcook = Context.Request.Cookies("authCookie ")
formsAuthTicket = FormsAuthentication.Decrypt(httpcook.Value)
genIdentity = New GenericIdentity(formsAuthTicket.Name())
roles = formsAuthTicket.UserData.Split("|") 'if more than one role
genPrincipal = New GenericPrincipal(genIdentity, roles)
'The principal object thus created would be accessed
'in the ‘application pages before allowing access
'to the individual functionality
HttpContext.Current.User = genPrincipal
End Sub
Now after the Principal object has been set, let’s move over to the web page
to authorize the user. In the Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim genPrincipal As IPrincipal
' Access the principal object from HTTPContext
genPrincipal = HttpContext.Current.User
If genPrincipal.IsInRole("Managers") = False then
Response.Write("You do not have access to this Page.")
' Now the controls on the form can be hidden
' or the user can be redirected
' to a different page
' < Code to implement the above goes here >
End if
End Sub
The above would not give access to PageA.aspx, to any user who does not belong to ‘Managers’ role/group. In all, this security model best suits for applications which need to implement role based security with roles as defined by the application and authentication performed by Windows. Scenario B: Custom authentication (Identity) with roles available from databaseThis scenario best suits applications which have users as well as roles
defined in the application. Such applications will have logon page/form which
accepts username and password and performs authentication. The same code as
explained in scenario A except for authentication mechanism can be adopted in
this scenario as well. The authentication would follow with user ID and password
being validated against a data store and continues to build the generic
principal object with the help of Scenario C: Windows authentication (Identity) with Windows group membership as rolesThis scenario best suits applications which depend on Windows for identity
and roles. Identity would be the Windows username and the role would be the
group membership of the Windows user. The concept of role based security remains
the same and is similar to the code as mentioned in Scenario A. Instead of
creating Scenario analysisIn the above scenarios, all we are doing is building the principal objects which consists of identity and roles. The pages/forms need not worry about building the Principal objects. They just need to perform ‘IsInRole’ checks depending on the authorization rules as set by the application. This demonstrates the clear segregation between authentication and authorization when Identity and Principal objects are adopted for implementing security. Also, throughout the life of the application, we are dealing with objects encapsulating identity, roles and are persisted across. ConclusionThe scenarios just demonstrate the usage of Principal and Identity objects. They do not imply any rules on its usage. The scenarios were chosen as a means to understand the concepts better. In all, the Principal and Identity objects provide a means to implement security for any application in .NET. Using the codeThe code snippets mentioned throughout this article is part of the source code available for download with this article. On downloading the source code (Zip File), extract the same to web folder (wwwroot) to successfully open the solution. In the IIS Settings for the web application, make sure anonymous access is unchecked in Directory Security tab.
|
||||||||||||||||||||||