SmartCardPrincipal Implementation

9:08 PM j. montgomery 1 Comments

Page 7 of 9
Previous Page: SmartCardIdentity Implementation | Next Page: Additional Implementation Details

The SmartCardPrincipal Class – Inherits from System.Security.Principal.IPrincipal
From the MSDN documentation, a principal object represents the security context of the user on whose behalf the code is running, including that user's identity (IIdentity) and any roles to which they belong. The Principal is the object that gets interrogated when a PrincipalPermission Demand is made to make sure it is in the proper role to perform the requested operation.
When SmartCardPrincipal.IsInRole() is called, our Smart Card aware object will return whether or not the Principal is in the requested role. On first run, this class will populate a Hashtable with the roles for the current user from the database. The key to lookup the Users’ Roles in the database will be a SHA256 hash of the Users’ public key.
Also notice that both IsElevatedUser and IsInRole() is virtual/Overridable – This allows for custom role resolution if you have a different methodology to resolve roles other then the database role resolution provided.

C#
1 using System;
2 using System.Configuration;
3 using System.Web;
4 using System.Web.Security;
5 using System.Collections;
6 using System.Security.Principal;
7 8 namespace SmartCardAuthentication
9 {
10 public class SmartCardPrincipal : IPrincipal
11 {
12 private SmartCardIdentity _identity;
13 private Hashtable _roles;
14 private bool _isElevatedUser;
15 private bool _rolesLoaded;
16 private bool _isElevatedLoaded;
17 18 public IIdentity Identity
19 {
20 get
21 {
22 return this._identity;
23 }
24 }
25 26 public SmartCardPrincipal(SmartCardIdentity identity)
27 {
28 this._identity = identity; 
29 this._rolesLoaded = false;
30 this._isElevatedLoaded = false;
31 }
32  
33  
34 public virtual bool IsElevatedUser
35 {
36 get {
37 if (!_isElevatedLoaded)
38 {
39 lock (this)
40 {
41 // Evaluate the user against the database
42 // to see if they have an elevated account 43 DataAccess dAccess = new DataAccess();
44 this._isElevatedUser =
45 dAccess.AuthenticateUser(_identity.PublicKeyHash);
46 }
47 this._isElevatedLoaded = true;
48 }
49 return this._isElevatedUser;
50 }
51 }
52 53 public virtual bool IsInRole(string role)
54 {
55 if (!_rolesLoaded)
56 {
57 lock (this)
58 {
59 if (this.IsElevatedUser)
60 {
61 DataAccess dAccess = new DataAccess();
62 _roles = dAccess.GetPrincipalRoles(_identity.PublicKeyHash);
63 _roles.Add("User", "User");
64 }
65 else
66 {
67 _roles = new Hashtable(1);
68 _roles.Add("User", "User");
69 }
70 _rolesLoaded = true;
71 }
72 }
73 return _roles.Contains(role);
74 }
75 }
76 }

VB.Net
1 Imports System.Configuration
2 Imports System.Web
3 Imports System.Web.Security
4 Imports System.Collections
5 Imports System.Security.Principal
6 7 Public Class SmartCardPrincipal
8 Implements IPrincipal
9 10 Private _identity As SmartCardIdentity
11 Private _roles As Hashtable
12 Private _rolesLoaded As Boolean 13 Private _isElevatedLoaded As Boolean 14 15 Public ReadOnly Property Identity() As IIdentity _
16 Implements IPrincipal.Identity
17 Get 18 Return Me._identity
19 End Get 20 End Property 21 22 Public Sub New( _
23 ByVal identity As SmartCardIdentity _
24 )
25 Me._identity = identity
26 Me._rolesLoaded = False 27 Me._isElevatedLoaded = False 28 End Sub 29 30 Public Overridable ReadOnly Property IsElevatedUser() As Boolean 31 Get 32 If (Not _isElevatedLoaded) Then 33 SyncLock (Me)
34 ' Authenticate the user against the database 35 Dim dAccess As New DataAccess
36 _isElevatedUser = dAccess.AuthenticateUser(Me._identity.PublicKeyHash)
37 38 _isElevatedLoaded = True 39 End SyncLock 40 End If 41 42 Return _isElevatedUser43 End Get 44 End Property 45 46 Public Overridable Function IsInRole(ByVal role As String) As Boolean _
47 Implements IPrincipal.IsInRole
48 If (Not _rolesLoaded) Then 49 SyncLock (Me) 50 If _identity.IsElevatedUser Then 51 ' If the user is elevated, retrieve roles from the database 52 Dim dAccess As New DataAccess
53 _roles = dAccess.GetPrincipalRoles(_identity.PublicKeyHash)
54 ' Finally add the Default Role 55 _roles.Add("User", "User")
56 Else 57 _roles = New Hashtable(1)
58 ' Regular user 59 _roles.Add("User", "User")
60 End If 61 _rolesLoaded = True 62 End SyncLock 63 End If 64 Return _roles.Contains(role)
65 End Function 66 End Class

Previous Page: SmartCardIdentity Implementation | Next Page: Additional Implementation Details

Page 7 of 9


1 comment:

  1. Why do you use a cryptographic hash as the key for the users' roles? Would a hash providing statistical randomness suffice, or is something gained using SHA that I am not seeing?

    Great article btw.

    Thank you!
    Mike

    ReplyDelete