对 RESTful Web 服务进行身份验证
HTTP 支持使用多种身份验证机制控制对资源的访问。 基本身份验证仅允许具有正确凭据的客户端访问资源。 本文演示了如何使用基本身份验证保护对 RESTful Web 服务资源的访问。
注意
在 iOS 9 及更高版本中,应用传输安全性 (ATS) 会在 Internet 资源(如应用的后端服务器)与应用之间的强制实施安全连接,从而防止意外泄露敏感信息。 由于为 iOS 9 生成的应用中默认启用了 ATS,因此所有连接都受 ATS 安全要求的约束。 如果连接不符合这些要求,它们将失败并出现异常。
如果无法对 Internet 资源使用 HTTPS
协议和安全通信,则可以选择退出 ATS。 这可以通过更新应用的 Info.plist 文件来实现。 有关详细信息,请参阅应用传输安全性。
通过 HTTP 对用户进行身份验证
基本身份验证是 HTTP 支持的最简单身份验证机制,涉及客户端将用户名和密码作为未加密的 base64 编码文本发送。 此功能的工作原理如下:
- 如果 Web 服务收到受保护资源的请求,它将拒绝 HTTP 状态代码为 401(访问被拒绝)的请求,并设置 WWW-Authenticate 响应标头,如下图所示:
- 如果 Web 服务收到受保护资源的请求,并且
Authorization
标头已正确设置,则 Web 服务会响应 HTTP 状态代码 200,该代码指示请求成功,并且请求的信息位于响应中。 下图显示了此方案:
注意
基本身份验证仅应通过 HTTPS 连接使用。 当通过 HTTP 连接使用时,如果攻击者捕获了 HTTP 流量,便可以轻松解码 Authorization
标头。
在 Web 请求中指定基本身份验证
基本身份验证的使用如下所述:
- 字符串“Basic”将添加到请求的
Authorization
标头中。 - 用户名和密码合并为一个字符串,格式为“username:password”,然后对其进行 base64 编码并添加到请求的
Authorization
标头。
因此,用户名为“XamarinUser”,密码为“XamarinPassword”,标头就会变为:
Authorization: Basic WGFtYXJpblVzZXI6WGFtYXJpblBhc3N3b3Jk
HttpClient
类可以在 HttpClient.DefaultRequestHeaders.Authorization
属性上设置 Authorization
标头值。 由于 HttpClient
实例存在于多个请求中,因此 Authorization
标头只需设置一次,而不是发出每个请求时设置,如以下代码示例所示:
public class RestService : IRestService
{
HttpClient _client;
...
public RestService ()
{
var authData = string.Format ("{0}:{1}", Constants.Username, Constants.Password);
var authHeaderValue = Convert.ToBase64String (Encoding.UTF8.GetBytes (authData));
_client = new HttpClient ();
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue ("Basic", authHeaderValue);
}
...
}
然后,当向 Web 服务操作发出请求时,会使用 Authorization
标头对请求进行签名,指示用户是否有权调用该操作。
重要
虽然此代码将凭据存储为常量,但它们不应以不安全的格式存储在已发布的应用程序中。
处理授权标头服务器端
REST 服务应使用 [BasicAuthentication]
属性修饰每个操作。 此属性用于分析 Authorization
标头,并通过将其与存储在 web.config 中的值进行比较来确定 base64 编码凭据是否真实有效。虽然此方法适用于示例服务,但它需要扩展才能用于面向公众的 Web 服务。
在 IIS 使用的基本身份验证模块中,用户根据 Windows 凭据进行身份验证。 因此,用户必须在服务器的域中拥有帐户。 但是,可以将基本身份验证模型配置为允许自定义身份验证,其中用户帐户针对外部源(例如数据库)进行身份验证。 有关详细信息,请参阅 ASP.NET 网站上的 ASP.NET Web API 中的基本身份验证。
注意
基本身份验证不是为了管理退出登录而设计的。因此,用于退出登录的标准基本身份验证方法是结束会话。