SmartCardPrincipal Implementation
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 _isElevatedUser
43 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

Secure Coding in .NET: Developing Defensible Applications
1 comments:
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
Post a Comment