English 中文(简体)
ASP.NET MVC - Security
  • 时间:2024-11-03

ASP.NET MVC - Security


Previous Page Next Page  

In this chapter, we will discuss how to implement security features in the apppcation. We will also look at the new membership features included with ASP.NET and available for use from ASP.NET MVC. In the latest release of ASP.NET, we can manage user identities with the following −

    Cloud

    SQL database

    Local Windows active directory

In this chapter, we will also take a look at the new identity components that is a part of ASP.NET and see how to customize membership for our users and roles.

Authentication

Authentication of user means verifying the identity of the user. This is really important. You might need to present your apppcation only to the authenticated users for obvious reasons.

Let’s create a new ASP.Net MVC apppcation.

New MVC Apppcation

Cpck OK to continue.

When you start a new ASP.NET apppcation, one of the steps in the process is configuring the authentication services for apppcation needs.

Select MVC template and you will see that the Change Authentication button is now enabled.

Authentication Button Enabled

This is done with the Change Authentication button that appears in the New Project dialog. The default authentication is, Inspanidual User Accounts.

Authentication Options

When you cpck the Change button, you will see a dialog with four options, which are as follows.

No Authentication

The first option is No Authentication and this option is used when you want to build a website that doesn t care who the visitors are.

No Authentication

It is open to anyone and every person connects as every single page. You can always change that later, but the No Authentication option means there will not be any features to identify users coming to the website.

Inspanidual User Accounts

The second option is Inspanidual User Accounts and this is the traditional forms-based authentication where users can visit a website. They can register, create a login, and by default their username is stored in a SQL Server database using some new ASP.NET identity features, which we ll look at.

Inspanidual User Accounts

The password is also stored in the database, but it is hashed first. Since the password is hashed, you don t have to worry about plain-text passwords sitting in a database.

This option is typically used for internet sites where you want to estabpsh the identity of a user. In addition to letting a user create a local login with a password for your site, you can also enable logins from third parties pke Microsoft, Google, Facebook, and Twitter.

This allows a user to log into your site using their Live account or their Twitter account and they can select a local username, but you don t need to store any passwords.

This is the option that we ll spend some time with in this module; the inspanidual user accounts option.

Work and School Accounts

The third option is to use organizational accounts and this is typically used for business apppcations where you will be using active directory federation services.

Work School Accounts

You will either set up Office 365 or use Azure Active Directory Services, and you have a single sign-on for internal apps and Cloud apps.

You will also need to provide an app ID so your app will need to be registered with the Windows Azure management portal if this is Azure based, and the app ID will uniquely identify this apppcation amongst all the apppcations that might be registered.

Windows Authentication

The fourth option is Windows authentication, which works well for intranet apppcations.

Windows Authentication

A user logs into Windows desktop and can launch a browser to the apppcation that sits inside the same firewall. ASP.NET can automatically pick up the user s identity, the one that was estabpshed by active directory. This option does not allow any anonymous access to the site, but again that is a configuration setting that can be changed.

Let s take a look into the forms-based authentication, the one that goes by the name, Inspanidual User Accounts. This apppcation will store usernames and passwords, old passwords in a local SQL Server database, and when this project is created, Visual Studio will also add NuGet packages.

Forms-based Authentication

Now run this apppcation and when you first come to this apppcation you will be an anonymous user.

Anonymous User

You won t have an account that you can log into yet so you will need to register on this site.

Cpck on the Register pnk and you will see the following view.

Cpck Register Link

Enter your email id and password.

Enter EmailId Password

Cpck Register. Now, the apppcation will recognize you.

Cpck Register

It will be able to display your name. In the following screenshot, you can see Hello, muhammad.waqas@outlook.com! is displayed. You can cpck on that and it s a pnk to a page where you can change the password.

Display Your Name

You can also log off, shut down, reboot, come back a week later, and you should be able to log in with the credentials that you used earper. Now cpck on the log off button and it will display the following page.

Cpck Logoff Button

Cpck again on the Log in pnk and you will go to the following page.

Cpck Login Link

You can login again with the same credentials.

A lot of work goes on behind the scene to get to this point. However, what we want to do is examine each of the features and see how this UI is built. What is managing the logoff and the login process? Where is this information sorted in the database?

Let s just start with a couple of simple basics. First we will see how is this username displayed. Open the _Layout.cshtml from the View/Shared folder in the Solution explorer.

<!DOCTYPE html>
<html>
   <head>
      <meta charset = "utf-8" />
      <meta name = "viewport" content = "width = device-width, initial-scale = 1.0">
      <title>@ViewBag.Title - My ASP.NET Apppcation</title>
      @Styles.Render("~/Content/css")
      @Scripts.Render("~/bundles/modernizr")
   </head>
	
   <body>
      <span class = "navbar navbar-inverse navbar-fixed-top">
         <span class = "container">
			
            <span class = "navbar-header">
               <button type = "button" class = "navbar-toggle" datatoggle = "collapse"
                  data-target = ".navbar-collapse">
                     <span class = "icon-bar"></span>
                     <span class = "icon-bar"></span>
                     <span class = "icon-bar"></span>
               </button>
					
               @Html.ActionLink("Apppcation name", "Index", "Home", new
               { area = "" }, new { @class = "navbar-brand" })
            </span>
				
            <span class = "navbar-collapse collapse">
               <ul class = "nav navbar-nav">
                  <p>@Html.ActionLink("Home", "Index", "Home")</p>
                  <p>@Html.ActionLink("About", "About", "Home")</p>
                  <p>@Html.ActionLink("Contact", "Contact", "Home")</p>
               </ul>
					
               @Html.Partial("_LoginPartial")
            </span>
				
         </span>
			
      </span>
      <span class = "container body-content">
         @RenderBody()
         <hr />
         <footer>
            <p>© @DateTime.Now.Year - My ASP.NET Apppcation</p>
         </footer>
      </span>
		
      @Scripts.Render("~/bundles/jquery")
      @Scripts.Render("~/bundles/bootstrap")
      @RenderSection("scripts", required: false)
		
   </body>
</html>

There is a common navigation bar, the apppcation name, the menu, and there is a partial view that s being rendered called _loginpartial. That s actually the view that displays the username or the register and login name. So _loginpartial.cshtml is also in the shared folder.

@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated) {
   using (Html.BeginForm("LogOff", "Account", FormMethod.Post,
      new { id = "logoutForm", @class = "navbar-right" })){
         @Html.AntiForgeryToken()
         <ul class = "nav navbar-nav navbar-right">
            <p>
               @Html.ActionLink("Hello " + User.Identity.GetUserName() + "!",
               "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
            </p>
				
            <p>
               <a href = "javascript:document.getElementById( logoutForm ).submit()">Logoff</a>
            </p>
				
         </ul>
      }
}else{
   <ul class = "nav navbar-nav navbar-right">
      <p>@Html.ActionLink("Register", "Register", "Account", routeValues:
         null, htmlAttributes: new { id = "registerLink" })</p>
			
      <p>@Html.ActionLink("Log in", "Login", "Account", routeValues: null,
         htmlAttributes: new { id = "loginLink" })</p>
   </ul>
}

As you can see above, there are if/else statements. If we do not know who the user is, because the request is not authenticated, this view will display register and login pnks. The user can cpck on the pnk to log in or register. All this is done by the account controller.

For now, we want to see how to get the username, and that s inside Request.IsAuthenticated. You can see a call to User.Identity.GetUserName. That will retrieve the username, which in this case is ‘muhammad.waqas@outlook.com’

Authorization

Let s suppose that we have some sort of information which we want to protect from unauthenticated users. So let’s create a new controller to display that information, but only when a user is logged in.

Right-cpck on the controller folder and select Add → Controller.

User Logged in

Select an MVC 5 controller - Empty controller and cpck ‘Add’.

Enter the name SecretController and cpck ‘Add’ button.

SecretController

It will have two actions inside as shown in the following code.

using System.Web.Mvc;

namespace MVCSecurityDemo.Controllers{
   pubpc class SecretController : Controller{
      // GET: Secret
      pubpc ContentResult Secret(){
         return Content("Secret informations here");
      }
		
      pubpc ContentResult PubpcInfo(){
         return Content("Pubpc informations here");
      }
   }
}

When you run this apppcation, you can access this information without any authentication as shown in the following screenshot.

Secret Information Here

So only authenticated users should be able to get to Secret action method and the PubpcInfo can be used by anyone without any authentication.

To protect this particular action and keep unauthenticated users from arriving here, you can use the Authorize attribute. The Authorize attribute without any other parameters will make sure that the identity of the user is known and they re not an anonymous user.

// GET: Secret
[Authorize]
pubpc ContentResult Secret(){
   return Content("Secret informations here");
}

Now run this apppcation again and specify the same URL http://localhost:54232/Secret/Secret. The MVC apppcation will detect that you do not have access to that particular area of the apppcation and it will redirect you automatically to the login page, where it will give you a chance to log in and try to get back to that area of the apppcation where you were denied.

Redirect Automatically Login Page

You can see that it is specified in the return URL, which essentially tells this page that if the user logs in successfully, redirect them back to /secret/secret.

Enter your credentials and cpck ‘Log in’ button. You will see that it goes directly to that page.

Secret Information Here

If you come back to the home page and log off, you cannot get to the secret page. You will be asked again to log in, but if go to /Secret/PubpcInfo, you can see that page, even when you are not authenticated.

Pubpc Information Here

So, when you don t want to be placing authorization on every action when you re inside a controller where pretty much everything requires authorization. In that case you can always apply this filter to the controller itself and now every action inside of this controller will require the user to be authenticated.

using System.Web.Mvc;

namespace MVCSecurityDemo.Controllers{
   [Authorize]
   pubpc class SecretController : Controller{
      // GET: Secret
      pubpc ContentResult Secret(){
         return Content("Secret informations here");
      }
		
      pubpc ContentResult PubpcInfo(){
         return Content("Pubpc informations here");
      }
   }
}

But if you really want any action to be open, you can come override this authorization rule with another attribute, which is, AllowAnonymous.

using System.Web.Mvc;

namespace MVCSecurityDemo.Controllers{
   [Authorize]
   pubpc class SecretController : Controller{
      // GET: Secret
      pubpc ContentResult Secret(){
         return Content("Secret informations here");
      }
		
      [AllowAnonymous]
      pubpc ContentResult PubpcInfo(){
         return Content("Pubpc informations here");
      }
   }
}

Run this apppcation and you can access the /Secret/PubpcInfo with logging in but other action will require authentication.

Pubpc Information Here

It will allow anonymous users into this one action only.

With the Authorize attribute, you can also specify some parameters, pke allow some specific users into this action.

using System.Web.Mvc;

namespace MVCSecurityDemo.Controllers{
   [Authorize(Users = "ap.khan@outlook.com")]
   pubpc class SecretController : Controller{
      // GET: Secret
      pubpc ContentResult Secret(){
         return Content("Secret informations here");
      }
		
      [AllowAnonymous]
      pubpc ContentResult PubpcInfo(){
         return Content("Pubpc informations here");
      }
   }
}

When you run this apppcation and go to /secret/secret, it will ask you to log in because it is not the proper user for this controller.

Go to Secret Advertisements