Sharing the goodness…
Beth Massi is a Senior Program Manager on the Visual Studio team at Microsoft and a community champion for business application developers. Learn more about Beth.
More videos »
NOTE: This information applies to LightSwitch Beta 1 ONLY. For Beta 2, please read the Beta 2 Deployment Guide.
Last post I showed you how to deploy a 3-tier Beta 1 LightSwitch application to a Windows 7 or Windows 2008 machine running IIS 7. As I mentioned in that post a few times the team has already fixed a lot of the issues with deployment so the experience will be a lot easier with the next release. It’s already pretty easy to set up and deploy automatically to a Windows 2008 server running IIS 7 (and I’ll show you how to do that) but the team is enabling a lot more for RTM, including Azure deployment directly from LightSwitch. I also mentioned that I would show you how to set up security in a LightSwitch application in a follow up post, so as promised, here we go.
Security is a big feature in LightSwitch and there are hooks built in all over screens, queries and entities that allow you to easily check permissions you define. Here’s the library documentation to check out: How to: Create a Role-based Application. In this post I’m first going to show you how to set up and check for permissions in your application and then I’ll deploy the application as a three-tier application and walk you through the security administration screens and authentication options. NOTE: This information, especially around deployment, pertains to LightSwitch Beta 1 and is subject to change at final release.
I have an application that has a couple screens that I can access from the left-hand Tasks menu. The SearchCustomer screen allows me to search customers and enter new ones. When I click on a customer, a detail screen opens. The other screen on the Task menu allows us to edit the Product Catalog.
I want to implement some security permissions in the application that will check if a logged in user can see the product catalog as well as whether the user can add, edit, delete, or just view customers. So the first thing I need to do is define a set of permissions and select how we want the application to authenticate users. The way you do that is open up the Project –> Properties from the main menu and then select the Access Control tab.
There are two steps to security in an application, the first is Authentication -- meaning "The application has verified that you are who you say you are" and the second is Authorization -- meaning "Now that the application knows who you are, here's what you can do in the system".
You can choose between two types of authentication in LightSwitch. You can choose to implement either Windows Authentication or Forms Authentication. Windows Authentication is recommended if all your users are on a windows domain and you want to trust whoever logged into their computer is the same user that is using the application. Meaning you don't have to provide an additional login form. This is handy because you never have to store or manage passwords outside of Windows itself which makes it very secure, however this is usually only practical if the application is running in a corporate/domain Intranet environment. The second option is Forms authentication which means that a username/password is prompted for when the application opens and these values are checked against the database. This works nicely for clients running across the Internet that are not on a Windows domain. I'll show you both but first let's choose Forms Authentication.
Next I need to define the authorization rules or permissions in the grid. You get one built-in permission that controls whether someone can see the security administration screens. You can define your own permissions and check them in code for anything really but typically you define permissions on entities, queries and screens. There are a set of security methods that allow you to define whether a screen can open, and on the entity, whether it can be viewed, edited, deleted, or added across any screen in the system. So let's define one screen permission for our product catalog and then four entity level permissions on customer to control the actions you can do on that entity no matter what the screen.
Notice that there is a checkbox column available on the right of each row that allows you to check off what permissions should be granted while debugging. This makes it easy to test combinations of permissions without having to log into the application. So even if Forms authentication is selected, in debug mode you don’t see a login form. For starters I'm just going to turn on the CanViewCustomerEntity permission to show you how most of the application will be locked down.
Now I need to implement these permissions in code. First I will do this in the product catalog screen, in my case it’s named EditableProductGrid. Open the Screen designer, drop down the Write Code button and notice in the security methods section there’s a CanRunEditableProductGrid.
Select that method and write the following line of code in bold:
Public Class Application
Private Sub CanRunEditableProductGrid(ByRef result As Boolean)
' Write this code to check permission:
result = Me.User.HasPermission(Permissions.CanAccessProductMaintScreen)
Notice that there’s a Permissions class that provides an enumeration of all the permissions we just added. These are strings and come in the form of <ApplicationName>:<PermissionName> so in the case of this permission the string is “OrderManagement:CanAccessProductMaintScreen” because my application is named OrderManagement. I also want to set up some code to only show the Search screen if a user can view the customers in the first place. So in the editor's methods drop down (top right dropdown on the code window) select CanRunSearchCustomer and write the line of code in bold:
Private Sub CanRunSearchCustomer(ByRef result As Boolean) ' Write this code to check permission:
result = Me.User.HasPermission(Permissions.CanViewCustomerEntity)
Now I need to do the same thing for our customer entity. In the Server Explorer double-click the Customers node under Data Sources to open the entity designer and then again under the Write Code button you will see a bunch of security methods; Customers_CanDelete, Customers_CanInsert, Customers_CanRead, Customers_CanUpdate, etc. These methods run on the middle-tier so they are always checked when performing actions on a customer entity no matter what screen is running on the client.
We need to check permissions in all these methods:
Public Class ApplicationDataService
Private Sub Customers_CanDelete(ByRef result As Boolean)
result = Me.Application.User.HasPermission(Permissions.CanDeleteCustomerEntity)
Private Sub Customers_CanInsert(ByRef result As Boolean)
result = Me.Application.User.HasPermission(Permissions.CanAddCustomerEntity)
Private Sub Customers_CanRead(ByRef result As Boolean)
result = Me.Application.User.HasPermission(Permissions.CanViewCustomerEntity)
Private Sub Customers_CanUpdate(ByRef result As Boolean)
result = Me.Application.User.HasPermission(Permissions.CanEditCustomerEntity)
As I mentioned above when entering permissions into the grid on the Access Control tab of the project properties, there is a checkbox column available on the right of each row that allows you to check off what permissions should be granted while debugging. Anything you check will return True from the HasPermission method call. For the first test I only checked off the right to view customer records. Now run the application (hit F5) and see if the application behaves properly. First thing I notice is that there is no Product Catalog screen on the menu, that’s good. The search screen opens OK and I can select a customer and view their details, but I can’t edit any of the fields, they are read-only. Good!
However I have a custom “Add...” button on my search screen and I forgot to add a permission check there.
If I click it, it opens the CustomerDetail screen that allows me to enter values for a new customer entity. Oh no! Do we have a security hole? Actually we don’t. If I enter data into this screen and try to click Save, LightSwitch will prevent me from performing this action. Since entity methods run on the server, our data is safe even if we forget to add a check in the UI.
To disable the button on the search screen I can right-click on the button in the screen designer and edit the CanExecute code to add the permission check.
Private Sub gridAddAndEditNew_CanExecute(ByRef result As Boolean)
' Write your code here.
result = Me.Application.User.HasPermission(Permissions.CanAddCustomerEntity)
You can go back to the Access Control tab on the project properties and enable any combination of permissions for debugging to test out the behavior of your application without having to go through the login process. Once we deploy the application, then we will need to set up roles based on these permissions and assign them to users of our application. You can quickly test out the security screens using 2-tier deployment as explained here: How to: Create a Role-based Application but I’m going to show you another way to quickly publish a 3-tier application to Windows 2008 server.
Before we can deploy a LightSwitch Beta 1 application directly from the development environment we need to set up a few things. If you want to test deployment on Windows 7 right now you need to create the package and install it manually like I showed in my previous post. That post also shows how to set up a website and talks you through application pools. However if you have a Windows 2008 server (or R2) then you can set it up for automatic web deployment directly from the development environment. REMEMBER: There is NO “go live” license for the LightSwitch Beta 1. You can deploy your LightSwitch applications to IIS for testing purposes ONLY.
In order to set up a Windows 2008 Server quickly, use the Web Platform Installer to install everything you need. See Installing LightSwitch Beta 1 Prerequisites section of the Beta 1 deployment guide. Once you have everything installed you need to configure and start the Management Service in IIS manager so that Web Deploy will work for Beta 1.
In IIS Manager select the root node with your server name on the left and then under Management double-click Management Service on the right pane to open the Management Service configuration. Check “Enable remote connections” and then on the right click Start to start the service.
Next you need to make sure the SQL Server that you want to deploy the intrinsic LightSwitch database (which stores the user names, permissions and roles) is available on the network. In this example I’m going to deploy the database to the same machine as the web server components. SQL 2008 Express is installed as part of the prerequisites above, you just need to enable a few things so that you can connect to it from another machine on your network.
Open up SQL Server Configuration Manager and expand the SQL Server Services and start the SQL Server Browser. You may need to right-click and select Properties to set the start mode to something other than Disabled. The SQL Server Browser makes the database instance discoverable on the machine. This allows you to connect via <servername>/<instancename> syntax to SQL Server across a network. Be careful and only enable this when you need to (like during deployment).
Next you need to enable the communication protocols so expand the node to expose the Protocols for SQEXPRESS as well as the Client Protocols and make sure at least Named Pipes is enabled.
Finally, you’ll need to add a user to the database that is in at least the db_creator role in order for remote deploy to work. Here’s how you can set up users in SQL Express. This can be a SQL Server username / password or it can be a windows authenticated user that has access. I’ll walk through the wizard in a second, but be aware that when you remote deploy to the server, the connection string you specify is also used as the connection string for the middle-tier.
So now that we have our web server set up and we’ve coded the permissions and security into the application it’s time to publish and see how to set up the security roles for users. I’m going to publish this as a 3-tier desktop client (out-of-browser Silverlight application). You choose the type of deployment on the Project—> Properties, Application Type tab. To publish you can either right-click on the project in the Solution Explorer and select Publish, or you can select the Build menu --> Publish.
The first screen verifies they type of deployment you want. Click Next. The Publish Output section asks you deployment location details. For this example I’ll select the “Remotely publish to a server now”. In this case you need to enter the service URL to the deployment service. If you didn’t change the port above when you started the Management Service then the URL will be in the form http://<servername>:8172/MsDeploy.axd. The Site/Application will default to the name of the application under the Default Web Site. Specify a valid Username/password to the IIS Management service (admins should have access by default) and click next.
The next screen asks us for a connection string to deploy the database to. This will create our production database on the machine you specify. Note that this connection string is used from Visual Studio LightSwitch to connect and create the intrinsic application database so you need to either specify a SQL username/password that has db_creator permissions (like I show here) or you can use windows authentication. This connection string is also what the middle-tier uses to connect to the database. So if you use windows authentication then be aware that whatever identity your web application is running under will need access to the database as well (I’ll show you how to check that below).
Another thing to note is when you click the ellipsis (…) button next to the connection string on this page the “Test connection” won’t work because the database name doesn’t exist yet. To test the connection, drop down the database name and select one that exists then click the “Test connection” button and it should succeed (if it doesn’t check your database configuration as shown in the previous section above). Then make sure you change the name to a new database name.
I’m going to select Windows authentication to SQL server so that no passwords are stored in the connection string. This means that Visual Studio LightSwitch will connect as my windows identity when creating the database from the wizard here, but the middle-tier will connect as the web application pool identity (we’ll take a look at that in a minute).
Click Next and the Authorization section is displayed. Since we selected Forms Authentication you need to enter the username & password of the user that will first access the application. This person will enter roles and users for the rest of the people who are going to need access to the system. In the case of Forms Authentication this username & encrypted password is stored in the database.
Now click the Publish button and the publish wizard will first build the application, create a web application & folder, copy the application files to the website and then create the database. Publish should succeed. If it doesn’t, check the errors list (from main menu select View –> Errors List) for messages as to what happened.
You may be tempted to test it now but we still have one more step. Let’s see what the publish wizard did. Take a look in IIS manager on the web server and you should see your web application under the Default Web Site. Click on “Basic Settings” under Actions on the right and note the application pool that the publish wizard set up.
Application pools give you isolation between worker processes (so if one web application crashes it can’t take others with it) but they also allow you to run under different identities. This way you can create an application pool that hosts a web application or set of services that run under a specific Windows Identity and you can allow access only to the resources that identity needs to run the application. In the case of a LightSwitch application, that additional resource will be the database. By default the wizard publishes the application under the ASP.NET 4.0 Application pool which is running under a machine account identity. However this identity does not have access to our database. So if you try to run the application now, you will see an error message like “Login failed for user 'IIS APPPOOL\ASP.NET v4.0'”.
There are a couple options here. If you used a SQL Server username/password in the connection string then you would most likely be ready to go (as long as that user had db_owner access to the database). However I specified Windows authentication to the database in the publish wizard above. So in this case, I’m going to create my own application pool called “LightSwitchAppPool” that runs under a least privileged user account called “LightSwitchUser” like I showed here and select that app pool in the Edit Application screen pictured above. Then in SQL Server Management Studio grant this user access to the database and make it a db_owner like I showed here. There’s no need to modify the connection string since we specified Windows authentication in the publish wizard above.
Now we’re ready to rock-and-roll. From any machine on the network, navigate to the website where you published the application (i.e. http://lightswitchsvr/OrderManagement2/) and click on the blue button to install the LightSwitch client application on your desktop. When the application first runs you will see a login screen (because we chose Forms Authentication).
Once you log in, you have access to the Roles and Users screens. First you set up roles and add the specific sets of permissions you want for each role.
Then you can add users and assign them to roles. Permissions in roles are additive and it doesn’t matter which order you add them to users. Meaning if you grant a permission in one role and not in another and you add both roles to a user, then that user will be granted that permission.
When entering users on the screen when Forms Authentication is enabled, you need to specify a password which is stored encrypted in the database. Once you are finished adding Roles and Users you can close the application and log in as another user to see what access the login has to screens and entities.
Okay what about Windows authentication? You now should be familiar with setting up Windows authentication between the middle-tier (web server) and the database but I also now want to authenticate users running the client to also authenticate via Windows and not Forms. This is a more secure option if we are deploying the application on a corporate network (same domain) and easier to manage because we don’t have to worry about storing passwords anymore. There’s no login screen in this case, the application is automatically passed the Windows credentials.
So back over in the LightSwitch development environment open up the project properties again and select the Access Control tab. Now select Use Windows authentication. Start the Publish wizard again by right-clicking on the project in the Solution Explorer and select Publish. The first three screens are going to be the same as before (the only thing I’ll change in this case is the name of the database in the connection string and the web application name both to OrderManagement3 to simulate a new application). The only real difference is the Authentication section. Instead of specifying a username & password you enter the name of the domain account that will be the only user that is allowed access the first time the application is run. This is the user that will set up the rest of the Roles and the Users in the system.
Once this is successfully published we can switch the Application pool on the OrderManagement3 site it created to our LightSwitchAppPool just like before. (Alternatively you could create an empty site on the server first already in the app pool you wanted before you publish). Don’t forget to grant the LightSwitchUser access to the new database (in my case OrderManagement3) and make it a db_owner.
But before we can navigate to the site and install the client application, there is one gotcha with Windows Authentication in IIS 7. When you use a custom user identity as the application pool identity you need to either use the NTLM provider (not Kerberos) or you need to Enable support for Kerberos authentication. Another option is to use the Network Service identity as the app pool’s identity and add that account access to the database instead.
To just use the NTLM provider (which is what I’m going to do) select the web site and select Authentication under the IIS section on the main window of the IIS manager. Select the Windows Authentication (which is now enabled), click “Providers…” under the actions section on the right-hand pane and then remove Negotiate from the list.
Now navigate to the web site and install this application. Notice this time there is no login screen, the application opens and you should see the same Roles and Users screens available. The only difference is this time you don’t have to specify passwords for the domain Users.
As you can see setting up security permissions in a LightSwitch application and checking permissions in code is very easy. You just need to take into consideration how the application will be deployed and what type of Authentication you want to enable. Deploying a 3-tier application is always going to be a little more difficult than a 2-tier application but 3-tier applications allow you to run your applications over a wide area network or internet and make it much easier to deploy to new users once the server is set up, all they have to do is navigate to the web site.
I just completed some videos on Security and Deployment so look for those to show up on the LightSwitch Developer Center soon!
Can't wait for your video tutorials. thanks again
Great Article and I love the video tutorials too. I do have one issue that I have not been able to find a fix for. I am deploying a 3-tier browser application to a Windows 2008 server and I cannot get Windows Authentication to work. Forms authentication works just fine. The error I get after the browser prompts me for credentials is: "401 - Unauthorized: Access is denied due to invalid credentials.
You do not have permission to view this directory or page using the credentials that you supplied."
I have tried your gocha about removing Kerberos but that did not fix the problem. I got a new error about the authentication type not found. I don;t know what to try next. Any help would be apreciated.
this article really helped out a lot! thanks for putting this out there.. if anyone is getting a "wrong password format" message when creating a user please take a look at social.msdn.microsoft.com/.../8674cdc7-72c4-4c0c-b9e1-c4f19c8e06d9 Matt Thallman, diagnosed and provided an solution for it.
How do we create a screen to allow a new user to enter his credentials and start using the app. At present only the Admnistrator can add users.
An administrator has to assign new users into the specific roles & permissions you set up. However we've added an option in our latest builds that let's you allow any windows authnticated user into the system. This prevents you from having to manually add users that should have full access to the application. This will show up in Beta 2 when we release it.
I use Form Autentication and when I try to add users (in debug mode) I get the error: "the password does not meet the password requirements Check the minimum password length and password complexity". What do I do wrong her?
You need to make sure passwords are strong. See: msdn.microsoft.com/.../ms161962.aspx
I have created an application where "Do not enable authentication" is selected. When I run the app on the server it was created on works fine. It's published to a shared network drive and when installed on another computer, it comes up with red exes and it says "Unable to load data. please check your network connection and try again." I'm thinking it may be a permissions issue, but I don't know where.
@Help... Try turning on tracing to see what the exact error message is. Here's an articles that explains some troubleshooting steps: blogs.msdn.com/.../diagnosing-problems-in-a-deployed-lightswitch-application-eric-erhardt.aspx