ASP.NET MVC - 安全

ASP.NET MVC - 安全 首页 / ASP.Net MVC入门教程 / ASP.NET MVC - 安全

在本章中,我们将讨论如何在应用程序中实现安全功能,我们还将研究ASP.NET附带的新成员资格功能,这些新成员资格功能可从ASP.NET MVC使用。

认证方式

用户身份验证是指验证用户身份,这真的很重要。出于明显的原因,您可能只需要向经过身份验证的用户展示您的应用程序。

让我们创建一个新的ASP.Net MVC应用程序。

无涯教程网

New MVC Application

单击确定继续。

当您启动新的ASP.NET应用程序时,该过程中的步骤之一是为应用程序需求配置身份验证服务。

选择MVC模板,您将看到“Change Authentication”按钮现已启用。

链接:https://www.learnfk.comhttps://www.learnfk.com/asp.net_mvc/asp.net-mvc-security.html

来源:LearnFk无涯教程网

认证方式 Button Enabled

这是通过出现在“New Project”对话框中的“Change Authentication”按钮完成的。默认身份验证为“User Accounts”。

认证方式选项

单击"Change"按钮时,将看到一个包含四个选项的对话框,如下所示。

不认证

第一个选项是“No Authentication”,当您要构建一个不关心访问者是谁的网站时,将使用此选项。

No 认证方式

它向任何人开放,每个人都像每个页面一样连接。您以后可以随时更改它,但是“No Authentication”选项表示将没有任何功能来识别访问该网站的用户。

个人用户帐号

第二个选项是“Individual User Accounts”,这是传统的基于表单的身份验证,用户可以在其中访问网站,他们可以注册,创建登录名,并且默认情况下,他们的用户名使用一些新的ASP.NET身份功能存储在SQL Server数据库中,我们将介绍这些功能。

个人用户帐号

密码也存储在数据库中,密码是散列的,因此您不必担心数据库中存在纯文本密码。

工作和学校账户

第三种选择是使用组织帐户,通常用于要使用活动目录联合服务的业务应用程序。

Work School Accounts

您将设置Office 365或使用Azure Active Directory服务,并且对内部应用程序和云应用程序进行一次登录。

您还需要提供一个应用程序ID,以便如果您的应用程序是基于Azure的,则需要在Windows Azure管理门户中进行注册,并且该应用程序ID将在所有可能注册的应用程序中唯一标识该应用程序。

Windows验证

第四个选项是Windows身份验证,它对于Intranet应用程序非常有效。

Windows 认证方式

用户登录Windows桌面,可以启动浏览器浏览位于同一防火墙内的应用程序, ASP.NET可以自动获取用户身份,该身份由活动目录创建,此选项不允许对站点的任何匿名访问,但是同样,这是可以更改的配置设置。

让我们看一下基于表单的身份验证,该身份称为“Individual User Accounts”,此应用程序将用户名和密码,旧密码存储在本地SQL Server数据库中,并且在创建此项目时,Visual Studio还将添加NuGet包。

Forms-based 认证方式

现在运行该应用程序,当您第一次使用该应用程序时,您将成为匿名用户。

Anonymous User

您还没有可以登录的帐户,因此需要在此站点上注册。

单击注册链接,您将看到以下视图。

Click Register Link

输入您的电子邮件ID和密码。

Enter EmailId Password

单击注册。现在,应用程序将识别您。

Click Register

它将能够显示您的姓名,您可以单击该链接,这是指向可以更改密码的页面的链接。

Display Your Name

您还可以注销,关闭,重新启动,然后在一周后回来,并且您应该能够使用之前使用的凭据登录,现在单击注销按钮,它将显示以下页面。

Click Logoff Button

再次单击"Login"链接,您将转到下一页。

Click Login Link


为了达到这一点,很多工作在幕后进行,但是,我们要做的是检查每个功能并查看如何构建此UI,如何管理注销和登录过程?该信息在数据库中的何处排序?

让我们从几个简单的基础开始。首先,我们将看到如何显示该用户名。从Solution Explorer中的"View/Shared"文件夹中打开_Layout.cshtml。

<!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 Application</title>
      @Styles.Render("~/Content/css")
      @Scripts.Render("~/bundles/modernizr")
   </head>
	
   <body>
      <div class = "navbar navbar-inverse navbar-fixed-top">
         <div class = "container">
			
            <div 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("Application name", "Index", "Home", new
               { area="" }, new { @class="navbar-brand" })
            </div>
				
            <div class = "navbar-collapse collapse">
               <ul class = "nav navbar-nav">
                  <li>@Html.ActionLink("Home", "Index", "Home")</li>
                  <li>@Html.ActionLink("About", "About", "Home")</li>
                  <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
               </ul>
					
               @Html.Partial("_LoginPartial")
            </div>
				
         </div>
			
      </div>
      <div class = "container body-content">
         @RenderBody()
         <hr />
         <footer>
            <p>© @DateTime.Now.Year - My ASP.NET Application</p>
         </footer>
      </div>
		
      @Scripts.Render("~/bundles/jquery")
      @Scripts.Render("~/bundles/bootstrap")
      @RenderSection("scripts", required: false)
		
   </body>
</html>

有一个通用的导航栏,应用程序名称,菜单,还有一个呈现的局部视图,称为_loginpartial。那实际上是显示用户名或注册和登录名的视图。因此,_loginpartial.cshtml也位于共享文件夹中。

@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">
            <li>
               @Html.ActionLink("Hello " + User.Identity.GetUserName() + "!",
               "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
            </li>
				
            <li>
               <a href = "javascript:document.getElementById('logoutForm').submit()">Logoff</a>
            </li>
				
         </ul>
      }
}else{
   <ul class = "nav navbar-nav navbar-right">
      <li>@Html.ActionLink("Register", "Register", "Account", routeValues:
         null, htmlAttributes: new { id = "registerLink" })</li>
			
      <li>@Html.ActionLink("Log in", "Login", "Account", routeValues: null,
         htmlAttributes: new { id = "loginLink" })</li>
   </ul>
}

如您在上面看到的,有if/else语句。如果我们不知道用户是谁,因为请求未通过身份验证,此视图将显示注册和登录链接,用户可以单击链接登录或注册,所有这一切都是由AccountController完成的。

现在,我们想看看如何获​​取用户名,它位于Request.IsAuthenticated中,您可以看到对User.Identity.GetUserName的调用。

授权

假设我们有一些信息要保护,以防未经身份验证的用户使用,因此,让我们创建一个新的控制器来显示该信息,但仅当用户登录时才显示。

右键单击控制器文件夹,然后选择Add→Controller。

User Logged in

选择一个 MVC 5 Controller-Empty 控制器,然后单击"Add"。

输入名称SecretController,然后单击"Add"按钮。

SecretController

它将在内部具有两个Action,如以下代码所示。

using System.Web.Mvc;

namespace MVCSecurityDemo.Controllers{
   public class SecretController : Controller{
      //GET: Secret
      public ContentResult Secret(){
         return Content("Secret informations here");
      }
		
      public ContentResult PublicInfo(){
         return Content("Public informations here");
      }
   }
}

运行此应用程序时,无需进行任何身份验证即可访问此信息,如以下屏幕截图所示。

Secret Information Here

因此,只有经过身份验证的用户才能访问Secret操作方法,并且任何未经任何身份验证的人都可以使用PublicInfo。

为了保护此特定操作并防止未经身份验证的用户到达此处,可以使用Authorize属性,没有任何其他参数的Authorize属性将确保用户的身份是已知的,并且他们不是匿名用户。

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

现在再次运行该应用程序,并指定相同的URL http://localhost:54232/Secret/Secret , MVC应用程序将检测到您无权访问该应用程序的特定区域,并将自动将您重定向到登录页面,在该页面上您将有机会登录并尝试回到该应用程序的该区域。

Redirect Automatically Login Page

您可以看到它是在返回URL中指定的,它实际上告诉此页面,如果用户成功登录,请将其重定向回/secret/secret。

输入您的凭据,然后单击"Login"按钮。您将看到它直接转到该页面。

Secret Information Here

如果您返回首页并注销,则无法进入机密页面。将会再次要求您登录,但是如果转到/Secret/PublicInfo,即使您没有经过身份验证,也可以看到该页面。

Public Information Here

因此,当您不想在每个Action上都放置授权时,当您位于控制器中时,几乎所有事情都需要授权,在这种情况下,您始终可以将此过滤器应用于控制器本身,现在此控制器内部的每个操作都将要求对用户进行身份验证。

using System.Web.Mvc;

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

但是,如果您真的希望打开任何操作,则可以使用另一个属性AllowAnonymous覆盖此授权规则。

using System.Web.Mvc;

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

运行此应用程序,您可以登录登录访问/Secret/PublicInfo,但其他操作将需要身份验证。

Public Information Here

它将仅允许匿名用户执行此操作。

使用Authorize属性,您还可以指定一些参数,如允许某些特定用户执行此操作。

using System.Web.Mvc;

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

当您运行此应用程序并转到/secret/secret时,它将要求您登录,因为它不是此控制器的正确用户。

Go to Secret

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

Python核心技术与实战 -〔景霄〕

零基础学Java -〔臧萌〕

玩转webpack -〔程柳锋〕

编译原理之美 -〔宫文学〕

用户体验设计实战课 -〔相辉〕

编程高手必学的内存知识 -〔海纳〕

超级访谈:对话张雪峰 -〔张雪峰〕

深入剖析Java新特性 -〔范学雷〕

云原生架构与GitOps实战 -〔王炜〕

好记忆不如烂笔头。留下您的足迹吧 :)