Walkthrough: Using Authentication Service with Silverlight Navigation Application

[This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.]

In this walkthrough, you learn how to set up your server and client projects in an WCF RIA Services solution to work with an authentication service. When you create a solution with the Silverlight Navigation Application template and enable RIA Services, you can access the ASP.NET Membership framework by adding an authentication service. The authentication service exposes authentication, roles, and profiles from the server project to the client project. You use the authentication service to validate user credentials, restrict access to resources based on roles, and store profile properties.

Ee942451.note(en-us,VS.110).gifNote:
The Silverlight Business Application automatically implements the authentication service. For more information, see Walkthrough: Using Authentication Service with Silverlight Business Application.

This and the other walkthroughs presented in the RIA Services documentation require several prerequisite programs, such as Visual Studio 2010 and the Silverlight Developer Runtime and SDK, be installed and configured properly, in addition to WCF RIA Services and the WCF RIA Services Toolkit. They also require installing and configuring SQL Server 2008 R2 Express with Advanced Services and installing the AdventureWorks OLTP and LT database.

Detailed instructions for the satisfaction of each of these prerequisites are provided by the topics within the Prerequisites for WCF RIA Services node. Follow the instructions provided there before proceeding with this walkthrough to ensure that you encounter as few problems as possible when working through this RIA Services walkthroughs.

To use the authentication service from a Silverlight application, you must configure the authentication on the server project. You configure authentication in the Web.config file. After configuring authentication, you can also configure roles and profiles on the server project, if you want to use those features from the Silverlight application. In this walkthrough, you will configure all three features. Finally, you add an authentication service which exposes the enabled features to the client.

To configure the server project

  1. In Visual Studio 2010, select File, New, and then Project.

    The New Project dialog box appears.

  2. Select the Silverlight project type.

  3. Select the Silverlight Navigation Application template and name the application ExampleNavigationApplication.

  4. Click OK.

    The New Silverlight Application dialog box appears.

  5. Make sure that the Host the Silverlight application in a new Web site check box is selected and that the New Web project type is set to ASP.NET Web Application Project.

  6. Select the Enable WCF RIA Services check box.

  7. Click OK to create the solution.

  8. In the server project (ExampleBusinessApplication.Web), open the Web.config file.

  9. In the <system.web> element, add an <authentication> element and set the mode property to Forms.

  10. In the <system.web> element, add a <roleManager> element and set the enabled property to true.

  11. In the <system.web> element, add a <profile> element, set the enabled property to true, and include a profile property named DefaultRows.

    The completed <system.web> element should include the following elements.

  12. Save the Web.config file.

  13. In the Solution Explorer, right-click the server project, select Add and then New Item.

    The Add New Item dialog box appears.

  14. Select the Authentication Domain Service template and name it AuthenticationDomainService.

    RIA_ServicesAddAuth
  15. Click Add.

  16. Open the authentication service code file (AuthenticationDomainService.cs or AuthenticationDomainService.vb) and add the DefaultRows property that you defined in the Web.config file to the User class.

  17. Build the solution.

In this section, you will use the ASP.NET Web Site Administration Tool to create a user and role. You will login as this user in a later section.

To add users with the ASP.NET Web Site Administration Tool

  1. To open the ASP.NET Web Site Administration Tool, first select the server project in the Solution Explorer.

  2. On the Project menu, select ASP.NET Configuration.

    If you do not see the ASP.NET Configuration option in the Project menu, it may be because you have selected the client project.

    RIA_OpenAdminTool
  3. Select the Security tab in ASP.NET Web Site Administration Tool.

    RIA_WebAdminSecurity
  4. In the Roles section, click the Create or Mange roles link.

  5. Add a new role named Managers and click the Add Role button.

    WebAdmin_CreateRole
  6. In the lower-right corner, click the Back button.

  7. In the Users section, click the Create user link.

  8. Create a new user with the following values and select the Managers role check box.

    User Name: CustomerManager

    Password: P@ssword

    E-mail: someone@example.com

    Security Question: Favorite color?

    Security Answer: Blue

    Managers role: selected

    WebAdmin_CreateUser
  9. Click the Create User button.

  10. Close the ASP.NET Web Site Administration Tool.

You must configure the client project to use the authentication mode that matches the authentication mode you configured in the server project.

To configure the client project

  1. In the client project, open the code-behind file for the App.xaml file (App.xaml.cs or App.xaml.vb).

  2. In the constructor, create a new instance of the WebContext class.

  3. Set the Authentication property to a new instance of the FormsAuthentication class, and add the WebContext instance to the ApplicationLifetimeObjects.

In this section, you will add Silverlight controls that enable the user to provide user name and password for logging in. You will add code that calls the Login method with the user's credentials. You will also set which controls are visible based on whether the user is logged in.

For simplicity, the login user interface is added to the Home page in this walkthrough. In your application, you may want to create a separate login page.

To login and logout a user

  1. In Solution Explorer, expand the Views folder in the client project.

  2. Open the Home.xaml file.

  3. After the TextBlock named ContentText, add the following XAML.

    The XAML includes a TextBox for providing a user name, a PasswordBox for providing a password, a Button for submitting the login request, and a TextBlock and HyperlinkButton for logging out which are only displayed after the user has logged in.

  4. Open the code-behind file for the home page (Home.xaml.cs or Home.xaml.vb).

  5. Add a using or an Imports statement for the System.ServiceModel.DomainServices.Client.ApplicationServices namespace.

  6. Add the following code to the Home class.

    The code includes event handlers for logging in and logging out, callback methods for completed login and logout operations, and a method that set the visibility of controls based on whether the user is authenticated.

  7. Run the solution.

    RS_CustomLoginNav
  8. Log in as CustomerManager with P@ssword for the password.

    Notice that the Login area is no longer displayed, but the welcome text and logout link are now displayed.

    RIA_CustomLoggedInNav
  9. Click Logout link and close Web browser.

The authentication service does not contain an operation to create new users. To register a new user, you create an empty domain service and add an operation for adding a user to the ASP.NET Membership framework.

To configure the server project for adding a new user

  1. In the server project, add a new class file named NewUser.

  2. Define the properties for registering a new user by adding the following code to the NewUser class.

    The ConfirmPassword property in the previous step is defined with a CustomValidationAttribute attribute. In the attribute, it specifies a RegistrationValidator class and a method named IsPasswordConfirmed. You must now define this custom validation class.

  3. Add a new class named RegistrationValidator.shared.cs or RegistrationValidator.shared.vb.

  4. Add the following code to the RegistrationValidator.shared file.

  5. Add a new item to the server project and select the Domain Service Class template.

  6. Name the file RegistrationDomainService.cs or RegistrationDomainService.vb and then click the Add button.

  7. In the Add New Domain Service Class dialog box, select <empty domain service class> from the Available DataContexts/ObjectContexts list.

  8. Click OK.

  9. To create a domain operation that adds a new user through the Membership framework and saves a profile property, add the following code to the RegistrationDomainService class.

    The GetUsers method must be included to ensure that the NewUser entity class is generated for the client project. Only classes that are exposed through a public query operation are generated in the client project.

    After creating the user, the profile property named DefaultRows is set. In this case, the profile property is set as part of the domain operation for creating a user. In a later section, you will add code to set the profile property from the client project.

To configure the client project for adding new users

  1. Open the Home.xaml file.

  2. After the end tag for the LoginBorder Border control, add the following XAML to create a second Border control with input controls to collect information for creating new users.

    The controls accept values for user name, password, password confirmation, e-mail address, security question, security answer, and the number of records to show on reports. The number of records to display will be saved as a profile property. All of the other values are used to create the user through ASP.NET Membership framework.

  3. Open the Home.xaml.cs (or Home.xaml.vb) code-behind file.

  4. Add a using or an Imports statement for the System.ServiceModel.DomainServices.Client, System.ComponentModel.DataAnnotations, and ExampleNavigationApplication.Web namespaces.

  5. Add an event handler for the register button click event and add a callback method for domain operation. The callback method includes code to login the user after successfully creating the user account.

  6. Modify the SetControlVisibility method to set the visibility of RegisterBorder, as shown in the following code.

    The following shows the complete code-behind file.

  7. Run the solution.

    RIA_LoginandRegister
  8. Provide values to register a new user.

  9. Close the Web browser.

You restrict access to a domain operation by applying either the RequiresAuthenticationAttribute attribute or the RequiresRoleAttribute attribute to the domain operation. Domain operations without an attribute are available to all users. Applying an attribute to domain operation does not prevent the user from calling the domain operation; however, users without the required credentials will receive an exception.

To restrict displayed data by roles

  1. In Solution Explorer, select the server project and click the Show All Files button.

  2. Right-click the App_Data folder and select Include in Project.

  3. Right-click the App_Data folder, select Add and then Existing Item.

  4. In the Add Existing Item dialog box, add the AdventureWorksLT sample database.

  5. In the server project, add a new item and select the ADO.NET Entity Data Model template.

  6. Name the model AdventureWorksModel.edmx and click Add.

    The Entity Data Model Wizard appears.

  7. Select the Generate from database option and then click Next.

  8. Select the AdventureWorksLT database and then click Next.

  9. From the list of database objects, select the Customer, Product, and SalesOrderHeader tables, and then click Finish.

    The entity data model appears in the designer.

  10. Build the solution.

  11. In the server project, add a new item and select the Domain Service Class template.

  12. Name the domain service AdventureWorksDomainService and then click Add.

  13. In the Add New Domain Service Class dialog box, select the Customer, Product, and SalesOrderHeader entities.

    RIA_CreateDSForAuth
  14. Click OK to finish creating the domain service.

  15. In the AdventureWorksDomainService class file, add the RequiresAuthenticationAttribute attribute to GetSalesOrderHeader method.

  16. Add the RequiresRoleAttribute attribute to the GetCustomers method, and set the name of the required role to "Managers".

    The GetProducts domain operation is available to any user, GetSalesOrderHeaders is available to authenticated users, and GetCustomers is available to only users in the Managers role.

    The following shows the complete domain service.

Before calling a domain operation with restricted permissions, you should check that the user has the required credentials; otherwise, an exception is thrown. In this section, you will check the user's credentials and populate from one to three DataGrid controls based on the user's credentials. You will also retrieve the number of records based on a property in the user profile. A default value of 10 is used for users that are not authenticated. This section does not include a way for users to set the DefaultRows profile property, but you will add that in a later section.

To add a Silverlight Page for displaying data

  1. In the client project, add a new item to the Views folder.

  2. Select the Silverlight Page template and name the new page Reports.xaml.

  3. Open the MainPage.xaml file and add a link for the Reports page by adding the following XAML after the HyperlinkButton named Link2 that links to the About page.

  4. Open the Reports.xaml file, and add the following XAML inside the Grid tags to match the formatting of the other pages in the site, and to include a HyperlinkButton control that will launch a window for editing a profile property.

  5. Drag three DataGrid controls from the Toolbox to just before the end tag of the stack panel named ContentStackPanel.

    When you drag the DataGrid controls from the Toolbox, a reference to the System.Windows.Controls.Data assembly is added to the project and a prefix for the System.Windows.Controls namespace is added to the page.

  6. Name the DataGrid controls ProductsGrid, SalesOrdersGrid, and CustomersGrid and set Margin to 5.

    The following example shows the complete Reports.xaml file.

  7. Open the Reports.xaml.cs or Reports.xaml.vb file and add using or Imports statements for the System.ServiceModel.DomainServices.Client and ExampleNavigationApplication.Web namespaces.

  8. Create an instance of the AdventureWorksDomainContext named context, and create a variable named numberOfRows that contains the number of rows to retrieve.

  9. Add a method named LoadRestrictedReports that calls the GetSalesOrderHeaderQuery method and the GetCustomersQuery method, if the user belongs to the Managers role, and populates the corresponding data grids with the results.

    If you call a domain operation when the user does not have the required credentials, the domain operation returns an exception. You can avoid this situation by checking the credentials before calling the domain operation.

  10. Add a method named LoadReports that checks whether the user is authenticated and, if so, calls LoadRestrictedReports method. It also retrieves the profile property named DefaultRows and adds an event handler for the PropertyChanged event on the User object. Finally, it calls the GetProductsQuery method for all users.

  11. Add an event handler for the PropertyChanged event that calls LoadReports if the property DefaultRows has changed.

  12. Add the following code to the constructor. This code loads the reports and makes the settings link visible for authenticated users.

  13. Add an event handler for the Click event on the settings link.

    The ProfileWindow will be added in a later step.

    The following shows the complete code file.

You can allow users to edit the DefaultRows profile property by adding child window. When the value is changed, you call the SaveUser method to save the value in the data source. You retrieve the current value through the properties on the User object of the current WebContext instance.

To add a window for setting profile property

  1. In the client project, add a new item to the Views folder.

  2. Select the Silverlight Child Window template and name it ProfileWindow.xaml.

    Add Child Window
  3. Click the Add button.

  4. In the ProfileWindow.xaml file, add the following XAML to include a ComboBox for selecting the number of rows to display in the reports.

  5. In the ProfileWindow.xaml.cs or ProfileWindow.xaml.vb code-behind file, add the following code to retrieve and set the profile property.

  6. Run the solution.

  7. Click the reports link.

    Notice that when the site starts and you are not logged in, only the products table is displayed on the Reports page.

  8. On the Home page, register and log in as a new user.

  9. Click the reports link.

    Notice that the tables for products and sales orders are displayed.

  10. Log out, and log in as CustomerManager.

    Notice that the tables for products, sales orders, and customers are displayed.

  11. Click the Adjust Settings link and set the default number of rows to show for the reports.

    RIA_ShowProfileSettings

    Notice that the DataGrid now contains the number of rows you selected.

  12. Close the Web browser.

Show: