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.

[1325 byte] By [MrFrijole] at [2007-12-24]
# 1

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?

ahmedilyas at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 2

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

mokeefe at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 3
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?

MrFrijole at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 4

This looks like an ASP question which usually go to www.asp.net

ReneeC at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 5
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
ahmedilyas at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 6

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.

mokeefe at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 7

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.

mokeefe at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 8

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

mokeefe at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic Language...
# 9

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

mokeefe at 2007-8-31 > top of Msdn Tech,Visual Basic,Visual Basic Language...