In our application, the user is in complete control over what roles are defined, and what specific functions are allowed for each role (e.g. the "permissions").
In the Project Tracker example, the roles and authorization rules are static (at least this was my interpretation), so how would you handle our scenario in CSLA?
One possibility is to call the permissions themselves "roles", so instead of a role being "Administrator", etc. the roles would be "Can Edit Project", "Can Delete Project", etc. In our application there are over 300 such permissions, so I'm not sure if this is advisable as it might add too much weight to the objects.
This has been discussed many times.
Do a search for HasPermissions and see what you come up with.
Joe
I looked at both suggestions -- it appears from this thread that Rocky says you can interpret "IsInRole" to be the equivalent of "HasPermission" except in unusual cases (unless I am missing something).
http://forums.lhotka.net/forums/thread/12198.aspx
I have our "HasPermission" functionality completely migrated over from the legacy application we are converting. My main question was how to integrate it into the CSLA framework. The authorization rules would seem to not be useful unless we interpret the roles as permissions.
Maybe some future version of CSLA could support a flexible authorization rule implementation comparable to the validation rule mechanism, where you can implement almost anything you want rather than just provide a list of strings to be tested elsewhere in the framework.
I'm new to CSLA as well so I feel your pain about trying to
take that leap from the sample project. While I've read both the VB.NET
Business Objects and Expert VB 2005
Business Objects books, I learn best from examples.
The Project Tracker is a good start but far too simplistic
for what we are trying to do so I've been scouring this forum and trying
different things out. I wish there were
more sample applications to learn from but I supposed businesses using CSLA
don't want to post their work products for the world to see.
The User table contains a list of each user (e.g., Name,
Password, Password Expiration Date, List of most recently used passwords). The Roles table contains a row for each Role
the User belongs to. Finally, the Role
Permissions table contains a list of the permission(s) associated with each Role
(i.e., Role, Function and Permission Level).
When the user logs on the application, his/her password is
validated. Assuming a valid password,
the Roles and Role Permissions tables are joined to find all the permissions for
the particular user.
Using the Project Tracker Identity as a template, I created
a new Identity class. Here’s the
important stuff I added:
<Serializable()> _
Public Class YAIdentity
Inherits
ReadOnlyBase(Of YAIdentity)
Implements IIdentity
Private
_UserSctyList As New
List(Of UserScty) ‘Holds list of permissions
''' <summary>
''' Internal
class to hold custom security info used during authorization checks
''' </summary>
''' <remarks></remarks>
Private Class UserScty
Public
FuncNme As String ‘Function Name
Public
SctyAcesCde As Integer ‘Security Access Code
Public
Sub New(ByVal pFuncNme As String, ByVal pSctyAcesCde
As Integer)
FuncNme = pFuncNme
SctyAcesCde = pSctyAcesCde
End Sub
End Class
''' <summary>
''' Indicates
whether user is authorized for specified function and accesses
''' </summary>
Friend Function IsAuthorized(ByVal
FuncNme As String,
ByVal SctyAcesCde As
SctyAcesCdes) As Boolean
For Each item As UserScty
In _UserSctyList
If
item.FuncNme = FuncNme AndAlso SctyAcesCde = item.SctyAcesCde Then
Return
True
End
If
Next
Return
False
End Function
In the DataPortal_Fetch method, I populate _UserSctyList based
on the contents of the second result set (like Rocky does in the Project
Tracker example).
Using dr As New
SafeDataReader(cm.ExecuteReader)
While
dr.Read()
With
dr
_UserSctyList.Add(New UserScty(.GetString("FUNC_NME"),
.GetInt32("SCTY_ACES_CDE")))
End With
End While
End Using
I created a new Principal class again using the PT Principal as a guide.
Namespace Security
<Serializable()> _
Public Class YAPrincipal
Inherits Csla.Security.BusinessPrincipalBase
Public Shared Function
Login( _
ByVal
UserNme As String,
ByVal UserPswdTxt As
String) As Boolean
Dim
identity As YAIdentity =
YAIdentity.GetIdentity(UserNme, UserPswdTxt)
If
identity.IsAuthenticated Then
Dim
principal As New
YAPrincipal(identity)
Csla.ApplicationContext.User =
principal
End If
Return
identity.IsAuthenticated
End Function
''' <summary>
''' Does the
user have permission?
''' </summary>
Public Shared Function
IsAuthorized(ByVal FuncNme As String, ByVal SctyAcesCde As
SctyAcesCdes) As Boolean
Dim
identity As YAIdentity = DirectCast(Csla.ApplicationContext.User.Identity,
YAIdentity)
Return
identity.IsAuthorized(FuncNme, SctyAcesCde)
End Function
<Flags()> _
Public Enum
SctyAcesCdes As Integer
Read = 1
Edit = 2
Add = 4
Delete = 8
Execute = 16
End Enum
And finally in my business objects I check for authorization
as shown below:
''' <summary>
''' Is the user
allowed to Add new items?
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function
CanAddObject As Boolean
Return
Security.YAPrincipal.IsAuthorized(“Project”, Security.SctyAcesCdes.Add)
End Function
''' <summary>
''' Is the user
allowed to Read existing items?
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function
CanReadObject As Boolean
Return
Security.YAPrincipal.IsAuthorized((“Project”, Security.SctyAcesCdes.Read)
End Function
''' <summary>
''' Is the user
allowed to Delete existing items?
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function
CanDeleteObject As Boolean
Return
Security.YAPrincipal.IsAuthorized((“Project”, Security.SctyAcesCdes.Delete)
End Function
''' <summary>
''' Is the user
allowed to Edit existing items?
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function
CanEditObject As Boolean
Return
Security.YAPrincipal.IsAuthorized((“Project”, Security.SctyAcesCdes.Edit)
End Function
Obviously, “Project” will vary depending upon the Business
Object but hopefully you get the idea.
If you look at the wish list (the items in green), the next version of CSLA has already implemented the Delegate for IsInRole which means you can use a different function (such as HasPermission) in the Authorization framework.
If you look at the source you may be able to port it backwards if you really need it now.
Joe
Copyright (c) Marimer LLC