鍍金池/ 教程/ C#/ ASP.Net MVC安全
ASP.Net MVC簡介
ASP.Net MVC過濾器
ASP.Net MVC視圖
ASP.Net MVC安全
ASP.Net MVC手腳架
ASP.Net MVC控制器
ASP.Net MVC與SQL Server數(shù)據(jù)庫操作
ASP.Net MVC NuGet包管理
ASP.Net MVC入門程序
ASP.Net MVC Razor
ASP.Net MVC Bootstrap
ASP.Net MVC單元測試
ASP.Net MVC動作
ASP.Net MVC模式
ASP.Net MVC選擇器
ASP.Net MVC開發(fā)環(huán)境配置
ASP.Net MVC生命周期
ASP.Net MVC模型綁定
ASP.Net MVC自托管(本地主機(jī)部署)
ASP.Net MVC驗證
ASP.Net MVC緩存
ASP.Net MVC數(shù)據(jù)模型
ASP.Net MVC路由
ASP.Net MVC教程
ASP.Net MVC助手
ASP.Net MVC數(shù)據(jù)注解
ASP.Net MVC Web API

ASP.Net MVC安全

在本章中,我們將討論如何在應(yīng)用程序中實現(xiàn)安全功能。還將看到ASP.NET中包含的新成員特性,并可從ASP.NET MVC中使用。在ASP.NET的最新版本中,可以通過以下方式管理用戶身份 -

  • SQL數(shù)據(jù)庫
  • 本地Windows活動目錄

在本章中,我們將介紹作為ASP.NET一部分的新身份組件,并了解如何自定義用戶和角色的成員資格。

認(rèn)證

用戶的認(rèn)證意味著驗證用戶的身份,這真的很重要??赡苄枰獙⒛膽?yīng)用程序僅顯示給經(jīng)過身份驗證的用戶,原因很明顯。
我們來創(chuàng)建一個新的ASP.Net MVC應(yīng)用程序項目:MVCSecurity 。點擊確定 繼續(xù)。

當(dāng)啟動一個新的ASP.NET應(yīng)用程序時,這個過程中的一個步驟就是為應(yīng)用程序需要配置身份驗證服務(wù)。選擇MVC模板,將看到現(xiàn)在啟用了更改認(rèn)證按鈕。

這是通過出現(xiàn)在“新建項目”對話框中的“更改認(rèn)證”按鈕完成的。默認(rèn)身份驗證是個人用戶帳戶。

認(rèn)證選項

當(dāng)單擊更改按鈕時,您將看到一個對話框,其中包含四個選項,如下所示。

1. 不進(jìn)行身份驗證

第一個選項是不驗證,當(dāng)想建立一個不關(guān)心訪問者是誰的網(wǎng)站時使用這個選項。

它是開放給任何人和每個人連接為每一個頁面。以后可以隨時更改,但“不進(jìn)行身份驗證” 選項意味著不會有任何功能來識別訪問該網(wǎng)站的用戶。

2. 個人用戶帳戶

第二個選項是個人用戶帳戶,這是用戶可以訪問網(wǎng)站的傳統(tǒng)的基于表單的身份驗證。 他們可以注冊,創(chuàng)建一個登錄名,默認(rèn)情況下,用戶名是使用一些新的ASP.NET身份特性存儲在SQL Server數(shù)據(jù)庫中。

密碼也存儲在數(shù)據(jù)庫中,但首先被散列。由于密碼是散列的,因此不必?fù)?dān)心在數(shù)據(jù)庫中的純文本密碼而被別人知道。

此選項通常用于要建立用戶身份的Internet站點。 除了允許用戶使用網(wǎng)站的密碼創(chuàng)建本地登錄外,還可以啟用來自Microsoft,Google,F(xiàn)acebook和Twitter等第三方的登錄。

這允許用戶使用他們的真實帳戶或他們的Twitter帳戶登錄到您的網(wǎng)站,但是您不需要存儲任何密碼。

這將在這個模塊中花費一些時間的選項。個人用戶帳戶 選項。

3. 工作和學(xué)校帳戶

第三個選擇是使用組織帳戶,這通常用于使用活動目錄聯(lián)合服務(wù)的業(yè)務(wù)應(yīng)用程序。

將設(shè)置Office 365或使用Azure Active Directory服務(wù),并且您有內(nèi)部應(yīng)用程序和云應(yīng)用程序的單一登錄。

您還需要提供應(yīng)用程序ID,以便應(yīng)用程序需要在Windows Azure管理門戶(如果這是基于Azure的)上進(jìn)行注冊,并且應(yīng)用程序ID將在所有可能注冊的應(yīng)用程序中唯一標(biāo)識此應(yīng)用程序。

4. Windows身份驗證

第四個選項是Windows身份驗證 ,適用于Intranet應(yīng)用程序。

用戶登錄到Windows桌面,并可以將瀏覽器啟動到位于同一防火墻內(nèi)的應(yīng)用程序。 ASP.NET可以自動獲取用戶的身份,即由活動目錄建立的身份。 該選項不允許任何匿名訪問該站點,但這也是一個可以更改的配置設(shè)置。

下面我們來看看基于表單的身份驗證 ,即名稱為個人用戶帳戶的身份驗證。 此應(yīng)用程序?qū)⒂脩裘兔艽a,舊密碼存儲在本地SQL Server數(shù)據(jù)庫中,創(chuàng)建此項目時,Visual Studio也將添加NuGet包。

現(xiàn)在運行這個應(yīng)用程序,當(dāng)您第一次訪問這個應(yīng)用程序,那么是以一個匿名用戶來訪問的。

因為您還沒有登錄的賬戶,所以需要在這個網(wǎng)站上先注冊一個用戶。

點擊注冊 鏈接,會看到下面的視圖。

輸入您的電子郵件ID和密碼,例如:maxsu@yiibai.comAbc@123。

點擊注冊。 現(xiàn)在,應(yīng)用程序?qū)⑹褂么速~戶信息識別您。

它將能夠顯示用戶的名字。 在下面的截圖中,可以看到:“你好,maxsu@yiibai.com!” 。 可以點擊它鏈接到一個頁面,可以在這個頁面中更改密碼。

也可以注銷,關(guān)閉,重新啟動,一個星期后回來,應(yīng)該可以使用之前使用的憑據(jù)登錄?,F(xiàn)在點擊注銷 按鈕,它將顯示以下頁面。再次點擊登錄鏈接進(jìn)入下一頁??梢允褂孟嗤膽{據(jù)重新登錄。

很多工作都在幕后進(jìn)行到現(xiàn)在。 但是,我們想要做的是檢查每個功能,看看這個UI是如何構(gòu)建的。 什么是管理注銷和登錄過程? 這些信息在數(shù)據(jù)庫中排序?

讓我們從一些簡單的基礎(chǔ)開始。 首先,我們將看到這個用戶名是如何顯示的。 從解決方案資源管理器中的View/Shared文件夾中打開_Layout.cshtml。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - 我的 ASP.NET 應(yīng)用程序</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" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("應(yīng)用程序名稱", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("主頁", "Index", "Home")</li>
                    <li>@Html.ActionLink("關(guān)于", "About", "Home")</li>
                    <li>@Html.ActionLink("聯(lián)系方式", "Contact", "Home")</li>
                </ul>
                @Html.Partial("_LoginPartial")
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>? @DateTime.Now.Year - 我的 ASP.NET 應(yīng)用程序</p>
        </footer>
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>
</html>

有一個共同的導(dǎo)航欄,應(yīng)用程序名稱,菜單,并有一個局部視圖呈現(xiàn)為_loginpartial。 這實際上是顯示用戶名或注冊和登錄名的視圖。 所以_loginpartial.cshtml也在shared文件夾中。其代碼如下所示 -

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

正如可以看到上面,有if/else語句。 如果請求沒有被認(rèn)證,這個視圖將顯示注冊和登錄鏈接。用戶可以點擊鏈接登錄注冊。所有這些都是由帳戶控制器完成的。

現(xiàn)在,我們想看看如何獲取用戶名,這是在Request.IsAuthenticated。 可以看到對User.Identity.GetUserName的調(diào)用。這將檢索用戶名,在這種情況下是"maxsu@yiibai.com"

授權(quán)

假設(shè)想要防止未經(jīng)驗證的用戶的信息。 因此,讓我們創(chuàng)建一個新的控制器來顯示這些信息,但只有當(dāng)用戶登錄時才能操作。

右鍵單擊Controllers 文件夾,然后選擇:添加 -> 控制器 。選擇一個MVC 5控制器 - 空 控制器,然后點擊“添加”。輸入名稱SecretController,然后單擊“添加” 按鈕。

它將會有兩個動作,如下面的代碼所示。參考以下代碼 -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCSecurity.Controllers
{
    public class SecretController : Controller
    {
        // GET: Secret
        public ActionResult Index()
        {
            return View();
        }
        // GET: Secret
        public ContentResult Secret()
        {
            return Content("Secret informations here");
        }

        public ContentResult PublicInfo()
        {
            return Content("Public informations here");
        }
    }
}

當(dāng)運行這個應(yīng)用程序時,可以在沒有任何驗證的情況下訪問這個信息(URL:http://localhost:57742/Secret/Secret),如下面的截圖所示。

假設(shè)只有經(jīng)過身份驗證的用戶才能夠使用Secret動作方法,并且任何人都可以使用PublicInfo,而不需要任何身份驗證。

為了保護(hù)這個特定的操作并保證未經(jīng)身份驗證的用戶到達(dá)此處,可以使用Authorize屬性。 沒有任何其他參數(shù)的授權(quán)屬性將確保用戶的身份是已知的,他們不是一個匿名用戶。

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

現(xiàn)在再次運行這個應(yīng)用程序,并指定相同的URL:http://localhost:57742/Secret/Secret。 MVC應(yīng)用程序?qū)z測到您無權(quán)訪問應(yīng)用程序的特定區(qū)域,并且會自動重定向到登錄頁面,在那里登錄并嘗試返回訪問受限的應(yīng)用程序的URL。

可以看到它在返回URL中指定,它告訴此頁面,如果用戶成功登錄,則將其重定向到/secret/secret

輸入您的用戶名和密碼,然后點擊“登錄”按鈕。會看到它直接進(jìn)入該頁面。

當(dāng)不想在每一個動作上進(jìn)行授權(quán)的時候,當(dāng)想要在一個控制器里,幾乎所有的事情都需要授權(quán)。 在這種情況下,總是可以將此過濾器應(yīng)用于控制器本身,現(xiàn)在,此控制器內(nèi)部的每個操作都將要求用戶進(jìn)行身份驗證。

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)覆蓋此授權(quán)規(guī)則。參考以下代碼 -

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");
      }
   }
}

使用Authorize屬性,也可以指定一些參數(shù),比如允許一些特定的用戶進(jìn)入這個動作。

using System.Web.Mvc;

namespace MVCSecurityDemo.Controllers{
   [Authorize(Users = "maxsu@yiibai.com")]
   public class SecretController : Controller{
      // GET: Secret
      public ContentResult Secret(){
         return Content("Secret informations here");
      }

      [AllowAnonymous]
      public ContentResult PublicInfo(){
         return Content("Public informations here");
      }
   }
}

當(dāng)運行此應(yīng)用程序并轉(zhuǎn)到URL:/secret/secret時,如果它不是此控制器要求的用戶(maxsu@yiibai.com),它會要求您登錄。


下一篇:ASP.Net MVC助手