我正在這使窗體身份驗證ASP.NET MVC5項目。項目目前正處於測試階段,並且在Azure在線託管,但項目業主想禁用對網站的所有公衆訪問(因爲網站的某些部分不要求用戶在所有驗證)。ASP.NET MVC5基本HTTP認證和AntiForgeryToken例外
對於這個測試階段,我們決定實現基本的HTTP認證,從這個link。我已經改變了代碼,因此它更適合我的需求:
public class BasicAuthenticationAttribute : FilterAttribute, IAuthorizationFilter
{
public string BasicRealm { get; set; }
protected string Username { get; set; }
protected string Password { get; set; }
public BasicAuthenticationAttribute(string username, string password)
{
this.Username = username;
this.Password = password;
}
public void OnAuthorization (AuthorizationContext filterContext)
{
var req = filterContext.HttpContext.Request;
var auth = req.Headers["Authorization"];
if (!String.IsNullOrEmpty(auth))
{
var cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':');
var user = new { Name = cred[0], Pass = cred[1] };
if (user.Name == Username && user.Pass == Password)
return;
}
var res = filterContext.HttpContext.Response;
var alreadySent = HttpContext.Current.Items.Contains("headers-sent");
if (!alreadySent)
{
res = filterContext.HttpContext.Response;
res.StatusCode = 401;
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
}
}
}
我也把它註冊爲一個全球性的過濾器:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorExtendedAttribute());
filters.Add(new BasicAuthenticationAttribute(AppConfig.BasicUsername, AppConfig.BasicPassword));
}
}
然而,也有一些問題,當我運行該項目。如果我使用這個版本的代碼:
if (!alreadySent)
{
res = filterContext.HttpContext.Response;
res.StatusCode = 401;
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
}
成功登錄後,它不斷重定向到表單登錄頁面。
但是如果我追加
res.End();
後
res.AppendHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Test"));
Antiforgerytoken在CSHTML文件拋出System.Web.HttpException
服務器不能追加頭後HTTP標頭已發送。
但是在這種情況下,它最終成功地進行了身份驗證。
我目前停留在這一點,不知道如何解決這個問題,因爲關閉窗體身份驗證是不是和選項,我不能刪除所有AntiForgeryTokens及其驗證。
爲什麼會選擇這種方式?如果你想構建一個自定義的'Authentication Filter',你應該從'AuthorizeAttribute'繼承,重寫'IsAuthorized'函數,返回'false'給未授權的請求,並在'HandleUnauthorizedRequest'函數中處理它們。 – AnhTriet
如果你用res.AppendHeader行翻轉res.StatusCode行會發生什麼? StatusCode值是否作爲「Body」的一部分計數,以便關閉Headers以不再被寫入?請考慮Andrew的迴應。 –
PLZ不使用基本身份驗證。請注意,您提到的其他問題就像6歲,即使如此,也有更好的選擇。參見:http://adrianotto.com/2013/02/why-http-basic-auth-is-bad/ – nothingisnecessary