ASP.NET MVC 5中的基本身份验证

时间:2013-11-22 11:56:55

标签: asp.net asp.net-mvc authentication asp.net-mvc-5

ASP.NET MVC 5?

中必须采取哪些步骤来实施基本身份验证

我已经读过OWIN不支持无cookie身份验证,基本身份验证通常是否可行?

我需要自定义属性吗?我不确定这些属性是如何工作的。

8 个答案:

答案 0 :(得分:70)

您可以使用自定义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() 
    {
        ...
    }
}

如果您需要其他信息,请查看我就该主题撰写的this blog post

答案 1 :(得分:13)

您可以使用自定义属性执行此操作。自定义属性的实现支持开源项目SimpleSecurity中的基本身份验证,您可以download here。有一个参考应用程序来演示它是如何使用的。它最初是为了与MVC 4中的SimpleMembership一起开发的,最近才开始ported to use ASP.NET Identity in MVC 5

答案 2 :(得分:5)

我想修改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();
    }
}

答案 3 :(得分:2)

HTTP基本身份验证不需要cookie。它基于HTTP请求中的HEADER。标题名为 Authorization ,其值应为用户名和密码,并将其组合成一个字符串“username:password”(所有base64编码)。

此致我从未使用ASP.NET MVC进行基本身份验证,但我使用Web API创建自定义属性(您可以从here开始使用WebAPI或here开始使用MVC)。

答案 4 :(得分:2)

来自@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"));
    }
}

答案 5 :(得分:1)

您可以在Nuget上尝试此套餐(AuthPackage) 它使您可以轻松地为您的asp.net mvc添加身份验证。

  1. 使用Package Manager控制台安装软件包:

    Install-Package AuthPackage

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

     <add key="connectionString" value="connectionStringHere" />
    
  3. 您已准备好注册用户,登录,注销

  4. 示例:

     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");
        }
    

    您可以阅读文档here

答案 6 :(得分:0)

由于Web.config中的以下代码,我们的“意外”应用程序使用了基本身份验证:

<system.webServer>
    <modules>
        <remove name="FormsAuthentication" />
    </modules>
    ... other stuff
</system.webServer>

应用程序另外配置为使用表单身份验证。 无论何时使用普通表单身份验证,都会弹出浏览器身份验证窗口。

答案 7 :(得分:0)

Darkseal’s answer

[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

.Net 核心中的可能实现在 https://github.com/mihirdilip/aspnetcore-authentication-basic