How do you wire event to function
I'm new to the .net framework and I have a question.
Here's what I'm trying to do:
I am developing a role base security software(Winform) and want to declaratively test whether the current user has the rights to a specific function.
Example:
Once a user tries the following:
Form1.Show()
Before the form is shown an event is raised and the user's credentials are tested.
I can do this programmatically:
if (User.isInRole("Administrator"))
Form1.Show();
else
MessageBox.Show("Insufficient Priviledges");
But I want to know if I could do something like this:
<Declarativefunction(role:="Adminsitrator")> _
public void Form1_Load(sender,e)
{
.....Code.....
}
PriviledgeEventHandler(sender,e)
{
MsgBox("Insufficient Priviledges");
}
I want this so that I can have a catch all subroutine to alert the user, instead of writing duplicate code all over the place. Any help would be appreciated, or if this is not good coding practice, please enlighten me.
Note: I have tried the PrincipalPermissionAttribute(SecurityAction.Demand(),role:="Administrator") but it throws an exception and you have to add try catch code to grab the exception otherwise the application will terminate if unhandled.
im not sure I quite follow. Are you asking how to make the code more effecient so that you can call this one method from any where within your code? if so, simply create a function which may return a boolean value indicating success or failure, then call the code from any where within your class:
private function DoCheckCredentials() as Boolean
if (User.isInRole("Administrator")) = true then
return true
else
return false
end function
and call the method like so:
If Me.DoCheckCredentials() = true then
MessageBox.Show("Success")
else
MessageBox.Show("Failure")
end if
I hope this makes sense?
With your method level attributes Why not handle unhandled application events.
Visual Studio
How to: Handle Application Events (Visual Basic)
http://msdn2.microsoft.com/en-us/library/f2bys999.aspx
Something like –
Private Sub MyApplication_UnhandledException(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException
Try
Throw e.Exception
Catch ex As System.Security.SecurityException
MessageBox.Show("Security Exception")
Catch
' all unhandled
End Try
End Sub
I have placed the handler in, but the handler is not being called. I must have the handler in the wrong place, where should I put it? I tried in the app.designer.vb for my winform but no luck. In the main form of my program it doesn't seem to catch either. Any help would be appreciated.
A sample project maybe?
This looks like an ASP question which usually go to www.asp.net
its not an ASP.NET question. IF it were, it would have been stated earlier. You can see from the posters code it has Form1_Load event, not Page_Load event
Two points.
As per the doc referenced above.
"The Visual Basic compiler prevents applications that are built for debugging from raising this event, to allow a debugger to handle the unhandled exceptions. This means that if you are testing your application by running it under the Visual Studio Integrated Development Environment debugger, your UnhandledException event handler will not be called. For more information on building applications for debugging, see /debug (Visual Basic)."
Problem
The unhandled exception handler doesn't resolve your problem as it doesn't allow for continued code execution past the exception. Looks like your back to the Try Catch.
Or some other class that uses reflection to check method attributes against the current users security permissions etc. Then with the security you would have to call each method like; at least it is only a single line. The security object would raise the alerts if required.
If
CheckSecurity(DoMethod, CurrentUser) Then DoMethod()I'm not up on this type of reflection, but will try for a solution.
Depending on your requirements the following may be sufficient. It provides a helper class that checks security on two method types. the more method signatures that you wish to secure the more delegates you would need to create.
Imports System.Security.Permissions
' Sample Main Form
Public Class FormAccessSecurity
' Requires delegates for each metod signature
Delegate Sub FormLoad()
Delegate Function FormLoadModal() As DialogResult
Private Sub Consume_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim AppSecurity As New SecurityHelper ' class defined below
' Using Form with custom attributes, executes if security rules ok.
Dim frm As New MyForm
AppSecurity.CheckSecurity(AddressOf frm.ShowDialog)
' Local sub with special attributes, executes if security rules ok.
AppSecurity.CheckSecurity(AddressOf Me.Test)
End Sub
<PrincipalPermission(SecurityAction.Demand, Authenticated:=True, Role:="Administrator", Unrestricted:=False)> _
Private Sub Test()
MessageBox.Show("Security is Happy to run Me.Test()!")
End Sub
End Class
' Sample Form with custom attributes on show and show diag
Public Class MyForm
Inherits System.Windows.Forms.Form
' Role Required here is "Gofer", expect failure
<PrincipalPermission(SecurityAction.Demand, Authenticated:=True, Role:="Gofer", Unrestricted:=False)> _
Public Overloads Sub Show()
MyBase.Show()
End Sub
' Role Required here is "Gofer", expect failure
<PrincipalPermission(SecurityAction.Demand, Authenticated:=True, Role:="Gofer", Unrestricted:=False)> _
Public Overloads Sub ShowDialog()
MyBase.ShowDialog()
End Sub
End Class
' Class for security implementation
Public Class SecurityHelper
' Requires delegates for each metod signature
Friend Delegate Sub FormLoad()
Friend Delegate Function FormLoadModal() As DialogResult
Friend Sub CheckSecurity(ByVal del As FormLoad)
If CheckAttributes(del.Method.GetCustomAttributes(False)) Then
del.Invoke()
End If
End Sub
Friend Sub CheckSecurityModal(ByVal del As FormLoadModal)
If CheckAttributes(del.Method.GetCustomAttributes(False)) Then
del.Invoke()
End If
End Sub
Private Function CheckAttributes(ByVal Attributes() As Object) As Boolean
For Each attribute As Object In Attributes
If TypeOf (attribute) Is PrincipalPermissionAttribute Then
Dim perm As PrincipalPermissionAttribute = CType(attribute, PrincipalPermissionAttribute)
If System.Threading.Thread.CurrentPrincipal.IsInRole(perm.Role) And perm.Action = SecurityAction.Demand Then
Return True
Else
MessageBox.Show("Insufficient security priveleges!", "Security Violation", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Return False
End If
End If
Next
' currently defaulting to true!
Return True
End Function
End Class
I hope this may be of some help.
Martin.
Whoops! Sometimes it is better to go have a coffee, at least then I don't look stupid! I have a habit of walking through my work in my head, and sometimes the penny drops!
To let the framework handle the security implementation logic, and for you to handle the security exceptions change the security provider to -
Comments?
' Class for security implementation
Public Class SecurityHelper
' Requires delegates for each metod signature
Friend Delegate Sub FormLoad()
Friend Delegate Function FormLoadModal() As DialogResult
Private Enum ErrorState
Unknown
SecurityError
End Enum
Friend Sub CheckSecurity(ByVal del As FormLoad)
Try
del.Invoke()
Catch ex As System.Security.SecurityException
RaiseError(ErrorState.SecurityError)
Catch
RaiseError(ErrorState.Unknown)
End Try
End Sub
Friend Sub CheckSecurityModal(ByVal del As FormLoadModal)
Try
del.Invoke()
Catch ex As System.Security.SecurityException
RaiseError(ErrorState.SecurityError)
Catch
RaiseError(ErrorState.Unknown)
End Try
End Sub
Private Sub RaiseError(ByVal ErrorType As ErrorState)
Select Case ErrorType
Case ErrorState.Unknown
MessageBox.Show("Unknown error occurred", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error)
Case ErrorState.SecurityError
MessageBox.Show("Insufficient security priveleges", "Security Error!", MessageBoxButtons.OK, MessageBoxIcon.Stop)
End Select
End Sub
End Class
It seems to me that the application of the security attributes is a waste of time unless you need something other than what you described.
While the method attributes can be appended/ altered at runtime, this is all out of scope. So I would presume that the best way to go is to check the user membership in the method itself not prior to opening or in an event handler! An event does not return a value and therefore no code execution logic can be applied where you are raising the event.
Consider
Public Class Sample
Private Sub Form5_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If Not My.User.IsInRole("Administrator") Then
SecurityHelper.RaiseError(SecurityHelper.ErrorType.InsufficientPrivieleges)
Exit Sub
End If
' If I'm here I am an admin
End Sub
End Class
Public Class SecurityHelper
Friend Enum ErrorType
InsufficientPrivieleges
End Enum
Friend Shared Sub RaiseError(ByVal ErrorType As ErrorType)
Select Case ErrorType
Case SecurityHelper.ErrorType.InsufficientPrivieleges
MessageBox.Show("In sufficient Priveleges")
End Select
End Sub
End Class