NOTE: This is the Visual Studio 2013 update of the popular Beginning LightSwitch article series. For previous versions see:
- Visual Studio 2012: Part 4: Too much information! Sorting and Filtering Data with Queries
- Visual Studio 2010: Part 4: Too much information! Sorting and Filtering Data with Queries
Welcome to Part 5 of the Beginning LightSwitch in Visual Studio 2013 series! In part 1- 4 we learned about entities, relationships, screens and queries in Visual Studio LightSwitch. If you missed them:
- Part 1: What’s in a Table? Describing Your Data
- Part 2: Feel the Love - Defining Data Relationships
- Part 3: Screen Templates, Which One Do I Choose?
- Part 4: Too much information! Sorting and Filtering Data with Queries
In this post I want to talk about user permissions, also known as Access Control. In most business applications we need to limit what resources users can access in the system, usually because of different job function or role. For instance, only system administrators can add new users to the system. Certain data in the application may be sensitive and should be restricted unless that user has rights to that data. LightSwitch makes it easy to define user permissions and provides hooks on entities and queries that allow you to check these permissions.
For a video demonstration on how to set up user permissions see: How Do I: Set Up Security to Control User Access to Parts of a Visual Studio LightSwitch Application?
Authentication & Authorization
There are two pieces of information LightSwitch applications need in order to determine which users have rights to what parts of the system. First, the system needs to verify the user accessing the application. This is called Authentication. In other words: “Prove you are who you say you are.” There are two supported types of authentication in LightSwitch; Windows and Forms.
Windows authentication means that the application trusts the user based on their Windows credentials. So once a user successfully logs into their Windows desktop, those credentials are automatically passed to the LightSwitch application. Forms authentication means that the application requests a username & password of its own, completely independent of any other credentials. So when you choose to use Forms authentication a login screen is presented to the user and they must type their username and password every time they want to access the application.
Once a user is authenticated, the application can determine access to parts of the system by reading their user permissions. This is called Authorization. In other words: “Now that I know who you are, here’s what you can do in the system.”
LightSwitch uses the ASP.NET membership provider model so you can also incorporate your own custom membership provider. For more information see Customizing LightSwitch User Management.
Setting Up User Permissions
It all starts on the Access Control tab of the Project Properties. To open it, double-click on the “Properties” node under the main project in the Solution Explorer.
Then select the Access Control tab to specify the type of authentication you want to employ as well as what user permissions you want to define.
By default, the application doesn’t have authentication enabled so here is where you select the type of authentication you want to use.
Using Forms authentication means you will be storing usernames and encrypted passwords inside the LightSwitch database. This type of authentication is appropriate for internet-based applications where users are not on the same network and you need to support other operating systems besides Windows. If you are deploying your application for mobile users or to an ISP or Azure website or cloud service, then you’ll want to choose Forms auth.
Using Windows authentication is appropriate if all your users are on the same network/domain or workgroup, like in the case of an internal line-of-business application. This means that no passwords are stored by your LightSwitch application. Instead the Windows logon credentials are used and passed automatically to the application. In this case you can also choose whether you want to set up specific users and roles or whether any authenticated user has access to the application.
The best way to think of the two options for Windows authentication are:
- Give special permissions and roles to the Windows users or Active Directory groups that I administer within the application. (This is always on if you have selected Windows authentication)
- ALSO, let any Windows user access the unprotected parts of my application
Next you define user permissions that you check in code in order to access resources (we’ll work through an example next). There is always a SecurityAdministration permission defined for you that is used by LightSwitch once you deploy the application. When you deploy, LightSwitch will create a single user with this permission which gives them access to the screens necessary to define the rest of the users and roles in the system. However, while debugging your application, LightSwitch doesn’t make you log in because this would be tedious to do every time you built and ran (F5) the application. So instead you can use the “Granted for debug” checkbox to indicate which sets of permissions should be turned on/off in the debug session.
Note: If you have enabled SharePoint in your LightSwitch application then the user management is handled by SharePoint. You can check the current user’s SharePoint profile information, including their department and role, by using the properties of the Application.User object. For more information see Using the Person Business Type
Let’s walk through a concrete example by implementing some security in our Address Book (Contact Manager) application we’ve been building in this series.
Checking User Permissions in the Address Book Application
Let’s start by selecting an authentication scheme. For this example, I’ll select “Use forms authentication” so that everyone that has access to the application can search for and edit contacts from any external network or internet. However, in order to add or delete contacts, users will need special permissions to do that.
So we need to create two new permissions. You can name the permissions whatever you want. You only see the name in code. When the system administrator sets up users and roles later, they will see the Display Name on the screen so be descriptive there. So add two permissions; CanAddContacts and CanDeleteContacts.
Next, leave the “Granted for debug” unchecked for both of those permissions so that we can test that they are working. When you leave this unchecked, the permission will not be granted. This allows us to easily test combinations of permissions while debugging. Now that we have these permissions set up here, we need to check them in code. As I mentioned, LightSwitch provides method hooks for you so you can write code when you need for all sorts of custom validation and business rules, including access control.
For more information on writing code in LightSwitch see the Performing Data-Related Tasks by Using Code topic in the library.
For more information on writing custom business rules see: Common Validation Rules in LightSwitch Business Applications
So in order to implement the security, we need to write a couple lines of code to check these permissions. LightSwitch provides access control methods on entities and queries and are executed on the server so that your data is protected no matter what client is hitting your middle-tier. When you want to restrict viewing (reading), inserting (adding), editing or deleting entities, open the entity in the Data Designer and drop down the “Write code” button and select the appropriate access control method.
For this application, select the Contacts_CanDelete method and this will open the code editor to that method stub. All you need to do is write one line of code (in bold below) to check the CanDeleteContacts permission you set up:
VB:
Namespace LightSwitchApplication
Public Class ApplicationDataService
Private Sub Contacts_CanDelete(ByRef result As Boolean)
'Add this one line of code to verify the user has permission to delete contacts:
result = Me.Application.User.HasPermission(Permissions.CanDeleteContacts)
End Sub
End Class
End Namespace
C#:
namespace LightSwitchApplication
{
public partial class ApplicationDataService
{
partial void Contacts_CanDelete(ref bool result)
{
//Add this one line of code to verify the user has permission to delete contacts:
result = this.Application.User.HasPermission(Permissions.CanDeleteContacts);
}
}
}
Now go back to the “Write Code” button on the designer and select Contacts_CanInsert and then similarly write the following line of code (in bold) to check the CanAddContacts permission. Your code file should look like this.
VB:
Namespace LightSwitchApplicationPublic Class ApplicationDataService
Private Sub Contacts_CanDelete(ByRef result As Boolean)'Add this one line of code to verify the user has permission to delete contacts:
result = Me.Application.User.HasPermission(Permissions.CanDeleteContacts)End Sub
Private Sub Contacts_CanInsert(ByRef result As Boolean)'Add this one line of code to verify the user has permission to add contacts:
result = Me.Application.User.HasPermission(Permissions.CanAddContacts)End Sub
End Class
End Namespace
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Security.Server;
namespace LightSwitchApplication
{
public partial class ApplicationDataService
{
partial void Contacts_CanDelete(ref bool result)
{
//Add this one line of code to verify the user has permission to delete contacts:
result = this.Application.User.HasPermission(Permissions.CanDeleteContacts);
}
partial void Contacts_CanInsert(ref bool result)
{
//Add this one line of code to verify the user has permission to delete contacts:
result = this.Application.User.HasPermission(Permissions.CanAddContacts);
}
}
}
You may be wondering why we are checking these permissions in the entity instead of the screens. Checking permissions in the entity guarantees that no matter what screen the user is working with, the data actions are protected. You need to remember to secure your entities on the server if you need to implement user permissions in your application. However, if you need to hide/disable UI elements on your HTML screens based on user permissions there are a couple options. See:
- LightSwitch Tip: A Simple Way to Check User Permissions from the HTML Client
- Using LightSwitch ServerApplicationContext and WebAPI to Get User Permissions
Run it!
Now we are ready to test the application so build and run by hitting F5. Because we didn’t grant the CanAddContacts permission for debug, if you try to add a contact and save the data an error message will be displayed.
If you go back to your project properties Access Control tab you can check off combinations of permissions so you can test them at debug time.
Users & Roles Screens
In order to set up users and roles in the system, the application needs to have an administration console and be deployed. When your application is deployed the first time, LightSwitch will ask you for an administrator username & password that it deploys into the users table and grants the SecurityAdministration permission. That administrator can then enter the rest of the users into the system.
For more information see: How to Assign Users, Roles and Permissions to a LightSwitch HTML Mobile Client
Wrap Up
As you can see defining and checking user permissions in Visual Studio LightSwitch is a simple but important task. Access control is a very common requirement in professional business applications and LightSwitch provides an easy to use framework for locking down all parts of the application through access control method hooks. Once you deploy your application, the system administrator can start setting up users and roles to control access to the secure parts of your application.
For more information on user permissions and deploying applications see Working with User Permissions and Deploying LightSwitch Applications topics on the LightSwitch Developer Center.
In the next post we’ll look at customizing the HTML client with some JavaScript and CSS. Until next time!
Enjoy!