简体   繁体   English

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

[英]Basic authentication in ASP.NET MVC 5

What steps must be done to implement basic authentication in ASP.NET MVC 5?必须执行哪些步骤才能在ASP.NET MVC 5 中实现基本身份验证?

I have read that OWIN does not support cookieless authentication, so is basic authentication generally possible?我读过 OWIN 不支持 cookieless 身份验证,所以基本身份验证通常是可能的吗?

Do I need a custom attribute here?我需要自定义属性吗? I am not sure about how these attributes work.我不确定这些属性是如何工作的。

You can use this simple yet effective mechanism using a custom ActionFilter attribute:您可以使用自定义 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();
    }
}

It can be used to put under Basic Authentication a whole controller:它可用于将整个控制器置于基本身份验证之下:

[BasicAuthenticationAttribute("your-username", "your-password", 
    BasicRealm = "your-realm")]
public class HomeController : BaseController
{
   ...
}

or a specific ActionResult:或特定的 ActionResult:

public class HomeController : BaseController
{
    [BasicAuthenticationAttribute("your-username", "your-password", 
        BasicRealm = "your-realm")]
    public ActionResult Index() 
    {
        ...
    }
}

In case you need additional info check out this blog post that I wrote on the topic.如果您需要更多信息,请查看我在该主题上写的这篇博文

You can do this with a custom attribute.您可以使用自定义属性执行此操作。 There is an implementation of a custom attribute that supports base authentication in the open source project SimpleSecurity , which you can download here .在开源项目SimpleSecurity 中有一个支持基本身份验证的自定义属性的实现,您可以在此处下载 There is a reference application to demonstrate how it is used.有一个参考应用程序来演示它是如何使用的。 It was originally developed to work with SimpleMembership in MVC 4 and has been recently ported to use ASP.NET Identity in MVC 5 .它最初是为了在 MVC 4 中与 SimpleMembership 一起使用而开发的,最近已被移植到在 MVC 5 中使用 ASP.NET Identity

I wanted to amend the answer shared by Darkseal, because that code has a major security flaw.我想修改 Darkseal 分享的答案,因为该代码存在重大安全漏洞。 As written, that action filter does not actually terminate the request when res.End() is called.正如所写,当 res.End() 被调用时,该操作过滤器实际上并没有终止请求。 The user is prompted for credentials and a 401 response is returned if the credentials don't match, but the controller action is still executed on the server side.系统会提示用户输入凭据,如果凭据不匹配,则会返回 401 响应,但控制器操作仍会在服务器端执行。 You need to set the filterContext.Result property to something in order for the request to terminate properly and not continue to the action method.您需要将 filterContext.Result 属性设置为某些内容,以便请求正确终止而不是继续执行操作方法。

This was particularly bad for my situation, as I was trying to protect a web service endpoint that receives a data feed from a third party.这对我的情况尤其不利,因为我试图保护从第三方接收数据馈送的 Web 服务端点。 As written, this action filter didn't protect anything because the data was still being pushed through my action method.正如所写,这个动作过滤器没有保护任何东西,因为数据仍在通过我的动作方法推送。

My "quick fix" is below:我的“快速修复”如下:

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 basic authentication doesn't require a cookie. HTTP 基本身份验证不需要 cookie。 It's based on a HEADER in the HTTP request.它基于 HTTP 请求中的 HEADER。 The header is named Authorization and its value should be username and password combined into a string, "username:password" (all base64 encoded).标头名为Authorization ,其值应该是用户名和密码组合成一个字符串,“用户名:密码”(所有 base64 编码)。

Sincerely I never used basic authentication with ASP.NET MVC, but I used Web API to create a custom attribute (you can start from here for WebAPI or here for MVC).真诚地,我从未使用 ASP.NET MVC 的基本身份验证,但我使用 Web API 创建自定义属性(您可以从这里开始 WebAPI 或这里开始 MVC)。

Great answer from @Darkseal.来自@Darkseal 的好答案。 Here's the same code repurposed for use with ASP.NET Web API (close cousin to MVC).这是重新用于 ASP.NET Web API(MVC 的近亲)的相同代码。 Same idea, slightly different namespaces and context classes.同样的想法,命名空间和上下文类略有不同。 Add it to your classes and methods in exactly the same way.以完全相同的方式将其添加到您的类和方法中。

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

you can try this package on Nuget (AuthPackage) its enables you to add authentication to your asp.net mvc easily.您可以在Nuget (AuthPackage) 上试用这个包,它使您能够轻松地向 asp.net mvc 添加身份验证。

  1. install package using Package Manager Console:使用包管理器控制台安装包:

    Install-Package AuthPackage安装包 AuthPackage

  2. add Connection String to your Web.config in (appSettings):将连接字符串添加到 (appSettings) 中的 Web.config:

     <add key="connectionString" value="connectionStringHere" />
  3. you're ready to register users, login, logout您已准备好注册用户、登录、注销

example:例子:

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

You can read the Documentation here你可以在这里阅读文档

An application of ours "accidentally" used basic authentication because of the following code in Web.config:由于 Web.config 中的以下代码,我们的一个应用程序“意外地”使用了基本身份验证:

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

The application is otherwise configured to use forms authentication.应用程序以其他方式配置为使用表单身份验证。 The browser authentication window popped up whenever normal forms authentication would otherwise have been used.每当使用正常表单身份验证时,都会弹出浏览器身份验证窗口。

The Darkseal's answer黑豹的回答

[BasicAuthenticationAttribute("your-username", "your-password", 
    BasicRealm = "your-realm")]

has 2 disadvantages : name and password are hardcoded and they support only single user.有两个缺点:名称和密码是硬编码的,它们只支持单用户。

More flexible solution should support multiple username/password pairs stored in configuration.更灵活的解决方案应该支持存储在配置中的多个用户名/密码对。

Microsoft describes a sample https://gm/aspnet/samples/tree/main/samples/aspnet/WebApi/BasicAuthentication. Microsoft 描述了一个示例 https://gm/aspnet/samples/tree/main/samples/aspnet/WebApi/BasicAuthentication。

public abstract class BasicAuthenticationAttribute : Attribute, IAuthenticationFilter

In overload of在过载

abstract Task<IPrincipal> AuthenticateAsync(string userName, string password,   
CancellationToken cancellationToken);   

you can implement check to find if username/password from the header exist in configuration/secret list of username/password pairs您可以实施检查以查找标题中的用户名/密码是否存在于用户名/密码对的配置/秘密列表中

It's also possible to create HTTP module that performs Basic Authentication.也可以创建执行基本身份验证的 HTTP 模块。 You can easily plug in an ASP.NET membership provider by replacing the CheckPassword method.您可以通过替换 CheckPassword 方法轻松插入 ASP.NET 成员资格提供程序。 https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/basic-authentication#basic-authentication-with-custom-membership https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/basic-authentication#basic-authentication-with-custom-membership

Example of OWIN implementation https://github.com/scottbrady91/Blog-Example-Classes/tree/master/OwinBasicAuthentication/WebApi OWIN 实现示例https://github.com/scottbrady91/Blog-Example-Classes/tree/master/OwinBasicAuthentication/WebApi

Possible implementation in .Net core is described in https://github.com/mihirdilip/aspnetcore-authentication-basic https://github.com/mihirdilip/aspnetcore-authentication-basic 中描述了 .Net 核心中的可能实现

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM