簡體   English   中英

ASP.NET MVC 5 中的基本身份驗證

[英]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();
    }
}

HTTP 基本身份驗證不需要 cookie。 它基於 HTTP 請求中的 HEADER。 標頭名為Authorization ,其值應該是用戶名和密碼組合成一個字符串,“用戶名:密碼”(所有 base64 編碼)。

真誠地,我從未使用 ASP.NET MVC 的基本身份驗證,但我使用 Web API 創建自定義屬性(您可以從這里開始 WebAPI 或這里開始 MVC)。

來自@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 添加身份驗證。

  1. 使用包管理器控制台安裝包:

    安裝包 AuthPackage

  2. 將連接字符串添加到 (appSettings) 中的 Web.config:

     <add key="connectionString" value="connectionStringHere" />
  3. 您已准備好注冊用戶、登錄、注銷

例子:

 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM