CHAPTER 22

image

Authorizing Your Users

An important part of any application is security. To help secure your application, LightSwitch provides a security modal that you can use to control the actions of users. You can create server-based rules to restrict the data that various groups of users can view and update. And with desktop applications, you can limit the screens and controls that users can access. In this chapter, I’ll show you how to do the following:

  • set up permissions, roles, users, and administrators in a system
  • limit access to data based on permissions
  • restrict access to screens and screen controls based on permissions

The core part of this chapter will describe how to implement server rules to prevent groups of users from viewing, updating, inserting, or deleting records. With desktop applications, you can prevent certain users from updating specific fields in a table, and you can also apply access control to entire screens and individual controls within a single screen. In this chapter, I’ll show you how to implement these features.

To provide some practical examples, this chapter will show how you can prevent all users from using the system between midnight and 3 a.m. You will also find out how to dynamically change your application’s Start-up screen depending on the current user. Other examples include how to enable groups of users to bypass custom .NET validation and how to bind a list of usernames to a drop-down control.

Applying Permissions

LightSwitch security depends on permissions, which you define at design time. Permissions define what your users can do. LightSwitch defines permissions in the same way that it defines screens and entities in your application. It defines permissions as LSML data within your application.

At runtime, the system administrator creates roles and assigns permissions to those roles. Roles allow you to group together permissions, and you can assign the same permission to multiple roles. At runtime, the administrator also creates users and assigns the roles to users. Each user can belong to one or more roles. Figure 22-1 illustrates this relationship.

9781484207673_Fig22-01.jpg

Figure 22-1. Permissions are assigned to roles, and roles are assigned to users

To restrict access to screens and data, you would write code that checks whether the logged-in user belongs to a role that has been assigned the required permission.

Unlike permissions, roles and users are defined external to your application. Therefore, users can create users and roles, but they cannot define permissions. Figure 22-2 illustrates where permissions, roles, and users are defined.

9781484207673_Fig22-02.jpg

Figure 22-2. Here are where permissions, roles, and users are defined

Image Note  A role can have any number of permissions assigned to it, and any number of users assigned to it.

Defining Permissions

You define permissions through the Access Control section of your project’s properties page.

Figure 22-3 shows an example set of permissions for an application. Let’s suppose you only want to allow managers to add and modify engineer records. You can accomplish this by defining a permission called CanEditEngineers. Once you add this permission, you can enforce this rule by writing code. I’ll describe the code you need to use as this chapter progresses.

9781484207673_Fig22-03.jpg

Figure 22-3. Adding permissions in the Access Control tab

In the list that appears in Figure 22-3, notice the SecurityAdministration permission that appears at the top. The SecurityAdministration permission is a built-in permission. Users with this permission can create and modify the roles and users in your application.

Image Note  To define permissions, you must enable Windows or Forms authentication. LightSwitch disables the Permissions grid if authentication is not enabled for your application.

Creating an Application Administrator

Every application requires an initial administrator. The purpose of this administrator is to create additional users in your application. This user also needs to create roles and decide which permissions need to be added to those roles, and which roles are assigned to which users.

For web applications that use Forms authentication, you can define the username and password of the administrator when you install your application in IIS. LightSwitch stores the username and password of the initial administrator in your web.config file (Figure 22-4). If your application contains no administrators when it first runs, LightSwitch uses the details in the web.config file to add the initial user.

9781484207673_Fig22-04.jpg

Figure 22-4. Specifying the initial user for your application

For two-tier desktop applications, you can define the username and password of your administrator when you publish your application from Visual Studio.

Managing Roles and Users

To manage roles and users, use an administrative account to log in to a desktop application. You can use any account that belongs in a role that’s been granted the SecurityAdministration permission.

By default, you can find a link to the Roles screen in the Administration section of the navigation menu (Figure 22-5). This screen allows you to create roles and assign permissions to those roles. It also allows you to assign users to roles. The Users screen allows you to add, edit, and delete users.

9781484207673_Fig22-05.jpg

Figure 22-5. Roles screen

Note that you can only manage roles and users through desktop applications. If you have an HTML client application and you want to define roles and users, you will need to add a desktop client to your application to allow you to access these two administrative screens.

Debugging Permission Code

When you debug an application, LightSwitch won’t prompt you to log in, even when you enable authentication. So, to test that your application works as expected, you can assign yourself permissions at debug time by checking the “Granted for Debug” checkbox, which appears next to each permission row (as shown in Figure 22-3).

LightSwitch grants you the permissions that you check while you run your application in debug mode. This enables you to test any security code that you add to your application.

Securing Server Objects

In this section, I’ll show you how to define rules so as to limit the data that users can view and edit. With the exception of one item (which I’ll explain later), the content in this section applies both to desktop and HTML client applications.

Because LightSwitch executes the code on the server, your access-control rules will apply when users access your data through OData or from Server Application Context code.

Applying Table-Level Access Control

You can apply access control at the table (or entity-set) level to control whether a user can add, view, edit, or delete records in the table. All screens that bind to the table will honor the access-control rules that you define at the table. The benefit of this approach is that you can define your access-control rules in a single place, without the need to modify and carry out checks on every screen that consumes the data.

To create access-control code, open your table in the table designer and click the Write Code button. Here, you can find a number of access-control methods, as shown in Figure 22-6. When you select a method, LightSwitch opens the code editor and creates a code stub in your data service class (that is: ServerDataSourcesApplicationData\_ApplicationDataService.lsml.[cs|vb], or the equivalent data-service file).

9781484207673_Fig22-06.jpg

Figure 22-6. Entity-set access-control methods

LightSwitch enforces the access-control rules on the server. The benefit of this is that if a user attempts to read or update data outside of a screen (via the OData endpoint, for example), LightSwitch still enforces your access-control rules.

To prevent the current user from a performing an action, set the return value of the relevant access-control method to false. For example, to prevent the current user from deleting engineers, set the return value of the Engineers_CanDelete method to false.

Image Note  Although this section uses the word table, the code I show you applies also to all entity sets from external data sources. Therefore, you can use the same techniques I show you in this section to control the actions a user can carry out in a SharePoint data source.

Restricting Users from Editing Data

To illustrate how to apply security code, let’s look at how to build a rule to limit the users who can add, update, and delete engineer records. The code that I show you will restrict these operations to users who belong to roles that you grant the CanEditEngineers permission. All other users can view engineer records, but not update any details.

To apply this rule, you need to add code to the Engineer_CanDelete, Engineer_CanInsert, and Engineer_CanUpdate methods. To add this code, open the Engineer table in the table designer, click the Write Code button, and add the code that’s shown in Listing 22-1.

To prevent a user from performing an action, you would set the return value of the respective access control method to false. For instance, you would set the return value of the [Table]_CanInsert method to false to deny a user the right to add rows to a table.

The code in Listing 22-1 utilizes the Application.User object. This is a versatile object that provides many useful features. You can use it to return the full name of the current user and to return other useful authentication properties, as shown in Figure 22-7.

9781484207673_Fig22-07.jpg

Figure 22-7. IntelliSense options for the Application.User object

An important method that this object exposes is the HasPermission method. This method accepts a permission value and returns whether the current user belongs in a role that includes the permission you supply. To make it easier for you to supply a permission value, LightSwitch provides a Permissions class that defines all the permissions in your application. As Listing 22-1 shows, you can refer to the CanEditEngineers permission by using the syntax Permissions.CanEditEngineers.

If you write access-control code that prevents a user from deleting, inserting, or updating records, LightSwitch automatically disables any built-in buttons (in data grids, for example) that carry out these functions. However, if you create a custom screen command (e.g., button or link) to perform a data operation that you disallow in code, LightSwitch won’t automatically disable your button. You will need to write code in the screen command’s _CanExecute method to perform this task.

An important point to remember when you write authentication code is to not perform access-control checks based on role membership. Because administrators define roles at runtime, you can’t guarantee that the role will exist. Therefore, you should always check against permissions and leave the task of managing roles and role permissions to the application’s administrative user.

Restricting Users from Reading Data

You can prevent users from reading data by setting the result of the table’s CanRead method to false. If a user with insufficient permissions attempts to open a screen that contains a data grid, the data grid will display nothing except a red X. This behavior isn’t user friendly, so it’s good practice to write additional screen code to stop the user from opening the screen in the first place.

When you use this technique to deny read access to a table, LightSwitch also disables access to the data inside the server pipelines. This reduces the possibility of any data “leakage.” Because LightSwtich applies the rule at the server, it also protects the data that it exposes via the OData endpoint. Therefore, a malicious user cannot circumvent your security by opening a browser and viewing the ApplicationData.svc page.

If your server-side business logic requires access that the current user doesn’t have, you can override the restrictions by granting the necessary permissions in code. You would use the method Application.Current.User.AddPermissions.

Image Note  Unfortunately, you can only call AddPermissions from code in the Save pipeline. If you try to call this method from any of the methods in the Query pipeline (e.g., PreProcessQuery), you’ll receive an exception. This behavior prevents you from denying all users read access to a table, and from only allowing access through queries (the queries would include permission-elevation logic that depended on the identity of the logged-on user).

Restricting Users from Saving All Data

You can prevent users from saving data by setting the return value of the SaveChanges_CanExecute method to false. LightSwitch executes this method on the server when a user attempts to save data. Unlike the access-control methods that I’ve explained up until now, this single method applies to all tables in the data source. If the SaveChanges_CanExecute method returns false, the user won’t be able to save any data in any table at all.

The logic that you write in any of these security methods is not only restricted to permission checks. You can also deny access based on other business rules. To give an example, the code in Listing 22-2 shows how you can use this technique to restrict access to your application between the hours of midnight and 3 a.m.

Restricting Users from Editing a Property

There may be situations in which you want to prevent users from modifying specific fields in a table. You can accomplish this by setting the result of the property’s _IsReadOnly method to true (Figure 22-8).

9781484207673_Fig22-08.jpg

Figure 22-8. IsReadOnly method

To demonstrate this technique, let’s look at how to restrict the users who can edit the problem description field in the Issue table. In this example, all users can view issue records, but only users who belong in roles with the CanChangeIssueDescription permission can modify the problem description. If a user lacks this permission, LightSwitch will render the problem description property as read only on all screens that show this property. Listing 22-3 shows the code that implements this rule.

In this listing, notice how the code checks whether the user is adding a new issue record by testing for an ID value of 0. If the user is adding a new record, it returns false to allow the user to create the problem description.

A caveat of this technique is that the IsReadOnly method applies only to desktop applications. If you define a property as read only for a user and that user edits the property in an HTML client application, LightSwitch will allow the change to take place.

Applying Query-Level Permissions

You can create rules to control the users who can execute a query. Each query includes a CanExecute method (Figure 22-9). Like the other examples in this section, you can prevent a user from executing a query by setting the return value of this method to false.

9781484207673_Fig22-09.jpg

Figure 22-9. A query’s CanExecute method

To illustrate this method, let’s look at how to allow only users with the CanViewReport permission to execute a query called IssuesWithHighestFeedback. To implement this rule, add the code that’s shown in Listing 22-4 to the query’s CanExecute method.

Securing Client Objects

In this section, I’ll describe access-control techniques that you can apply to your client. Because LightSwitch provides better support for desktop clients, this section focuses predominantly on desktop applications. In this section, I’ll show you how to control the users who can open specific screens. Next, I’ll show you how to restrict the use of buttons and commands on individual screens.

Restricting Users from Opening Screens

To control access to a screen, open your screen in the designer, click the Write Code button, and select the screen’s _CanRun method. This generates a method stub in LightSwitch’s client application class. To prevent users from opening a screen, set the result of the _CanRun method to false.

To demonstrate this technique, let’s look at how to restrict access to the Engineer Management screen. The code that I will show you enables only users who belong in roles that are assigned the CanEditEngineers permission to open the screen. To implement this rule, open the screen in the designer and add the code that’s shown in Listing 22-5.

If a user attempts to open a screen (e.g., from a user-defined method) where the result of the _CanRun method returns false, the screen will not open.

To help keep your navigation menu tidy, LightSwitch automatically filters the screens that are shown in the navigation menu. If a user has insufficient permissions to open a screen, LightSwitch hides the screen in the navigation menu.

Restricting Users from Clicking Links and Buttons

Screen buttons and links bind to screen commands that appear in the screen member list of the screen designer. To prevent a user from executing a command, set the result of the command’s _CanExecute method to false. You can open the code editor by clicking the link in the command’s property sheet (Figure 22-10).

9781484207673_Fig22-10.jpg

Figure 22-10. Execute methods

If a user lacks the permission to execute a command, LightSwitch automatically hides any buttons or links that bind to that command.

In this example, the Issue Detail screen includes a link that opens a PDF report. This link should only be visible if the user belongs in a role that’s been assigned the CanViewReport permission. Listing 22-6 shows the code that carries out this rule.

Image Tip  Although I show you how to use the CanRun method to enforce permissions, remember that you can also use this method to guard screen commands based on other conditions. Let’s suppose you create a method that generates Microsoft Word documents by using COM automation. If your application runs as a browser application (rather than as a desktop application), you can hide the button that carries out the Word automation by writing code in the CanRun method that checks AutomationFactory.IsAvailable.

Securing HTML Client Applications

The access-control features that are available in HTML client applications are far more limited than their desktop client equivalents. First, there’s no way to control the users who can open screens. Unlike desktop applications, each screen doesn’t include a CanRun method you can use to restrict access to the screen.

Any custom screen method that you create includes a CanExecute method (Figure 22-11). You can set the return value of this method to false to disable any buttons or controls that bind to the method.

9781484207673_Fig22-11.jpg

Figure 22-11. CanExecute code

The HTML client does not implement a JavaScript equivalent of the .NET HasPermission method. Because of this, you can’t write JavaScript code to determine the permissions that the current user has. This makes it almost impossible to write meaningful client-side access-control code.

You can probably devise a method to carry out more useful permission checks and to work around this problem. However, note that JavaScript is an interpreted client-side language. An end user can view any bespoke security code you writing by viewing the source of your web page. Because of this, it’s best to focus your efforts on applying security at the server level so as to secure HTML client applications.

Custom Authorization Examples

Now that I’ve explained how the LightSwitch security model works, I’ll show you some practical security features that you can add to your application.

Associating Logins with Your Data

As you’ve seen throughout this book, the sample Help Desk application stores engineer records in a custom table. When you enable authentication, LightSwitch stores the username and password combinations in a table that the membership provider manages. You can enhance your application by associating the records in your custom table with the usernames in the membership database. In our application, for example, you could use this enhancement to set default values or to open screens at start-up depending on the data that you store in the Engineer table.

To build this functionality, the first step is to add a field to your Engineer table to store the engineers’ usernames. The next step is to build a screen to enable users to set the username for each engineer record. To assist with data entry, you can make it easier for users to enter a username by providing a drop-down list that contains a list of valid usernames. In this example, I’ll show you how to build a drop-down list control that binds to the security data. This control opens in a modal window that includes OK and Cancel buttons. When the user clicks the OK button, the code will update the engineer with the username that the user selects in the drop-down control. Figure 22-12 shows the end result of this example.

9781484207673_Fig22-12.jpg

Figure 22-12. Opening the modal window with a login name drop-down

To create this screen, open an Engineer Details screen and carry out the following screen-design steps:

  1. Use the Add Data button to add a new string property called LoginNameProperty. Uncheck the “Is Required” checkbox.
  2. Add a new modal window control to your screen. You can use a columns layout group to place the Modal Window button to the right of the login name field.
  3. Drag the LoginName property onto your screen. Change the control type to a custom control and set the custom control type to a combo box.

Add OK and Cancel buttons to your modal window control. Name your buttons OkModalWindow and CloseModalWindow respectively. Figure 22-13 shows the design-time view of your screen.

9781484207673_Fig22-13.jpg

Figure 22-13. Design-time view of Username Picker screen

Now, add the code that’s shown in Listing 22-7. Once you deploy your application and set up some users, you’ll be able to use the drop-down control to enter users.

Let’s look at an explanation of this code. The code that runs on initialization uses the DataWorkspace.SecurityData object to obtain a list of usernames image. The UserRegistrations collection returns the username data, and the next block of code sets the data source of the drop-down to be a list of usernames image. The code that runs when the user clicks the OK button sets the LoginName of the engineer record to the login name that the user selects in the drop-down image. The code that runs when the user clicks the Close button simply calls the CloseModalWindow method to close the modal window image.

As a side note, the DataWorkspace.SecurityData object provides many useful features you can use, including properties you can use to determine the role membership and permissions of a given user. You can even call a method to change the password of a user. Figure 22-14 shows some of the features that the SecurityData object provides.

9781484207673_Fig22-14.jpg

Figure 22-14. The SecurityData object provides many useful features

Image Note  If you deploy an HTML client application to SharePoint, you can use the built-in person-picker control to select users. Typically, SharePoint users map to Active Directory users in on-premises installations of SharePoint.

Opening Screens Conditionally at Login

The ability to configure the Start-up screen of an application in code can be very useful. In typical business applications, different groups of users often focus on different tasks. Therefore, you can make your application more user friendly by showing a Start-up screen that is relevant to the user who logs on.

To demonstrate this technique, I’ll show you how to customize the start-up routine of your application based on the engineer who logs in. If the engineer who logs in has the CanViewAllIssues permission, the application opens a screen that is suitable for managers. For all other engineers, the application opens a regular Start-up screen.

As a prerequisite to this section, create a set of screens for managers and non-managers. Name your screens EngineersManagerGrid and EngineerDashboard respectively. You may have created these screens earlier in this book. Now, carry out the following steps:

  1. Create a new screen by using the New Data Screen template. Leave the Screen Data drop-down blank and name your screen StartUp.
  2. Click the Write Code button, select the Startup_CanRun method, and enter the code that’s shown in Listing 22-8.
  3. Open the properties of your application and use the option in the Screen Navigation tab to set your Start-up screen to StartUp.

At this point, you can run your application and see how the Start-up screen changes depending on the permissions of the user who logs in.

This technique utilizes the screen’s CanRun method image rather than the IntializeDataWorkspace or Activated method. If you were to use one of these screen methods, the user would see the Start-up screen appear prior to the code opening the desired screen.

If the user has the CanViewAllIssues permission image, the code opens the manager screen. If not, it retrieves the engineer ID that relates to the logged-in user image. Because this code runs outside the context of a screen object, it needs to create a data workspace to perform this query. If the code finds the engineer, it opens the Dashboard screen for the engineer. In this example, ShowEngineerDashboard includes a parameter you can use to set the data that the screen shows. Finally, the code sets the return value of the CanRun method to false image to cancel the opening of the Start-up screen.

Configuring the Start-up Screen in HTML Applications

With HTML client applications, you can specify the Start-up screen through the JavaScript method that starts your application. The default entry point to an HTML client application is the default.htm web page. Toward the bottom of this file, you can find the code that starts your application. This method is called _run, and as Figure 22-15 illustrates, you can specify the screen name that your application shows when it starts.

9781484207673_Fig22-15.jpg

Figure 22-15. Contents of Default.htm file

A technique that you can use to customize your Start-up screen is to replace the default.htm page with an ASP.NET page. Once you do this, you can write .NET code that emits JavaScript to start your application with a specific screen. If you add login controls to your .NET page, you can write .NET code that chooses the Start-up screen based on permissions or other server-side logic.

Restricting Row-Level Access to Data

Another common business requirement is the ability to restrict which rows from the table that a user can see. To demonstrate how to build this feature into your application, let’s look at how to configure the Help Desk system so that engineers can only view the issue records that are assigned to them.

The best way to enforce this rule is to apply your access-control rule on the default All query. This is because all queries that return issue records ultimately call the default All query. Therefore, LightSwitch will always execute the code that you define here every time you return data from the issues table.

To create this example, open the issues table in the table designer. Click the Write Code button and select the Issues_Filter option. Add the code that’s shown in Listing 22-9.

Let’s review how this code works. The first part checks whether the user has the CanViewAllIssues permission. If the user doesn’t have this permission, the code obtains the currently logged-in engineer image. Next, it applies a filter to only return only the records where the assigned-to engineer of the issue record matches the engineer who is logged in image.

It’s very important to note that if an engineer retrieves issue records through a navigation property, the data-retrieval process bypasses the default _all query. If an engineer can view other engineer records on a screen that shows related issues, the engineer can view the issue records that should not be visible.

Another important point is that if an engineer updates a record that someone else has updated, the concurrency-error window that appears could contain data that shouldn’t be seen by the engineer.

Image Caution  If you need to restrict the data that a user can see, make sure to test your application to make sure that data leakage doesn’t occur in the way that I have described.

Setting Screen Control Properties by Permission

Another way in which you can enhance your application is to hide screen controls based on the current user. In this section, I’ll use the issue Search screen to demonstrate this technique. This screen includes an auto-complete box control that allows the user to filter the results by assigned engineer. I’ll show you how to configure this screen so that users with the CanViewAllIssues permission have full access to the auto-complete box. I’ll also show you how to configure the Search screen to only return records for the current user if that user lacks the CanViewAllIssues permission. We’ll accomplish this by setting the selected item in the auto-complete box to the current user, and we’ll then prevent the user from changing the selected item by making the control read-only.

The prerequisite to this example is to create a Search screen for the issue table if one doesn’t already exist. Name your screen IssueSearchAll and configure it so that it filters the results by a property called EngineerSelectionProperty. Now, click the Write Code button, select the InitializeDataWorkspace method, and enter the code that’s shown in Listing 22-10.

Let’s look at how this code works. If the user doesn’t have the CanViewAllIssues permission, the code obtains the currently logged-in engineer image. It then sets the selected item of the AutoCompleteBox to this engineer and disables the control by setting the IsEnabled property to false image.

Allowing Users to Bypass Validation

In the final example of this chapter, I’ll show you how to allow specific users to bypass custom validation. Typically, you would use this technique to enable special users to carry out changes that normal users cannot perform. For example, let’s suppose you create a rule that prohibits users from entering a close date for an issue record without selecting the engineer who closed the issue. It’s possible to configure your validation code to relax this rule for managerial users.

To implement this technique, you can simply amend your .NET validation code to only apply a rule based on whether the current user has a particular permission. This simple technique requires you to modify every validation rule that you have defined on a table.

An alternative technique is to write code in a table’s _AllowSaveWithErrors method. If you set the return value of this method to true, the current user can save changes irrespective of any validation failures in the record. You can use this technique when you want a user to be able to circumvent all validation rules in a table, as opposed to just specific rules in a table.

To illustrate this technique, let’s look at how to implement a rule to allow users with a permission called CanBypassValidation to save changes to the Issue table without adhering to any custom .NET validation rules. To implement this rule, open the Issue table, click the Write Code button, and select the Issue_AllowSaveWithErrors method. Enter the code as shown in Listing 22-11.

If you now run your application and log in as a user with the CanBypassValidation rule, you’ll be able to save your changes without adhering to the validation rules.

Although this code allows the user to bypass any custom .NET validation rules, LightSwitch still honors the validation rules that your data layer defines (for example, SQL Server check constraints).

Summary

In this chapter, I showed you how to secure your application. With LightSwitch, you can restrict access to tables, rows, queries, screens, and individual controls on screens. LightSwitch security comprises three types of objects: permissions, roles, and users.

For each application, you create permissions to define the access rights. The developer defines permissions, and LightSwitch stores these in LSML format inside a file called service.lsml. In contrast, the system administrator defines roles and users at runtime. LightSwitch stores roles and users in the Intrinsic database. Roles allow you to group together permissions. The system administrator assigns permissions to roles; it’s possible to assign the same permission to multiple roles. To configure the actions that each user can carry out, the system administrator assigns roles to users. Each user can belong to one or more roles.

At the server, you can apply access rules to tables and queries. With tables, you can limit the users who can view and edit data. For each table, you can write .NET code in the [TableName]_CanRead method to define the users who can view the data in the table. To prohibit a user from viewing data in the table, you would set the return value of this method to false. The general pattern you use to enforce rules is to test if the current user has a permission by calling the Application.User.HasPermission method. To check for a specific permission, you would pass the permission name to this method. You can use the result of this method to set the return value of the [TableName]_CanRead method.

To prohibit a user from editing data, you would write code that sets the return value of the [TableName]_CanDelete, [TableName]_CanInsert, and [TableName]_CanUpdate methods. To prevent a user from deleting, inserting, or updating, you would set the return value of the respective method to false.

For each data source, LightSwitch exposes a method called SaveChanges_CanExecute. You can prevent a user from saving changes to all tables in the data source by setting the return value of this method to false.

In the case of desktop applications, all screens expose a method called [ScreenName]_CanRun. You can prevent a user from opening a screen by setting the return value of this method to false. If a user has insufficient permissions to open a screen, LightSwitch will hide the menu item that opens the screen in the navigation menu. At a screen level, each button on a screen exposes a method called [CommandName]_CanExecute. You can prevent a user from executing a button by setting the return value of this method to false.

Unlike desktop applications, the HTML client does not have a JavaScript method you can call to determine the permissions of the current user. Therefore, with HTML client applications, you cannot easily prevent users from opening screens or clicking buttons based on permission.

In the final part of this chapter, I demonstrated security features you can add to your application. If your application contains a custom table that stores user data, you can build more-useful applications if you have some way to link your user data with the LightSwitch login names. To retrieve a list of usernames, you can use the methods that LightSwitch exposes through the DataWorkspace.SecurityData object. I showed you how to use this method to create a drop-down list that shows a list of users. I then showed you how to use this control on a screen to associate users with engineer records.

Next, I showed you how to customize your application’s Start-up screen based on the current user. You can implement this technique by creating a “dummy” Start-up screen. This Start-up screen includes code in the CanRun method that conditionally opens an actual Start-up screen based on the current user.

A common requirement is the ability to limit the rows that a user can view in a table. You can implement this feature by writing code in the Filter method of table. You would write .NET code to filter out the records that you don’t want the user to see. Any query that returns data from this table will apply the filter that you specify in this method. The benefit of this technique is that you can apply your rule in a single place, rather than add code to every query that returns data from the table. An important caveat to this technique is that the code doesn’t apply to data that a user accesses via a navigation property or to data that LightSwitch displays in the concurrency error dialog. Therefore, it’s important to exercise some caution when you use this method.

Finally, I showed you how to create a permission that allows a user to override all the custom validation rules in a table. You can implement this technique by writing code in the table’s AllowSaveWithErrors method. Within this method, you can check a user’s permissions and set the return value of this method to true so as to allow the current user to save data, even when validation errors exist in the data.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset