34

我正在使用 ASP.Net Web Api 实现一个 RESTful Web 服务。我已经得出结论使用基本身份验证 + SSL 来进行身份验证部分。实现它的最佳/正确方法是什么?

我的第一次尝试是手动进行,解析授权标头,根据我的数据库解码和验证用户。它有效,但我想知道我是否遗漏了什么。

我见过一些使用用户角色和主体的解决方案。虽然我不确定这些实际上做了什么,但我几乎可以肯定我不需要这些,因为在我的数据库中我定义了我自己的用户和他们的角色。

另外,我还没有完全理解的是,服务的消费者是否必须在每个请求中发送凭据,或者它们是否以某种方式被缓存。我的服务应该做些什么来实现这一点,还是完全由消费者来处理?

最后一个关于客户端使用 javascript 发出请求的问题。如果他们尝试使用该服务,会有任何“跨域请求”问题吗?

4

3 回答 3

30

Jamie Kurtze 在ASP.NET Web API REST Security Basics中提供了使用基本身份验证的一个很好的解释

据我了解,如果您希望您的请求是无状态的,那么每个请求都需要设置 Authentication 字段

Jamie Kurtze 将必要的代码包装在派生自 DelegateHandler 的类中,而 Rick Strahl 使用过滤器检查调用是否有效。您可以在他的博客文章中阅读更多关于此主题的信息,网址为A WebAPI 基本身份验证授权过滤器

于 2013-08-13T19:37:40.347 回答
24

[BasicHttpAuthorize]通过将属性添加到适当的控制器/方法,对初始(登录)请求使用基本身份验证。如果需要,使用属性指定用户角色。像这样定义BasicHttpAuthorizeAttribute为一个专门的AuthorizeAttribute

public class BasicHttpAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (Thread.CurrentPrincipal.Identity.Name.Length == 0) { // If an identity has not already been established by other means:
            AuthenticationHeaderValue auth = actionContext.Request.Headers.Authorization;
            if (string.Compare(auth.Scheme, "Basic", StringComparison.OrdinalIgnoreCase) == 0) {
                string credentials = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(auth.Parameter));
                int separatorIndex = credentials.IndexOf(':');
                if (separatorIndex >= 0) {
                    string userName = credentials.Substring(0, separatorIndex);
                    string password = credentials.Substring(separatorIndex + 1);
                    if (Membership.ValidateUser(userName, password))
                        Thread.CurrentPrincipal = actionContext.ControllerContext.RequestContext.Principal = new GenericPrincipal(new GenericIdentity(userName, "Basic"), System.Web.Security.Roles.Provider.GetRolesForUser(userName));
                }
            }
        }
        return base.IsAuthorized(actionContext);
    }
}

让初始响应包含用户的 API 密钥。使用 API 密钥进行后续调用。这样,即使用户更改了用户名或密码,客户端的身份验证仍然有效。但是,在更改密码时,请为用户提供“断开客户端连接”的选项,您可以通过删除服务器上的 API 密钥来实现该选项。

于 2013-09-25T14:16:29.980 回答
1

在这里查看一个好的基本身份验证实现

http://leastprivilege.com/2013/04/22/web-api-security-basic-authentication-with-thinktecture-identitymodel-authenticationhandler/

有更多关于它的阅读: https ://github.com/thinktecture/Thinktecture.IdentityModel.45/wiki

于 2013-06-16T13:10:58.560 回答