安全性框架:會話管理

產品/服務 文章
Microsoft Entra ID
IoT 裝置
Azure Document DB
ADFS
Identity Server
Web 應用程式
Web API

使用 Microsoft Entra ID 時,使用 MSAL 方法實作適當的登出

標題 詳細資料
元件 Microsoft Entra ID
SDL 階段 組建
適用的技術 泛型
屬性 N/A
參考 讓您的 Web 應用程式使用 Microsoft 身分識別平臺登入使用者
步驟 ASP.NET Core OpenId連線中介軟體可讓您的應用程式藉由提供名為 的 OpenId 來攔截對Microsoft 身分識別平臺登出端點的呼叫連線OnRedirectToIdentityProviderForSignOut

範例

services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.Events.OnRedirectToIdentityProviderForSignOut = async context =>
    {
        //Your logic here
    };
});

針對產生的 SaS 權杖使用有限存留期

標題 詳細資料
元件 IoT 裝置
SDL 階段 組建
適用的技術 泛型
屬性 N/A
參考 N/A
步驟 針對驗證至Azure IoT 中樞所產生的 SaS 權杖應該有有限的到期期間。 將 SaS 權杖存留期維持在最小值,以限制在權杖遭到入侵時可重新執行的時間量。

針對產生的資源權杖使用最小權杖存留期

標題 詳細資料
元件 Azure Document DB
SDL 階段 組建
適用的技術 泛型
屬性 N/A
參考 N/A
步驟 將資源權杖的時間範圍縮減為所需的最小值。 資源權杖的預設有效時間範圍為 1 小時。

使用 ADFS 時,使用 WsFederation 方法實作適當的登出

標題 詳細資料
元件 ADFS
SDL 階段 組建
適用的技術 泛型
屬性 N/A
參考 N/A
步驟 如果應用程式依賴 ADFS 所發出的 STS 權杖,則登出事件處理常式應該呼叫 WSFederationAuthenticationModule.FederatedSignOut() 方法來登出使用者。 此外,目前的會話應該終結,而會話權杖值應該重設並 Null 化。

範例

        [HttpPost, ValidateAntiForgeryToken]
        [Authorization]
        public ActionResult SignOut(string redirectUrl)
        {
            if (!this.User.Identity.IsAuthenticated)
            {
                return this.View("LogOff", null);
            }

            // Removes the user profile.
            this.Session.Clear();
            this.Session.Abandon();
            HttpContext.Current.Response.Cookies.Add(new System.Web.HttpCookie("ASP.NET_SessionId", string.Empty)
                {
                    Expires = DateTime.Now.AddDays(-1D),
                    Secure = true,
                    HttpOnly = true
                });

            // Signs out at the specified security token service (STS) by using the WS-Federation protocol.
            Uri signOutUrl = new Uri(FederatedAuthentication.WSFederationAuthenticationModule.Issuer);
            Uri replyUrl = new Uri(FederatedAuthentication.WSFederationAuthenticationModule.Realm);
            if (!string.IsNullOrEmpty(redirectUrl))
            {
                replyUrl = new Uri(FederatedAuthentication.WSFederationAuthenticationModule.Realm + redirectUrl);
            }
           //     Signs out of the current session and raises the appropriate events.
            var authModule = FederatedAuthentication.WSFederationAuthenticationModule;
            authModule.SignOut(false);
        //     Signs out at the specified security token service (STS) by using the WS-Federation
        //     protocol.            
            WSFederationAuthenticationModule.FederatedSignOut(signOutUrl, replyUrl);
            return new RedirectResult(redirectUrl);
        }

使用 Identity Server 時實作適當的登出

標題 詳細資料
元件 身分識別伺服器
SDL 階段 組建
適用的技術 泛型
屬性 N/A
參考 IdentityServer3-Federated 登出
步驟 IdentityServer 支援與外部識別提供者同盟的能力。 當使用者登出上游識別提供者時,視所使用的通訊協定而定,使用者登出時可能會收到通知。它可讓 IdentityServer 通知其用戶端,讓他們也可以將使用者登出。如需實作詳細資料,請參閱參考一節中的檔。

透過 HTTPS 提供的應用程式必須使用安全的 Cookie

標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 泛型
屬性 EnvironmentType - OnPrem
參考 HTTPCookies 元素 (ASP.NET 設定 架構) HttpCookie.Secure 屬性
步驟 Cookie 通常只能存取其範圍所在的網域。 不幸的是,「網域」的定義不包含通訊協定,因此透過 HTTPS 建立的 Cookie 可透過 HTTP 存取。 「secure」 屬性會向瀏覽器指出 Cookie 只能透過 HTTPS 提供。 請確定透過 HTTPS 設定的所有 Cookie 都會使用 安全 屬性。 您可以將 requireSSL 屬性設定為 true,在 web.config 檔案中強制執行需求。 這是慣用的方法,因為它會針對所有目前和未來的 Cookie 強制執行 安全 屬性,而不需要進行任何額外的程式碼變更。

範例

<configuration>
  <system.web>
    <httpCookies requireSSL="true"/>
  </system.web>
</configuration>

即使使用 HTTP 來存取應用程式,仍會強制執行設定。 如果 HTTP 是用來存取應用程式,則此設定會中斷應用程式,因為 Cookie 是以安全屬性設定,而且瀏覽器不會將它們傳回應用程式。

標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 Web Form、MVC5
屬性 EnvironmentType - OnPrem
參考 N/A
步驟 當 Web 應用程式是信賴憑證者,而 IdP 是 ADFS 伺服器時,可以在 web.config 區段中將 requireSSL 設定為 True system.identityModel.services 來設定 FedAuth 權杖的安全屬性:

範例

  <system.identityModel.services>
    <federationConfiguration>
      <!-- Set requireSsl=true; domain=application domain name used by FedAuth cookies (Ex: .gdinfra.com); -->
      <cookieHandler requireSsl="true" persistentSessionLifetime="0.0:20:0" />
    ....  
    </federationConfiguration>
  </system.identityModel.services>
標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 泛型
屬性 N/A
參考 安全 Cookie 屬性
步驟 為了降低跨網站腳本攻擊資訊洩漏的風險,所有主要瀏覽器都引進了新的屬性 HTTPOnly。 屬性指定無法透過腳本存取 Cookie。 透過使用 HttpOnly Cookie,Web 應用程式可減少透過腳本竊取 Cookie 中所含敏感性資訊並傳送至攻擊者網站的可能性。

範例

所有使用 Cookie 的 HTTP 型應用程式都應該在 Cookie 定義中指定 HttpOnly,方法是在 web.config 中實作下列組態:

<system.web>
.
.
   <httpCookies requireSSL="false" httpOnlyCookies="true"/>
.
.
</system.web>
標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 Web Form
屬性 N/A
參考 FormsAuthentication.RequireSSL 屬性
步驟 RequireSSL 屬性值是使用組態專案的 requireSSL 屬性,在 ASP.NET 應用程式的組態檔中設定。 您可以在 ASP.NET 應用程式的 Web.config 檔案中指定傳輸層安全性(TLS),先前稱為 SSL(安全通訊端層),必須藉由設定 requireSSL 屬性,將表單驗證 Cookie 傳回伺服器。

範例

下列程式碼範例會在 Web.config 檔案中設定 requireSSL 屬性。

<authentication mode="Forms">
  <forms loginUrl="member_login.aspx" cookieless="UseCookies" requireSSL="true"/>
</authentication>
標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 MVC5
屬性 EnvironmentType - OnPrem
參考 Windows Identity Foundation (WIF) 設定 – 第二部分
步驟 若要設定 FedAuth Cookie 的 HTTPOnly 屬性,hideFromCsript 屬性值應設定為 True。

範例

下列組態顯示正確的組態:

<federatedAuthentication>
<cookieHandler mode="Custom"
                       hideFromScript="true"
                       name="FedAuth"
                       path="/"
                       requireSsl="true"
                       persistentSessionLifetime="25">
</cookieHandler>
</federatedAuthentication>

減輕 ASP.NET 網頁上的跨網站偽造要求攻擊

標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 泛型
屬性 N/A
參考 N/A
步驟 跨網站偽造要求(CSRF 或 XSRF)是一種攻擊類型,攻擊者可以在網站上不同使用者建立會話的安全性內容中執行動作。 如果目標網站只依賴會話 Cookie 來驗證已接收的要求,則目標是修改或刪除內容。 攻擊者可能會藉由取得不同使用者的瀏覽器,從使用者已登入的易受攻擊網站載入 URL,以利用此弱點。 攻擊者有許多方式可以這麼做,例如裝載從易受攻擊的伺服器載入資源的不同網站,或讓使用者按一下連結。 如果伺服器將額外的權杖傳送給用戶端、要求用戶端在所有未來的要求中包含該權杖,並確認所有未來的要求都包含與目前會話相關的權杖,例如使用 ASP.NET AntiForgeryToken 或 ViewState,即可防止攻擊。
標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 MVC5、MVC6
屬性 N/A
參考 ASP.NET MVC 和 ASP.NET Web Pages 中的 XSRF/CSRF 防護
步驟 反 CSRF 和 ASP.NET MVC 表單 - 在 AntiForgeryToken [檢視] 上使用協助程式方法;將 放入 Html.AntiForgeryToken() 表單中,例如

範例

@using (Html.BeginForm("UserProfile", "SubmitUpdate")) { 
    @Html.ValidationSummary(true) 
    @Html.AntiForgeryToken()
    <fieldset> 

範例

<form action="/UserProfile/SubmitUpdate" method="post">
    <input name="__RequestVerificationToken" type="hidden" value="saTFWpkKN0BYazFtN6c4YbZAmsEwG0srqlUqqloi/fVgeV2ciIFVmelvzwRZpArs" />
    <!-- rest of form goes here -->
</form>

範例

同時,Html.AntiForgeryToken() 會為訪客提供名為 __RequestVerificationToken 的 Cookie,其值與上面顯示的隨機隱藏值相同。 接下來,若要驗證傳入表單貼文,請將 [ValidateAntiForgeryToken] 篩選新增至目標動作方法。 例如:

[ValidateAntiForgeryToken]
public ViewResult SubmitUpdate()
{
// ... etc.
}

檢查該條件的授權篩選:

  • 連入要求具有稱為 __RequestVerificationToken 的 Cookie
  • 連入要求有名為 Request.Form __RequestVerificationToken 的專案
  • 這些 Cookie 和 Request.Form 值符合假設所有狀況良好,要求會正常通過。 但如果不是,則表示授權失敗,並顯示「未提供必要的反偽造權杖或無效」訊息。

範例

反 CSRF 和 AJAX:表單權杖可能是 AJAX 要求的問題,因為 AJAX 要求可能會傳送 JSON 資料,而不是 HTML 表單資料。 其中一個解決方案是在自訂 HTTP 標頭中傳送權杖。 下列程式碼會使用 Razor 語法來產生權杖,然後將權杖新增至 AJAX 要求。

<script>
    @functions{
        public string TokenHeaderValue()
        {
            string cookieToken, formToken;
            AntiForgery.GetTokens(null, out cookieToken, out formToken);
            return cookieToken + ":" + formToken;                
        }
    }

    $.ajax("api/values", {
        type: "post",
        contentType: "application/json",
        data: {  }, // JSON data goes here
        dataType: "json",
        headers: {
            'RequestVerificationToken': '@TokenHeaderValue()'
        }
    });
</script>

範例

當您處理要求時,請從要求標頭擷取權杖。 然後呼叫 AntiForgery.Validate 方法來驗證權杖。 如果權杖無效,Validate 方法會擲回例外狀況。

void ValidateRequestHeader(HttpRequestMessage request)
{
    string cookieToken = "";
    string formToken = "";

    IEnumerable<string> tokenHeaders;
    if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
    {
        string[] tokens = tokenHeaders.First().Split(':');
        if (tokens.Length == 2)
        {
            cookieToken = tokens[0].Trim();
            formToken = tokens[1].Trim();
        }
    }
    AntiForgery.Validate(cookieToken, formToken);
}
標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 Web Form
屬性 N/A
參考 利用 ASP.NET 內建功能來抵禦 Web 攻擊
步驟 WebForm 應用程式中的 CSRF 攻擊可藉由將 ViewStateUserKey 設定為隨機字串,以因每個使用者而有所不同 - 使用者識別碼,或較佳的會話識別碼來緩和。 基於許多技術和社交原因,會話識別碼較適合,因為會話識別碼無法預測、逾時,而且會依每個使用者而有所不同。

範例

以下是您需要在所有頁面中擁有的程式碼:

void Page_Init (object sender, EventArgs e) {
   ViewStateUserKey = Session.SessionID;
   :
}

設定閒置存留期的會話

標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 泛型
屬性 N/A
參考 HttpSessionState.Timeout 屬性
步驟 會話逾時代表使用者在間隔期間未在網站上執行任何動作時所發生的事件(由網頁伺服器定義)。 事件在伺服器端將使用者會話的狀態變更為「無效」(例如「不再使用」),並指示網頁伺服器銷毀它(刪除其中包含的所有資料)。 下列程式碼範例會將 Web.config 檔案中的逾時會話屬性設定為 15 分鐘。

範例

<configuration>
  <system.web>
    <sessionState mode="InProc" cookieless="true" timeout="15" />
  </system.web>
</configuration>

請確保 Azure SQL 上的威脅偵測啟用

標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 Web Form
屬性 N/A
參考 驗證的 Forms 元素(ASP.NET 設定架構)
步驟 將表單驗證票證 Cookie 逾時設定為 15 分鐘

範例

<forms  name=".ASPXAUTH" loginUrl="login.aspx"  defaultUrl="default.aspx" protection="All" timeout="15" path="/" requireSSL="true" slidingExpiration="true"/>
</forms>
標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 Web Form、MVC5
屬性 EnvironmentType - OnPrem
參考 asdeqa
步驟 當 Web 應用程式是信賴憑證者且 ADFS 是 STS 時,驗證 Cookie 的存留期 - FedAuth 權杖 - 可以透過 web.config 中的下列設定來設定:

範例

  <system.identityModel.services>
    <federationConfiguration>
      <!-- Set requireSsl=true; domain=application domain name used by FedAuth cookies (Ex: .gdinfra.com); -->
      <cookieHandler requireSsl="true" persistentSessionLifetime="0.0:15:0" />
      <!-- Set requireHttps=true; -->
      <wsFederation passiveRedirectEnabled="true" issuer="http://localhost:39529/" realm="https://localhost:44302/" reply="https://localhost:44302/" requireHttps="true"/>
      <!--
      Use the code below to enable encryption-decryption of claims received from ADFS. Thumbprint value varies based on the certificate being used.
      <serviceCertificate>
        <certificateReference findValue="4FBBBA33A1D11A9022A5BF3492FF83320007686A" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
      </serviceCertificate>
      -->
    </federationConfiguration>
  </system.identityModel.services>

範例

此外,ADFS 發出的 SAML 宣告權杖存留期應該設定為 15 分鐘,方法是在 ADFS 伺服器上執行下列 Powershell 命令:

Set-ADFSRelyingPartyTrust -TargetName "<RelyingPartyWebApp>" -ClaimsProviderName @("Active Directory") -TokenLifetime 15 -AlwaysRequireAuthentication $true

從應用程式實作適當的登出

標題 詳細資料
元件 Web 應用程式
SDL 階段 組建
適用的技術 泛型
屬性 N/A
參考 N/A
步驟 當使用者按下登出按鈕時,請從應用程式執行適當的登出。 登出時,應用程式應該終結使用者的會話,同時重設和 Null 化會話 Cookie 值,以及重設和 Null 化驗證 Cookie 值。 此外,當多個會話系結至單一使用者身分識別時,必須在伺服器端在逾時或登出時集體終止。 最後,請確定每個頁面上都有登出功能可用。

降低對 ASP.NET Web API 的跨網站偽造要求攻擊

標題 詳細資料
元件 Web API
SDL 階段 組建
適用的技術 泛型
屬性 N/A
參考 N/A
步驟 跨網站偽造要求(CSRF 或 XSRF)是一種攻擊類型,攻擊者可以在網站上不同使用者建立會話的安全性內容中執行動作。 如果目標網站只依賴會話 Cookie 來驗證已接收的要求,則目標是修改或刪除內容。 攻擊者可能會藉由取得不同使用者的瀏覽器,從使用者已登入的易受攻擊網站載入 URL,以利用此弱點。 攻擊者有許多方式可以這麼做,例如裝載從易受攻擊的伺服器載入資源的不同網站,或讓使用者按一下連結。 如果伺服器將額外的權杖傳送給用戶端、要求用戶端在所有未來的要求中包含該權杖,並確認所有未來的要求都包含與目前會話相關的權杖,例如使用 ASP.NET AntiForgeryToken 或 ViewState,即可防止攻擊。
標題 詳細資料
元件 Web API
SDL 階段 組建
適用的技術 MVC5、MVC6
屬性 N/A
參考 防止 ASP.NET Web API 中的跨網站偽造要求 (CSRF) 攻擊
步驟 反 CSRF 和 AJAX:表單權杖可能是 AJAX 要求的問題,因為 AJAX 要求可能會傳送 JSON 資料,而不是 HTML 表單資料。 其中一個解決方案是在自訂 HTTP 標頭中傳送權杖。 下列程式碼會使用 Razor 語法來產生權杖,然後將權杖新增至 AJAX 要求。

範例

<script>
    @functions{
        public string TokenHeaderValue()
        {
            string cookieToken, formToken;
            AntiForgery.GetTokens(null, out cookieToken, out formToken);
            return cookieToken + ":" + formToken;                
        }
    }
    $.ajax("api/values", {
        type: "post",
        contentType: "application/json",
        data: {  }, // JSON data goes here
        dataType: "json",
        headers: {
            'RequestVerificationToken': '@TokenHeaderValue()'
        }
    });
</script>

範例

當您處理要求時,請從要求標頭擷取權杖。 然後呼叫 AntiForgery.Validate 方法來驗證權杖。 如果權杖無效,Validate 方法會擲回例外狀況。

void ValidateRequestHeader(HttpRequestMessage request)
{
    string cookieToken = "";
    string formToken = "";

    IEnumerable<string> tokenHeaders;
    if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
    {
        string[] tokens = tokenHeaders.First().Split(':');
        if (tokens.Length == 2)
        {
            cookieToken = tokens[0].Trim();
            formToken = tokens[1].Trim();
        }
    }
    AntiForgery.Validate(cookieToken, formToken);
}

範例

反 CSRF 和 ASP.NET MVC 表單 - 在檢視上使用 AntiForgeryToken 協助程式方法;將 Html.AntiForgeryToken() 放入表單中,例如

@using (Html.BeginForm("UserProfile", "SubmitUpdate")) { 
    @Html.ValidationSummary(true) 
    @Html.AntiForgeryToken()
    <fieldset> 
}

範例

上述範例將輸出如下的內容:

<form action="/UserProfile/SubmitUpdate" method="post">
    <input name="__RequestVerificationToken" type="hidden" value="saTFWpkKN0BYazFtN6c4YbZAmsEwG0srqlUqqloi/fVgeV2ciIFVmelvzwRZpArs" />
    <!-- rest of form goes here -->
</form>

範例

同時,Html.AntiForgeryToken() 會為訪客提供名為 __RequestVerificationToken 的 Cookie,其值與上面顯示的隨機隱藏值相同。 接下來,若要驗證傳入表單貼文,請將 [ValidateAntiForgeryToken] 篩選新增至目標動作方法。 例如:

[ValidateAntiForgeryToken]
public ViewResult SubmitUpdate()
{
// ... etc.
}

檢查該條件的授權篩選:

  • 連入要求具有稱為 __RequestVerificationToken 的 Cookie
  • 連入要求有名為 Request.Form __RequestVerificationToken 的專案
  • 這些 Cookie 和 Request.Form 值符合假設所有狀況良好,要求會正常通過。 但如果不是,則表示授權失敗,並顯示「未提供必要的反偽造權杖或無效」訊息。
標題 詳細資料
元件 Web API
SDL 階段 組建
適用的技術 MVC5、MVC6
屬性 識別提供者 - ADFS、識別提供者 - Microsoft Entra ID
參考 在 ASP.NET Web API 2.2 中使用個別帳戶和本機登入來保護 Web API
步驟 如果使用 OAuth 2.0 保護 Web API,則只有在權杖有效時,才會預期授權要求標頭中有持有人權杖,並授與對要求的存取權。 不同于以 Cookie 為基礎的驗證,瀏覽器不會將持有人權杖附加至要求。 要求用戶端必須在要求標頭中明確附加持有人權杖。 因此,對於 ASP.NET 使用 OAuth 2.0 保護的 Web API 而言,持有人權杖會被視為防禦 CSRF 攻擊。 請注意,如果應用程式的 MVC 部分使用表單驗證(亦即使用 Cookie),MVC Web 應用程式必須使用反偽造權杖。

範例

必須通知 Web API 只依賴持有人權杖,而不是依賴 Cookie。 方法中 WebApiConfig.Register 可以透過下列組態來完成:

config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

SuppressDefaultHostAuthentication 方法會告訴 Web API 忽略要求到達 Web API 管線之前,由 IIS 或 OWIN 中介軟體發生的任何驗證。 如此一來,我們可以限制 Web API 只使用持有人權杖進行驗證。