.Net Security: How to apply security in your application

How to apply security in your application

There are two ways to apply security in an application with Visual Guard: Execute security actions or test permissions in the code of your application.

The first way is fully dynamic and separates the implementation of the security in your application from the rest of your code but it has some limitations if you need to apply security on an object loaded dynamically or if the permissions are tightly integrated with the application data.

The second way allows you to tightly integrate the security in your application but it means modifying the application code and redeploying your application each time the security implementation needs to be modified.

Using Security Actions

Security actions are defined in the Visual Guard console and attached to a specific permission. When the permission is granted to a user, Visual Guard will execute the security action in your application. There are 2 types of security actions:

  • 'Properties' Action: This type of action dynamically modifies the value of a property of an object that is secured by Visual Guard in your application.
  • 'Script' Action: This type of action allows you to dynamically execute a script in your application.

Properties Action:

These security actions modify the value of a property of an application component. For example, Visual Guard can set the property 'Enabled' of the button 'OK' to false or can set the property 'Filter' of a Dataview containing the customer list to 'Country = 'USA''.

These actions can be executed when the object request to be secured is invoked or event of the object is raised. For example, you can execute an action that will disable the button 'OK' each time the event 'EnabledChanged' of the button 'OK' is raised. In this case the button will be always disabled.

You can also define a condition for a security action. Visual Guard will evaluate the condition just before executing an action. If the condition is false, the action is not executed. For example, you want to disallow modification of a sales order in a form when the user is not the creator of the sales order. In this case, you can define a Property 'IsCreator' on your form (this property must be a 'public' property). This property will indicate when the current user is the creator of the Sales Order. In your security action you will add a condition that will check this property before disabling the button 'Save' and setting fields to ReadOnly mode.

You can also use permission arguments to change the value of a property. For example, you want to display only sales orders created by employees based in a particular country. In this case you should create a permission with an argument 'Country'. This argument will contain the Country code used to filter the list. Then you should add a security action to this permission. This action will change the property 'Filter' of the Dataview containing the list of Sales orders. The value will not be a predefined value but a value based on a Visual Guard expression. The expression will be:

#CurrentValue + ' And Country = '''+ #Permission['Country'] + ''''

Visual Guard will evaluate the expression at runtime and replace the current value of the Filter property with the value of the expression.

When an object is dynamically created (like a Template in a WebForm application), Visual Guard cannot see this object and you cannot add an action on this object. In this case you can add a public property on your target object and set this property. For example, the column 'Salary' of a GridView in WebForm needs to be hidden depending on the permission. The 'Salary' column is not visible in the Visual Guard console. You have to add the property 'HideSalary' on your WebForm and test the value in your program to determine whether the column is visible.

public bool HideSalary
{
   get
   {
      return hideSalary;
   }
   set
   {
      hideSalary = value;
      EmployeeDataList.Columns[5].Visible = value;
   }
}

Once the property is added, you can add a security action that will set this property when needed.

Script Action

This type of action enables you to execute a script defined in the Visual Guard console when a permission is granted to a user. The scripts will be dynamically compiled at runtime when the security is loaded for a user and will be executed in the domain of the application. In these scripts you can use the class of your application just like in your application code.
The following example shows how to use the information available from the script.

Option Explicit On

Imports Novalys.VisualGuard.NorthwindSample
Imports Novalys.VisualGuard.Security
Imports Novalys.VisualGuard.Security.Action
Imports System
Imports System.Collections
Imports System.Windows.Forms
Imports System.Text

Namespace Novalys.VisualGuard.DynamicScript
   Public Class Cdff07f9054f2411bac2d424a4346dc27
      Inherits Novalys.VisualGuard.Security.Action.VGDynamicScript
      Public Overrides Sub Execute(ByVal target AsObject, ByVal permission As VGIPermission, ByVal eventArgs() As Object)

      ' All script actions can be seen in the debugger
      ' If the current application is in debug mode, signals a breakpoint to the debugger

DebugBreak()

      ' This parameter contains the object for which the action is executed
      Dim main as MDIForm = CType(target, MDIForm)
      main.Text = main.Text + " ********"

      ' Information about the current permission and its attributes
      Dim sb As New StringBuilder
      sb.AppendFormat("Current Permission : {0} (id={1})", permission.Name, permission.Id)
      sb.Append(Environment.NewLine)
      sb.AppendFormat(" * Value of the permission attribute 'Attribute1': {0}",       permission.Item("Attribute1"))
      sb.Append(Environment.NewLine)
      sb.AppendFormat(" * Value of the permission attribute 'Attribute2': {0}",       permission.Item("Attribute2"))
      sb.Append(Environment.NewLine)

      ' Information about the arguments of the event for which the action is executed
      ' For example for a click event:
      ' * the first element in the array is the sender
      ' * the second is the EventArgs

      If eventArgs.Length > 0 Then
         sb.Append("Event Information")
         sb.Append(Environment.NewLine)
      For Each arg As Object In eventArgs
            sb.AppendFormat(" * {0}", arg.GetType().ToString())
            sb.Append(Environment.NewLine)
         Next
      Else
         sb.Append("The event does not have any arguments")
         sb.Append(Environment.NewLine)
      End If

      ' Information about the current principal
      sb.AppendFormat("Current User: {0}", VGSecurityManager.Principal.Identity.Name)
      sb.Append(Environment.NewLine)
      For Each role As VGGrantedRole In VGSecurityManager.Principal.Roles
         sb.AppendFormat("{0}, ", role.Name)
      Next
      MessageBox.Show(sb.ToString())
   End Sub
End Class
End Namespace

Testing permissions in your application

In some cases, it is not possible to use security actions to adapt the application to the permission granted to the user. For example, Visual Guard cannot apply a security action on an object created dynamically in your application. It is also difficult to apply security actions that depend on data defined in the application. In this case, you will need to check in your application when a permission or role is granted to the current user.

The property VGSecurityManager.Principal allows you to get information about the current user. You can use the method VGSecurityManager.Principal.HasPermission to check whether a permission is granted to this user and the method VGSecurityManager.Principal.IsInRole to determine whether this user belongs to a role.

This example shows how to determine whether the permission 'Display only particular country information’ is granted to the current user and how to get the value of the argument 'Country'

If Not VGSecurityManager.Principal.HasPermission("Display information only on a particular country") Then
   MessageBox.Show("The current user can see all countries")
Else
   Dim myPerm As VGSecurityManager.Principal.GetPermission("Display information only on a particular country")
   Dim myValue As String = CType(myPerm("Country"), String)
   MessageBox.Show(String.Format("The current user can see information only about the country '{0}'", myValue))
End If

When the value of a permission argument can only be resolved at runtime, you can change the value by using the property VGIPermissionAttribute.Value

Using VGPrincipalPermission and Code Access Security

Visual Guard enables you to use the code access security to restrict the access to a method or a class. For example, the code below prevents the "MethodWithRestrictedAccess' method from being invoked by a user who is not an Administrator and does not have the '\Employees\Allows to edit employees' permission.

<VGPrincipalPermission(SecurityAction.Demand, Name="Administrator",Type=VGPermissionType.Role]> _
<VGPrincipalPermission(SecurityAction.Demand, Name="\Employees\Allows to edit employees",Type=VGPermissionType.Permission)]> _
Private Sub MethodWithRestrictedAccess()
   MessageBox.Show("You can see this message only if you are an Administrator")
End Sub

You can also use the VGPrincipalPermission class to check in your code whether the current principal has a permission or a role or is authenticated

Private Sub MethodWithRestrictedAccess()
   Dim PrincipalPerm1 As New VGPrincipalPermission("\Samples\Allow to call restricted method", VGPermissionType.Permission)
   Dim PrincipalPerm2 As New VGPrincipalPermission("Administrator", VGPermissionType.Role)
   PrincipalPerm1.Union(PrincipalPerm2).Demand()
End Sub

Using URL authorization in ASP.Net context

In ASP.Net context, Visual Guard enables you to use the standard ASP.NET URL authorization module to allow or deny access to a particular directory by user name or role. For example, the following authorization section of a web.config file shows how to allow access to the members of 'Administrator' role and deny access to all other users.

<authorization>
   <allow roles="Administrator"/>
   <deny users="*"/>
</authorization>

Visual Guard extends this standard ASP.NET URL authorization module and enables you to check Visual Guard permissions granted to the current user.
To do that, Visual Guard has to prefix the fullname of the permission to check with a percent character (%). Il is also possible to use the Visual Guard unique id to specify a permission. In this case, you have to use the format: %{dddddddd-dddd-dddd-dddd-dddddddddddd }

The following example shows how to allow access to a user with the permission with a fullname equal to '\Employees\Allows to edit employees' and the permission with an id equal to 'e40b426a-9e78-4cb6-9f0d-ab047420f542'.

Using ASP.NET login controls Web

<authorization>
   <allow roles="Administrator"/>
   <deny users="%\Employees\Allows to edit employees,%{e40b426a-9e78-4cb6-9f0d-ab047420f542}"/>
</authorization>

Visual Guard enables you to use the standard LoginView control to display the appropriate content for a given role or user. It allows you to use a Visual Guard permission in place of a role. In this case you have to prefix the fullname of the permission with a percent character (%). The syntax is the same as described in the URL authorization chapter.

<asp:LoginView ID="LoginView1" runat="server">
   <RoleGroups>
      <asp:RoleGroup Roles="%\Employees\Hide Salary">
               ...
      </asp:RoleGroup>
      <asp:RoleGroup Roles="%{e40b426a-9e78-4cb6-9f0d-ab047420f542}">
               ...
      </asp:RoleGroup>
   </RoleGroups>
</asp:LoginView>

Visual Guard is also compatible with all ASP.NET login controls and with the security trimming option of the standard SiteMapProvider to filter the content of a site map.

See Also
Debugging Visual Guard Security Actions
How Visual Guard secures an application