This tutorial shows you how to build a secure ASP.NET 4.5 Web Forms web app that incorporates a SQL Database and deploy the application to Azure.
[WACOM.NOTE] For an MVC version of this tutorial, see Deploy a Secure ASP.NET MVC 5 app with Membership, OAuth, and SQL Database to an Azure Website.
You can open an Azure account for free, and if you don't already have Visual Studio 2013, the SDK automatically installs Visual Studio 2013 for Web Express. You can start developing for Azure for free.
This tutorial assumes that you have no prior experience using Microsoft Azure. Once completing this tutorial, you'll have a web application up and running in the cloud that uses a cloud database.
You'll learn:
- How to create an ASP.NET 4.5 Web Forms project and publish it to an Azure Website.
- How to use OAuth and the ASP.NET membership to secure your application.
- How to use a single database for both membership and application data.
- How to use Web Forms Scaffolding to create web pages that allow you to modify data.
- How to use the new membership API to add users and roles.
- How to use a SQL database to store data in Azure.
You'll build a simple contact list web application that is built on ASP.NET 4.5 Web Forms and uses the Entity Framework for database access. The following image shows the Web Forms page that allows read and write access to the database:
[WACOM.NOTE] To complete this tutorial, you need an Azure account. If you don't have an account, you canactivate your MSDN subscriber benefits or sign up for a free trial.
This tutorial contains the following sections:
- Set up the Development Environment
- Set up the Azure environment
- Create an ASP.NET Web Forms Application
- Add a Database to the Application
- Enable SSL for the Project
- Add an OAuth 2.0 Provider
- Use the Membership API to Restrict Access
- Deploy the Application with the Database to Azure
- Review the Database
- Next Steps
Set up the Development Environment
To start, set up your development environment by installing the Visual Studio 2013 and the Azure SDK for .NET.
- Install Visual Studio 2013, if you don't already have it installed.
- Install Azure SDK for Visual Studio 2013. This tutorial requires Visual Studio 2013 before installing the Azure SDK for Visual Studio 2013.[WACOM.NOTE]
Depending on how many of the SDK dependencies you already have on your machine, installing the SDK could take a long time, from several minutes to a half hour or more. - If you are prompted to run or save the installation executable, click Run.
-
[WACOM.NOTE]
If you already have the SDK installed, there will be 0 items to be installed. The number of items to install will be noted at the lower left of the Web Platform Installer window. - If you don't already have Visual Studio Update 2, download and install Visual Studio 2013 Update 2 or higher.[WACOM.NOTE]
You must install Visual Studio 2013 Update 2 or higher to use Goggle OAuth 2.0 and to use SSL locally without warnings. Also, you need Update 2 to use Web Forms Scaffolding.
When the installation is complete, you have everything necessary to start developing.
Set up the Azure Environment
In this section you'll set up the Azure environment by creating an Azure Website and a SQL database in Azure.
Create a Website and a SQL Database in Azure
In this tutorial your Azure Website will run in a shared hosting environment, which means it runs on virtual machines (VMs) that are shared with other Azure websites. A shared hosting environment is a low-cost way to get started in the cloud. Later, if your web traffic increases, the application can scale to meet the need by running on dedicated VMs. If you need a more complex architecture, you can migrate to an Azure Cloud Service. Cloud services run on dedicated VMs that you can configure according to your needs.
Azure SQL Database is a cloud-based relational database service that is built on SQL Server technologies. The tools and applications that work with SQL Server also work with SQL Database.
- In the Azure Management Portal, click Websites in the left tab, and then click New.
- In the Create Website step of the wizard, enter a string in the URL box to use as the unique URL for your application. The complete URL will consist of what you enter here plus the suffix that you see next to the text box. The illustration shows a URL that is probably taken so you must choose a different URL.
- In the Web Hosting Plan drop-down list, choose a region that is closest to your location. This setting specifies which data center where your VM will run.
- In the Database drop-down list, choose Create a free 20 MB SQL database.
- In the DB Connection String Name box, leave the default value of DefaultConnection.
- Click the arrow at the bottom of the box. The wizard advances to the Specify database settings step.
- In the Name box, enter
ContactDB
. - In the Server box, select New SQL Database server. Alternatively, if you previously created a SQL Server database, you can select that SQL Server from the dropdown control.
- Set the Region to the same area you created the Website.
- Enter an administrator Login Name and Password. If you selected New SQL Database server you aren't entering an existing name and password here, you're entering a new name and password that you're defining now to use later when you access the database. If you selected a SQL Server you've created previously, you'll be prompted for the password to the previous SQL Server account name you created. For this tutorial, you won't check theAdvanced box.
- Click the check mark at the bottom right of the box to indicate you're finished.
The Azure Management Portal returns to the Websites page, and the Status column shows that the site is being created. Shortly after (typically less than a minute), the Status column shows that the site was successfully created. In the navigation bar at the left, the number of sites you have in your account appears next to the Websites icon, and the number of databases appears next to the SQL Databases icon.
Create an ASP.NET Web Forms Application
You have created an Azure Website, but there is no content in it yet. Your next step is to create the Visual Studio web app that you'll publish to Azure.
Create the Project
- Select New Project from the File menu in Visual Studio.
- Select the Templates -> Visual C# -> Web templates group on the left.
- Choose the ASP.NET Web Application template in the center column.
-
[WACOM.NOTE]
The name of the project in this tutorial series is ContactManager. It is recommended that you use this exact project name so that the code provided throughout the tutorial series functions as expected. - In the New ASP.NET Project dialog box, select the Web Forms template. Uncheck the Host in the cloud check box if it is selected and click OK.
The Web Forms application will be created.In ASP.NET Web Forms, master pages allow you to create a consistent layout for the pages in your application. A single master page defines the look and feel and standard behavior that you want for all of the pages (or a group of pages) in your application. You can then create individual content pages that contain the content you want to display. When users request the content pages, ASP.NET merges them with the master page to produce output that combines the layout of the master page with the content from the content page. The new site needs the application name and a link updated. The link will point to a page that will display contact details. To make these changes you will modify the HTML on the master page. - In Solution Explorer, find and open the Site.Master page.
- If the page is in Design view, switch to Source view.
- Update the master page by modifying or adding the markup highlighted in yellow:
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="ContactManager.SiteMaster" %> <!DOCTYPE html> <html lang="en"> <head runat="server"> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title><%: Page.Title %> - Contact Manager</title> <asp:PlaceHolder runat="server"> <%: Scripts.Render("~/bundles/modernizr") %> </asp:PlaceHolder> <webopt:bundlereference runat="server" path="~/Content/css" /> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> </head> <body> <form runat="server"> <asp:ScriptManager runat="server"> <Scripts> <%--To learn more about bundling scripts in ScriptManager see http://go.microsoft.com/fwlink/?LinkID=301884 --%> <%--Framework Scripts--%> <asp:ScriptReference Name="MsAjaxBundle" /> <asp:ScriptReference Name="jquery" /> <asp:ScriptReference Name="bootstrap" /> <asp:ScriptReference Name="respond" /> <asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebForms.js" /> <asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebUIValidation.js" /> <asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Scripts/WebForms/MenuStandards.js" /> <asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Scripts/WebForms/GridView.js" /> <asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Scripts/WebForms/DetailsView.js" /> <asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Scripts/WebForms/TreeView.js" /> <asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebParts.js" /> <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" /> <asp:ScriptReference Name="WebFormsBundle" /> <%--Site Scripts--%> </Scripts> </asp:ScriptManager> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" runat="server" id="ContactDemoLink" href="~/Contacts/Default.aspx">Contact Demo</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a runat="server" href="~/">Home</a></li> <li><a runat="server" href="~/About">About</a></li> <li><a runat="server" href="~/Contact">Contact</a></li> </ul> <asp:LoginView runat="server" ViewStateMode="Disabled"> <AnonymousTemplate> <ul class="nav navbar-nav navbar-right"> <li><a runat="server" href="~/Account/Register">Register</a></li> <li><a runat="server" href="~/Account/Login">Log in</a></li> </ul> </AnonymousTemplate> <LoggedInTemplate> <ul class="nav navbar-nav navbar-right"> <li><a runat="server" href="~/Account/Manage" title="Manage your account">Hello, <%: Context.User.Identity.GetUserName() %> !</a></li> <li> <asp:LoginStatus runat="server" LogoutAction="Redirect" LogoutText="Log off" LogoutPageUrl="~/" OnLoggingOut="Unnamed_LoggingOut" /> </li> </ul> </LoggedInTemplate> </asp:LoginView> </div> </div> </div> <div class="container body-content"> <asp:ContentPlaceHolder ID="MainContent" runat="server"> </asp:ContentPlaceHolder> <hr /> <footer> <p>© <%: DateTime.Now.Year %> - Contact Manager</p> </footer> </div> </form> </body> </html>
Later in this tutorial you will add Web Forms scaffolding. Scaffolding will create the page that the above “Contact Demo” link references.
Run the Application Locally
- In Solution Explorer, right-click the Default.aspx page and select Set As Start Page.
- Next, press CTRL+F5 to run the application.
The application default page appears in the default browser window.
This is all you need to do for now to create the application that you'll deploy to Azure. Later, you'll add database functionality, as well as the necessary pages to display and edit contact data.
Deploy the Application to Azure
Now that you have created and ran your application locally, it is time to deploy the application to Azure.
- If you are not already signed in, click the Sign In button in the Select Existing Website dialog box. Once you've finished signing in, select the website you created in the first part of this tutorial. Click OK to continue.
Visual Studio will download your publishing settings. - In the Publish Web dialog box, click Publish.
You will see the overall publishing status in the Web Publish Activity window within Visual Studio:
The application you created is now running in the cloud. The next time you deploy the application from Visual Studio, only the changed (or new) files will be deployed.
[WACOM.NOTE] If you run into an error while publishing to an already established Website, you can clear the location before adding your new files.
Publish your application again, however in the Publish Web dialog box, select the Settings tab. Then, set the configuration to Debug and select the option to Remove additional files at destination. Select Publish to deploy your application again.
Add a Database to the Application
Next, you'll update the Web Forms application to add the capability to display and update contacts, as well as store the data in the default database. When you created the Web Forms project, the database was also created by default. The application will use Entity Framework to access the database and to read and update data in the database.
Add a Data Model Class
You begin by creating a simple data model using code. This data model will be contained in a class called
Contacts
. TheContacts
class name was chosen to avoid a class name conflict with the Contact
class contained in the Contact.aspx.cs file created by the Web Forms template.- Replace the default code with the following code:
using System.ComponentModel.DataAnnotations; using System.Globalization; namespace ContactManager.Models { public class Contacts { [ScaffoldColumn(false)] [Key] public int ContactId { get; set; } public string Name { get; set; } public string Address { get; set; } public string City { get; set; } public string State { get; set; } public string Zip { get; set; } [DataType(DataType.EmailAddress)] public string Email { get; set; } } }
The Contacts class defines the data that you will store for each contact, plus a primary key (
ContactID
) that is needed by the database. The Contacts class represents the contact data that will be displayed. Each instance of a Contacts object will correspond to a row within a relational database table, and each property of the Contacts class will map to a column in the relational database table. Later in this tutorial, you'll review the contact data contained in the database.Web Forms Scaffolding
You've created the Contacts model class above. Now, you can use the Web Forms Scaffolder to generate List, Insert,Edit and Delete pages that are used when working with this data. The Web Forms Scaffolder uses Entity Framework, Bootstrap, and Dynamic Data. By default, the Web Forms Scaffolder is installed as an extension to your project as part of the project template when using Visual Studio 2013.
The following steps will allow you to use the Web Forms Scaffolder.
- In Visual Studio, from the menu bar select Tools -> Extensions and Updates.
The Extensions and Updates dialog box is displayed. - From the left pane of the dialog box, select Online -> Visual Studio Gallery -> Tools -> Scaffolding.
- If you don't see 'Web Forms Scaffolding' in the list, enter 'Web Forms Scaffolding' in the search box on the right of the dialog box.
- If the Web Forms Scaffolder is not already installed, select Download to download and install 'Web Forms Scaffolding'. Restart Visual Studio if needed. Be sure to save your changes to the project when requested.
- Build the project (Ctrl+Shift+B).
You must build the project before using the scaffolding mechanism. - In Solution Explorer, right-click the project and then select Add -> New Scaffolded Item.
The Add Scaffold dialog box is displayed.
The Web Forms Scaffolder adds a new folder that contains Default.aspx, Delete.aspx, Edit.aspx, and Insert.aspx pages. The Web Forms Scaffolder also creates a DynamicData folder that contains an EntityTemplates folder and aFieldTemplates folder. The
ApplicationDbContext
will be used for both the membership database and the contact data.Configure the Application to Use the Data Model
The next task is to enable the Code First Migrations feature in order to create the database based on the data model you created. Also, you will add sample data and a data initializer.
- In the Tools menu, select NuGet Package Manager and then Package Manager Console.
- In the Package Manager Console window, enter the following command:
enable-migrations
The enable-migrations command creates a Migrations folder, and it puts in that folder a Configuration.cs file that you can edit to seed the database and configure data migrations. - In the Package Manager Console window, enter the following command:
add-migration Initial
Theadd-migration Initial
command generates a file named Initial in the Migrations folder that creates the database. The first parameter ( Initial ) is arbitrary and is used to create the name of the file. You can see the new class files in Solution Explorer. In theInitial
class, theUp
method creates theContact
table, and theDown
method (used when you want to return to the previous state) drops it. - Open the Migrations\Configuration.cs file.
- Add the following namespace:
using ContactManager.Models;
- Replace the
Seed
method with the following code:protected override void Seed(ContactManager.Models.ApplicationDbContext context) { context.Contacts.AddOrUpdate(p => p.Name, new Contacts { ContactId = 1, Name = "Ivan Irons", Address = "One Microsoft Way", City = "Redmond", State = "WA", Zip = "10999", Email = "ivani@wideworldimporters.com", }, new Contacts { ContactId = 2, Name = "Brent Scholl", Address = "5678 1st Ave W", City = "Redmond", State = "WA", Zip = "10999", Email = "brents@wideworldimporters.com", }, new Contacts { ContactId = 3, Name = "Terrell Bettis", Address = "9012 State St", City = "Redmond", State = "WA", Zip = "10999", Email = "terrellb@wideworldimporters.com", }, new Contacts { ContactId = 4, Name = "Jo Cooper", Address = "3456 Maple St", City = "Redmond", State = "WA", Zip = "10999", Email = "joc@wideworldimporters.com", }, new Contacts { ContactId = 5, Name = "Ines Burnett", Address = "7890 2nd Ave E", City = "Redmond", State = "WA", Zip = "10999", Email = "inesb@wideworldimporters.com", } ); }
This code initializes (seeds) the database with the contact information. For more information on seeding the database, see Seeding and Debugging Entity Framework (EF) DBs. - In the Package Manager Console enter the command:
update-database
Theupdate-database
runs the first migration which creates the database. By default, the database is created as a SQL Server Express LocalDB database.
Run the Application Locally and Display the Data
Run the application now to see how you can view the contacts.
- First, build the project (Ctrl+Shift+B).
- Press Ctrl+F5 to run the application.
The browser will open and show the Default.aspx page. - Select the Contact Demo link at the top of the page to display the Contact List page.
Enable SSL for the Project
Secure Sockets Layer (SSL) is a protocol defined to allow Web servers and Web clients to communicate more securely through the use of encryption. When SSL is not used, data sent between the client and server is open to packet sniffing by anyone with physical access to the network. Additionally, several common authentication schemes are not secure over plain HTTP. In particular, Basic authentication and forms authentication send unencrypted credentials. To be secure, these authentication schemes must use SSL.
- In Solution Explorer, click the ContactManager project, then press F4 to display the Properties window.
- Change SSL Enabled to
true
. - Copy the SSL URL so you can use it later.
The SSL URL will behttps://localhost:44300/
unless you've previously created SSL Websites (as shown below). - In Solution Explorer, right click the Contact Manager project and click Properties.
- In the left tab, click Web.
- Change the Project Url to use the SSL URL that you saved earlier.
- Save the page by pressing CTRL+S.
- Press Ctrl+F5 to run the application.
Visual Studio will display an option to allow you to avoid SSL warnings.
You can easily test your Web application locally using SSL.
Add an OAuth 2.0 Provider
ASP.NET Web Forms provides enhanced options for membership and authentication. These enhancements include OAuth. OAuth is an open protocol that allows secure authorization in a simple and standard method from web, mobile, and desktop applications. The ASP.NET MVC internet template uses OAuth to expose Facebook, Twitter, Google and Microsoft as authentication providers. Although this tutorial uses only Google as the authentication provider, you can easily modify the code to use any of the providers. The steps to implement other providers are very similar to the steps you will see in this tutorial.
In addition to authentication, the tutorial will also use roles to implement authorization. Only those users you add to the
canEdit
role will be able to change data (create, edit, or delete contacts).
The following steps will allow you to add a Google authentication provider.
- Open the App_Start\Startup.Auth.cs file.
- Remove the comment characters from the
app.UseGoogleAuthentication()
method so that the method appears as follows:app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() { ClientId = "", ClientSecret = "" });
- Navigate to the Google Developers Console. You will also need to sign-in with your Google developer email account (gmail.com). If you do not have a Google account, select the Create an account link.
Next, you'll see the Google Developers Console. - In the left tab, click APIs & auth, and then click Credentials.
- Click the Create New Client ID under OAuth.
The Create Client ID dialog will be displayed. - In the Create Client ID dialog, keep the default Web application for the application type.
- Set the Authorized JavaScript Origins to the SSL URL you used earlier in this tutorial (https://localhost:44300/unless you've created other SSL projects).
This URL is the origin for your application. For this sample, you will only enter the localhost test URL. However, you can enter multiple URL to account for localhost and production. - Set the Authorized Redirect URI to the following:
https://localhost:44300/signin-google
This value is the URI that ASP.NET OAuth users to communicate with the google OAuth server. Remember to the SSL URL you used above (https://localhost:44300/ unless you've created other SSL projects). - Click the Create Client ID button.
- In Visual Studio, update the
UseGoogleAuthentication
method of the Startup.Auth.cs page by copying and pasting the AppId and App Secret into the method. The AppId and App Secret values shown below are samples and will not work.using System; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.DataProtection; using Microsoft.Owin.Security.Google; using Owin; using ContactManager.Models; namespace ContactManager { public partial class Startup { // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301883 public void ConfigureAuth(IAppBuilder app) { // Configure the db context and user manager to use a single instance per request app.CreatePerOwinContext(ApplicationDbContext.Create); app.CreatePerOwinContext(ApplicationUserManager.Create); // Enable the application to use a cookie to store information for the signed in user // and to use a cookie to temporarily store information about a user logging in with a third party login provider // Configure the sign in cookie app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login"), Provider = new CookieAuthenticationProvider { OnValidateIdentity = SecurityStampValidator.OnValidateIdentity( validateInterval: TimeSpan.FromMinutes(20), regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) } }); // Use a cookie to temporarily store information about a user logging in with a third party login provider app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); // Uncomment the following lines to enable logging in with third party login providers //app.UseMicrosoftAccountAuthentication( // clientId: "", // clientSecret: ""); //app.UseTwitterAuthentication( // consumerKey: "", // consumerSecret: ""); //app.UseFacebookAuthentication( // appId: "", // appSecret: ""); app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() { ClientId = "000000000000.apps.googleusercontent.com", ClientSecret = "00000000000" }); } } }
- Press CTRL+F5 to build and run the application. Click the Log in link.
- Under Use another service to log in, click Google.
- If you need to enter your credentials, you will be redirected to the google site where you will enter your credentials.
- After you enter your credentials, you will be prompted to give permissions to the web application you just created:
- Click Accept. You will now be redirected back to the Register page of the ContactManager application where you can register your Google account.
- You have the option of changing the local email registration name used for your Gmail account, but you generally want to keep the default email alias (that is, the one you used for authentication). Click Log in.
Use the Membership API to Restrict Access
ASP.NET Identity is the membership system used for authentication when building an ASP.NET web application. It makes it easy to integrate user-specific profile data with application data. Also, ASP.NET Identity allows you to choose the persistence model for user profiles in your application. You can store the data in a SQL Server database or another data store, including NoSQL data stores such as Azure Storage Tables.
By using the default ASP.NET Web Forms template, you have built-in membership functionality that you can immediately use when the application runs. You will use ASP.NET Identity to add an administrator role and assign a user to that role. Then, you will learn how to restrict access to the administration folder and the pages in that folder that are used to modify the contact data.
Add an Administrator
Using ASP.NET Identity, you can add an administrator role and assign a user to that role using code.
- In Solution Explorer, open the Configuration.cs file in the Migrations folder.
- Add the following
using
statements within theContactManger.Migrations
namespace:using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework;
- Add the following
AddUserAndRole
method to theConfiguration
class after theSeed
method:public void AddUserAndRole(ContactManager.Models.ApplicationDbContext context) { IdentityResult IdRoleResult; IdentityResult IdUserResult; var roleStore = new RoleStore<IdentityRole>(context); var roleMgr = new RoleManager<IdentityRole>(roleStore); if (!roleMgr.RoleExists("canEdit")) { IdRoleResult = roleMgr.Create(new IdentityRole { Name = "canEdit" }); } //var userStore = new UserStore<ApplicationUser>(context); //var userMgr = new UserManager<ApplicationUser>(userStore); var userMgr = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context)); var appUser = new ApplicationUser { UserName = "canEditUser@wideworldimporters.com", Email = "canEditUser@wideworldimporters.com" }; IdUserResult = userMgr.Create(appUser, "Pa$$word1"); if (!userMgr.IsInRole(userMgr.FindByEmail("canEditUser@wideworldimporters.com").Id, "canEdit")) { // IdUserResult = userMgr.AddToRole(appUser.Id, "canEdit"); IdUserResult = userMgr.AddToRole(userMgr.FindByEmail("canEditUser@wideworldimporters.com").Id, "canEdit"); } }
- Add a call to the
AddUserAndRole
method from within the beginning of theSeed
method. Note that only the beginning of theSeed
method is being shown.protected override void Seed(ContactManager.Models.ApplicationDbContext context) { AddUserAndRole(context);
- After saving all your changes, in the Package Manager Console run the following command:
Update-Database
This code creates a new role calledcanEdit
and creates a new local user with the email ofcanEditUser@wideworldimporters.com. Then, the code adds canEditUser@wideworldimporters.com to thecanEdit
role. For more information, see the ASP.NET Identity resource page.
Restrict Access to the Administration Folder
The ContactManager sample application allows both anonymous users and logged-in users to view contacts. However, after you complete this section, the logged-in users that are assigned to the "canEdit" role will be the only users able to modify the contacts.
You will create a folder named Admin where only users that are assigned to the "canEdit" role can access.
- In Solution Explorer, add a sub-folder to the Contacts folder and name the new sub-folder Admin.
- Move the following files from the Contacts folder to the Contacts/Admin folder:
- Delete.aspx *and Delete.aspx.cs*
- Edit.aspx *and Edit.aspx.cs*
- Insert.aspx *and Insert.aspx.cs*
- Update the link references in Contacts/Default.aspx by adding "Admin/" before the pages references that link toInsert.aspx, Edit.aspx, and Delete.aspx:
<%@ Page Title="ContactsList" Language="C#" MasterPageFile="~/Site.Master" CodeBehind="Default.aspx.cs" Inherits="ContactManager.Contacts.Default" ViewStateMode="Disabled" %> <%@ Register TagPrefix="FriendlyUrls" Namespace="Microsoft.AspNet.FriendlyUrls" %> <asp:Content runat="server" ContentPlaceHolderID="MainContent"> <h2>Contacts List</h2> <p> <asp:HyperLink runat="server" NavigateUrl="Admin/Insert.aspx" Text="Create new" /> </p> <div> <asp:ListView runat="server" DataKeyNames="ContactId" ItemType="ContactManager.Models.Contacts" AutoGenerateColumns="false" AllowPaging="true" AllowSorting="true" SelectMethod="GetData"> <EmptyDataTemplate> There are no entries found for Contacts </EmptyDataTemplate> <LayoutTemplate> <table class="table"> <thead> <tr> <th>Name</th> <th>Address</th> <th>City</th> <th>State</th> <th>Zip</th> <th>Email</th> <th> </th> </tr> </thead> <tbody> <tr runat="server" id="itemPlaceholder" /> </tbody> </table> </LayoutTemplate> <ItemTemplate> <tr> <td> <asp:DynamicControl runat="server" DataField="Name" ID="Name" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="Address" ID="Address" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="City" ID="City" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="State" ID="State" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="Zip" ID="Zip" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="Email" ID="Email" Mode="ReadOnly" /> </td> <td> <a href="Admin/Edit.aspx?ContactId=<%#: Item.ContactId%>">Edit</a> | <a href="Admin/Delete.aspx?ContactId=<%#: Item.ContactId%>">Delete</a> </td> </tr> </ItemTemplate> </asp:ListView> </div> </asp:Content>
- Update the six references of the
Response.Redirect("Default.aspx")
code toResponse.Redirect("~/Contacts/Default.aspx")
for the following three files:- Delete.aspx.cs
- Edit.aspx.cs
- Insert.aspx.cs
Now the links will all work correctly when you display and update the contact data. - To restrict access to the Admin folder, from the Solution Explorer right-click the Admin folder and select Add New Item.
- From the list of Visual C# Web templates, select Web Configuration File from the middle list, accept the default name of Web.config, and then select Add.
- Replace the existing XML content in the Web.config file with the following:
<?xml version="1.0"?> <configuration> <system.web> <authorization> <allow roles="canEdit"/> <deny users="*"/> </authorization> </system.web> </configuration>
- Save the Web.config file. The Web.config file specifies that only users assigned to the "canEdit" role can access the pages contained in the Admin folder.
When a user that is not part of the "canEdit" role attempts to modify the data, they will be redirected to the Log in page.
Deploy the Application with the Database to Azure
Now that the web application is complete, you can publish it to Azure.
Publish the Application
- In Visual Studio, build the project (Ctrl+Shift+B).
- Right-click the project in Solution Explorer and select Publish.
The Publish Web dialog box is displayed. - From the Profile tab, select Azure Websites as the publish target if it is not already selected.
- Click Sign In if you are not already signed in.
- Select the existing website that you created earlier in this tutorial from the Existing Websites dropdown box and click the OK button.
If you are asked to save changes make to the profile, select Yes. - Click the Settings tab.
- Set the Configuration dropdown box to Debug.
- Click the down arrow icon next to ApplicationDbContext and set it to ContactDB.
- Check the Execute Code First Migrations checkbox.[WACOM.NOTE]
In this example, you should select this checkbox only the first time you publish the application. This way, theSeed method in the Configuration.cs file will only be called once. - Then, click Publish.
Your application will be published to Azure.
[WACOM.NOTE]
If you closed and re-opened Visual Studio after you created the publish profile, you might not see the connection string in the drop-down list. In that case, instead of editing the publish profile that you created earlier, create a new one the same way you did earlier, and then follow these steps on the Settings tab.)
Review the Application in Azure
- Select the Log off link.
Stop the Application
In order to prevent other people from registering and using your sample application, you will stop the website.
- In Visual Studio from the View Menu, select Server Explorer.
- In Server Explorer, navigate to Websites.
Review the Database
It is important to know how to view and modify the database directly. Knowing how to work directly with the database allows you to confirm data in the database and also understand how the data is stored in each table.
Examine the SQL Azure DB
- In Visual Studio, open Server Explorer and navigate to ContactDB.
- Right-click on ContactDB and select Open in SQL Server Object Explorer.
- If the Add Firewall Rule dialog box is displayed, select Add Firewall Rule.[WACOM.NOTE]
If you can't expand SQL Databases and can't see ContactDB from Visual Studio, you can follow the instructions to open a firewall port or a range of ports. To do this, follow the instructions under Set up Azure firewall rules near the end of the MVC tutorial. As an alternative, you can also review the data of the local database by building, running, and adding data to the application locally (CTRL+F5 from Visual Studio). - If the Connect to Server dialog box is displayed, enter the password you created at the beginning of this tutorial and press the Connect button.[WACOM.NOTE]
If you don't recall the password, you can find it in your local project file. In Solution Explorer, expand theProperties folder and then expand the PublishProfiles folder. Open the contactmanager.pubxml file (your file may be named differently). Search the file for your publishing password. - Expand the contactDB database and then expand Tables.
- Right-click the dbo.AspNetUsers table and select View Data.
You can view the data associated with the canEditUser@contoso.com user.
Add a User to the Admin Role by Editing the Database
Earlier in the tutorial you used code to add users to the canEdit role. An alternative method is to directly manipulate the data in the membership tables. The following steps show how to use this alternate method to add a user to a role.
- In SQL Server Object Explorer, right click on dbo.AspNetUserRoles and select View Data.
- Copy the RoleId and paste it into the empty (new) row.
- In the dbo.AspNetUsers table, find the user you want to put in the role, and copy the user's Id.
- Paste the copied Id into the UserId field of the new row in the AspNetUserRoles table.
[WACOM.NOTE]
We are working on a tool that will make managing users and roles much easier.
Next steps
For more information about ASP.NET Web Forms, see Learn About ASP.NET Web Forms on the ASP.NET website andMicrosoft Azure Tutorials and Guides.
This tutorial was based on the MVC tutorial Deploy a Secure ASP.NET MVC 5 app with Membership, OAuth, and SQL Database to an Azure Web Site written by Rick Anderson (Twitter @RickAndMSFT) with assistance from Tom Dykstra and Barry Dorrans (Twitter @blowdart).
Please leave feedback about what you liked and what you would like to see improved, not only about the tutorial itself but also about the products that it demonstrates. Your feedback will help us prioritize improvements. You can also request and vote on new topics at Show Me How With Code.
No comments:
Post a Comment