您可以使用自定义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()
{
...
}
}
如果您需要更多信息,请查看我在该主题下撰写的这篇博客文章。
filterContext.Result
之前添加以下代码行:filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
,您需要 .NET 4.5 或更高版本。 - Spilarix您可以使用自定义属性来实现此功能。在开源项目SimpleSecurity中,有一个支持基本身份验证的自定义属性实现,您可以在此处下载。有一个参考应用程序以演示如何使用它。它最初是为与MVC 4中的SimpleMembership配合使用而开发的,并最近已经移植到使用MVC 5中的ASP.NET Identity。
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();
}
}
res.end()
的问题已被替换为HttpUnauthorizedResult()
。 - starlockefilterContext.Result = new HttpUnauthorizedResult();
会导致 ASP 将用户重定向到默认的登录页面,而不是让身份验证弹出窗口出现。 - Douglas Gaskell@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"));
}
}
install package using Package Manager Console:
Install-Package AuthPackage
add Connection String to your Web.config in (appSettings):
<add key="connectionString" value="connectionStringHere" />
you're ready to register users, login, logout
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");
}
[BasicAuthenticationAttribute("your-username", "your-password",
BasicRealm = "your-realm")]
有两个缺点:用户名和密码是硬编码的,只支持单个用户。
更灵活的解决方案应该支持在配置中存储多个用户名/密码对。
微软描述了一个示例 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);
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
... other stuff
</system.webServer>
该应用程序已经配置以使用表单身份验证。每当正常的表单认证将被使用时,浏览器身份验证窗口就会弹出。
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"));
filterContext.HttpContext.Response.StatusCode = 401;
filterContext.HttpContext.Response.End();
}
filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
[HttpGet]
[BasicAuthentication("TestUserName", "Abc123*")]
public ActionResult Submit()
{
return new ContentResult() { Content = "You have successfully connected to the AP&G GISB Server." };
}