使用 Visual Studio 2015 開發 ASP.NET Web API 2 專案時,有好幾種專案範本可以選擇,你可以從「空白」專案範本開始,也可以從「MVC」專案範本開始 (記得勾選 Web API 核心參考),也可以直接從「Web API」專案範本開始,由於專案範本通常夾雜大量的範例程式,很多時候我們並無法在第一時間得知每段程式碼與設定檔的細節,以至於在後續開發的過程發生許多問題。本篇文章將帶大家了解如何成功在 ASP.NET Web API 2 專案正確啟用 ASP.NET 的表單驗證機制 (FormsAuthenticaion)。
針對不同的專案範本,我特別建立了一個可比較的 Git 專案,你只要先複製這個 GitHub 專案回來,就可以比對不同專案範本之間的檔案差異之處。
這邊我寫了一個非常簡單的表單驗證程式碼,程式碼如下:
先建立一個 LoginViewModel
using System.ComponentModel.DataAnnotations;
namespace YourNamespace.Models
{
public class UserLoginViewModel
{
[Required]
[StringLength(20)]
public string Username { get; set; }
[Required]
public string Password { get; set; }
}
}
再建立一個 UsersController
using YourNamespace.Models;
using System.Net;
using System.Web.Http;
using System.Web.Security;
namespace YourNamespace.Controllers
{
[RoutePrefix("user")]
public class UsersController : ApiController
{
[Route("login")]
public IHttpActionResult PostLogin(UserLoginViewModel user)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
if (user.Username == "admin" && user.Password == "123")
{
FormsAuthentication.RedirectFromLoginPage(user.Username, false);
return StatusCode(HttpStatusCode.NoContent);
}
else
{
return StatusCode(HttpStatusCode.Unauthorized);
}
}
[Route("logout")]
[HttpGet][HttpPost]
public void Logout()
{
FormsAuthentication.SignOut();
}
[Authorize]
[Route("profile")]
public IHttpActionResult GetProfile()
{
return Ok(User.Identity.Name);
}
}
}
基本上,上述這兩個檔案就可以完成最基本的登入 (PostLogin)、登出 (Logout) 等基本身分驗證功能,搭配 [Authorize] 動作過濾器 (Action Filter) 還可以對 取得登入者名稱 (GetProfile) 功能進行基本授權驗證,因此這是一份完成的表單驗證實作,非常容易上手。
以下我將介紹在不同的專案範本下,才能讓這段程式碼正常運作:
1. 使用「空白」專案範本開始,外加 Web API 核心參考 (如下圖示)
這部分只要在專案根目錄下的 Web.config 加入 <authentication mode="Forms"></authentication> 即可:
2. 使用「MVC」專案範本開始,外加 Web API 核心參考 (如下圖示)
在 MVC 專案範本下,預設會停用所有表單驗證功能,如果要啟用表單驗證的話,則要修改 Web.config 兩個地方:
- 調整 <authentication> 的 mode 屬性為 Forms ( 原本預設值為 None )
- 刪除 <remove name="FormsAuthentication" /> 設定 (原本這行會停用所有表單驗證的功能)
由於 ASP.NET MVC 專案預設移除了 FormsAuthentication 模組,如果你沒有意識到這個模組預設被移除的話,會導致你的 Code 怎樣寫都能執行,登入也能跑,也不會發生例外,但登入者會永遠是「尚未登入」的鬼打牆狀態!
3. 使用「Web API」專案範本開始,外加 Web API 核心參考 (如下圖示)
在 Web API 專案範本下,預設也會停用所有表單驗證功能,但要改的地方又比 MVC 專案多一些,地雷實在很多啊!
如果要啟用表單驗證的話,除了要修改 Web.config 兩個地方 (跟 MVC 專案範本一樣),還要修改 App_Start\WebApiConfig.cs 檔案:
修改 Web.config 兩個地方:
- 調整 <authentication> 的 mode 屬性為 Forms ( 原本預設值為 None )
- 刪除 <remove name="FormsAuthentication" /> 設定 (原本這行會停用所有表單驗證的功能)
修改 App_Start\WebApiConfig.cs 兩行程式碼,將其註解起來:
- // config.SuppressDefaultHostAuthentication();
- // config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
預設的 ASP.NET Web API 2 專案範本中,由於被設定成僅使用 bearer 權杖驗證,因此這兩行必須註解起來,表單驗證才能正常執行。
不過有一點要注意,如果你將這兩行註解起來的話,ASP.NET Web API 就不能走專案範本預設的 OAuth 驗證,專案內的 AccountController 也將無法正常使用!
本文所有程式碼,包含所有修改程式碼的版本紀錄,都已經整理到 https://github.com/doggy8088/WebApi2FormsAuth 這個專案中,大家可以先 git clone 回來,再透過 Git 工具 (TortoiseGit, SourceTree, … ) 即可查看每一個版本的變化歷程。
相關連結