![](/img/trans.png)
[英]ASP.NET MVC5 Basic HTTP authentication and AntiForgeryToken exception
[英]Basic authentication in ASP.NET MVC 5
必須執行哪些步驟才能在ASP.NET MVC 5 中實現基本身份驗證?
我讀過 OWIN 不支持 cookieless 身份驗證,所以基本身份驗證通常是可能的嗎?
我需要自定義屬性嗎? 我不確定這些屬性是如何工作的。
您可以使用自定義 ActionFilter 屬性來使用這種簡單而有效的機制:
public class BasicAuthenticationAttribute : ActionFilterAttribute
{
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 override void OnActionExecuting(ActionExecutingContext 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;
}
filterContext.HttpContext.Response.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Ryadel"));
/// thanks to eismanpat for this line: http://www.ryadel.com/en/http-basic-authentication-asp-net-mvc-using-custom-actionfilter/#comment-2507605761
filterContext.Result = new HttpUnauthorizedResult();
}
}
它可用於將整個控制器置於基本身份驗證之下:
[BasicAuthenticationAttribute("your-username", "your-password",
BasicRealm = "your-realm")]
public class HomeController : BaseController
{
...
}
或特定的 ActionResult:
public class HomeController : BaseController
{
[BasicAuthenticationAttribute("your-username", "your-password",
BasicRealm = "your-realm")]
public ActionResult Index()
{
...
}
}
如果您需要更多信息,請查看我在該主題上寫的這篇博文。
您可以使用自定義屬性執行此操作。 在開源項目SimpleSecurity 中有一個支持基本身份驗證的自定義屬性的實現,您可以在此處下載。 有一個參考應用程序來演示它是如何使用的。 它最初是為了在 MVC 4 中與 SimpleMembership 一起使用而開發的,最近已被移植到在 MVC 5 中使用 ASP.NET Identity 。
我想修改 Darkseal 分享的答案,因為該代碼存在重大安全漏洞。 正如所寫,當 res.End() 被調用時,該操作過濾器實際上並沒有終止請求。 系統會提示用戶輸入憑據,如果憑據不匹配,則會返回 401 響應,但控制器操作仍會在服務器端執行。 您需要將 filterContext.Result 屬性設置為某些內容,以便請求正確終止而不是繼續執行操作方法。
這對我的情況尤其不利,因為我試圖保護從第三方接收數據饋送的 Web 服務端點。 正如所寫,這個動作過濾器沒有保護任何東西,因為數據仍在通過我的動作方法推送。
我的“快速修復”如下:
public class BasicAuthenticationAttribute : ActionFilterAttribute
{
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 override void OnActionExecuting(ActionExecutingContext 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;
res.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Ryadel"));
filterContext.Result = new HttpUnauthorizedResult();
}
}
來自@Darkseal 的好答案。 這是重新用於 ASP.NET Web API(MVC 的近親)的相同代碼。 同樣的想法,命名空間和上下文類略有不同。 以完全相同的方式將其添加到您的類和方法中。
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
public class BasicAuthenticationAttribute : ActionFilterAttribute
{
public string BasicRealm { get; set; }
protected string Username { get; set; }
protected string Password { get; set; }
public BasicAuthenticationAttribute(string username, string password)
{
Username = username;
Password = password;
}
public override void OnActionExecuting(HttpActionContext filterContext)
{
var req = filterContext.Request;
var auth = req.Headers.Authorization;
if (auth?.Scheme == "Basic")
{
var cred = Encoding.ASCII.GetString(Convert.FromBase64String(auth.Parameter)).Split(':');
var user = new { Name = cred[0], Pass = cred[1] };
if (user.Name == Username && user.Pass == Password) return;
}
filterContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
filterContext.Response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", BasicRealm ?? "YourRealmName"));
}
}
您可以在Nuget (AuthPackage) 上試用這個包,它使您能夠輕松地向 asp.net mvc 添加身份驗證。
使用包管理器控制台安裝包:
安裝包 AuthPackage
將連接字符串添加到 (appSettings) 中的 Web.config:
<add key="connectionString" value="connectionStringHere" />
您已准備好注冊用戶、登錄、注銷
例子:
public async Task<ActionResult> SignIn()
{
var context = System.Web.HttpContext.Current;
AuthUser authUser = new AuthUser(context);
await authUser.SignIn("waleedchayeb2@gmail.com", "123456");
return RedirectToAction("Index", "Home");
}
你可以在這里閱讀文檔
由於 Web.config 中的以下代碼,我們的一個應用程序“意外地”使用了基本身份驗證:
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
... other stuff
</system.webServer>
應用程序以其他方式配置為使用表單身份驗證。 每當使用正常表單身份驗證時,都會彈出瀏覽器身份驗證窗口。
[BasicAuthenticationAttribute("your-username", "your-password",
BasicRealm = "your-realm")]
有兩個缺點:名稱和密碼是硬編碼的,它們只支持單用戶。
更靈活的解決方案應該支持存儲在配置中的多個用戶名/密碼對。
Microsoft 描述了一個示例 https://gm/aspnet/samples/tree/main/samples/aspnet/WebApi/BasicAuthentication。
public abstract class BasicAuthenticationAttribute : Attribute, IAuthenticationFilter
在過載
abstract Task<IPrincipal> AuthenticateAsync(string userName, string password,
CancellationToken cancellationToken);
您可以實施檢查以查找標題中的用戶名/密碼是否存在於用戶名/密碼對的配置/秘密列表中
也可以創建執行基本身份驗證的 HTTP 模塊。 您可以通過替換 CheckPassword 方法輕松插入 ASP.NET 成員資格提供程序。 https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/basic-authentication#basic-authentication-with-custom-membership
OWIN 實現示例https://github.com/scottbrady91/Blog-Example-Classes/tree/master/OwinBasicAuthentication/WebApi
https://github.com/mihirdilip/aspnetcore-authentication-basic 中描述了 .Net 核心中的可能實現
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.