kinght2008 发表于 2017-12-28 23:22:40

ASP.NET Web API Basic Identity 中的基本身份验证

缺点


[*]用户凭证在请求中发送。
[*]凭据作为明文发送。
[*]每个请求都会发送凭据。
[*]无法注销,除非结束浏览器会话。
[*]易于跨站点请求伪造(CSRF); 需要反CSRF措施。
优点


[*]互联网标准。
[*]受所有主要浏览器支持。
[*]相对简单的协议。
基本认证的工作原理如下:


[*]如果请求需要认证,则服务器返回401(未授权)。响应包括WWW-Authenticate头,指示服务器支持基本身份验证。
[*]客户端发送另一个请求,其中的客户端凭证位于授权头中。凭据的格式为字符串“name:password”,base64编码。凭证未加密。
基本认证在“领域”的上下文中执行。服务器包括WWW-Authenticate头中的领域名称。用户的凭据在该领域内有效。领域的确切范围由服务器定义。例如,您可以定义多个领域以分区资源。
https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/basic-authentication/_static/image1.png
因为凭据是未加密发送的,所以基本身份验证仅通过HTTPS安全。请参阅在Web API中使用SSL。
基本认证也容易受到CSRF攻击。在用户输入凭据后,浏览器会在会话持续期间自动将它们发送到同一域的后续请求。这包括AJAX请求。请参阅防止跨站点请求伪造(CSRF)攻击。

使用IIS的基本身份验证

IIS支持基本身份验证,但是有一个警告:用户根据其Windows凭据进行身份验证。这意味着用户必须在服务器的域上有一个帐户。对于面向公众的网站,通常需要对ASP.NET成员资格提供程序进行身份验证。1
要使用IIS启用基本身份验证,请在ASP.NET项目的Web.config中将身份验证模式设置为“Windows”:

复制
xml  

<system.web>  <authentication mode="Windows" />
  
</system.web>
  

  

在此模式下,IIS使用Windows凭据进行身份验证。此外,您必须在IIS中启用基本身份验证。在IIS管理器中,转到功能视图,选择验证,然后启用基本验证。
https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/basic-authentication/_static/image2.png
在Web API项目中,为需要验证的任何控制器操作添加属性。
客户端通过在请求中设置Authorization头来验证自身。浏览器客户端自动执行此步骤。非浏览器客户端将需要设置标头。

使用自定义成员资格的基本身份验证

如上所述,IIS内置的基本身份验证使用Windows凭据。这意味着您需要在托管服务器上为您的用户创建帐户。但对于互联网应用程序,用户帐户通常存储在外部数据库中。
以下代码如何执行基本身份验证的HTTP模块。您可以通过替换CheckPassword方法来轻松插入ASP.NET成员资格提供程序,该方法在本示例中是一个虚拟方法。
在Web API 2中,应考虑编写身份验证过滤器或OWIN中间件,而不是HTTP模块。

复制
C#  

namespace WebHostBasicAuth.Modules  
{

  public>  {
  private const string Realm = "My Realm";
  

  public void Init(HttpApplication context)
  {
  // Register event handlers
  context.AuthenticateRequest += OnApplicationAuthenticateRequest;
  context.EndRequest += OnApplicationEndRequest;
  }
  

  private static void SetPrincipal(IPrincipal principal)
  {
  Thread.CurrentPrincipal = principal;
  if (HttpContext.Current != null)
  {
  HttpContext.Current.User = principal;
  }
  }
  

  // TODO: Here is where you would validate the username and password.
  private static bool CheckPassword(string username, string password)
  {
  return username == "user" && password == "password";
  }
  

  private static void AuthenticateUser(string credentials)
  {
  try
  {
  var encoding = Encoding.GetEncoding("iso-8859-1");
  credentials = encoding.GetString(Convert.FromBase64String(credentials));
  

  int separator = credentials.IndexOf(':');
  string name = credentials.Substring(0, separator);
  string password = credentials.Substring(separator + 1);
  

  if (CheckPassword(name, password))
  {

  var>  SetPrincipal(new GenericPrincipal(identity, null));
  }
  else
  {
  // Invalid username or password.
  HttpContext.Current.Response.StatusCode = 401;
  }
  }
  catch (FormatException)
  {
  // Credentials were not formatted correctly.
  HttpContext.Current.Response.StatusCode = 401;
  }
  }
  

  private static void OnApplicationAuthenticateRequest(object sender, EventArgs e)
  {
  var request = HttpContext.Current.Request;
  var authHeader = request.Headers["Authorization"];
  if (authHeader != null)
  {
  var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
  

  // RFC 2617 sec 1.2, "scheme" name is case-insensitive
  if (authHeaderVal.Scheme.Equals("basic",
  StringComparison.OrdinalIgnoreCase) &&
  authHeaderVal.Parameter != null)
  {
  AuthenticateUser(authHeaderVal.Parameter);
  }
  }
  }
  

  // If the request was unauthorized, add the WWW-Authenticate header
  // to the response.
  private static void OnApplicationEndRequest(object sender, EventArgs e)
  {
  var response = HttpContext.Current.Response;
  if (response.StatusCode == 401)
  {
  response.Headers.Add("WWW-Authenticate",
  string.Format("Basic realm=\"{0}\"", Realm));
  }
  }
  

  public void Dispose()
  {
  }
  }
  
}
  

  

要启用HTTP模块,添加以下在你的web.config文件system.webServer部分:+

复制
xml  

<system.webServer>  <modules>
  <add name="BasicAuthHttpModule"
  
      type="WebHostBasicAuth.Modules.BasicAuthHttpModule, YourAssemblyName"/>
  </modules>
  

  

将“YourAssemblyName”替换为程序集的名称(不包括“dll”扩展名)。
您应该禁用其他身份验证方案,例如Forms或Windows身份验证。
页: [1]
查看完整版本: ASP.NET Web API Basic Identity 中的基本身份验证