【问题标题】:Cross platform authentication using ASP.NET Web API使用 ASP.NET Web API 的跨平台身份验证
【发布时间】:2012-04-10 12:14:48
【问题描述】:

我什至如何开始使用 ASP.NET Web API 编写身份验证代码,使其跨平台支持桌面、移动和 Web?我读过一些进行 RESTful 身份验证的方法,例如在标头中使用令牌。

有没有使用这种方法的示例项目?

问题:

  1. 如果不是,我该如何修复[Authorize] 属性来读取令牌?
  2. 如何生成此令牌?我不认为我可以使用表单身份验证,因为它使用 cookie。
  3. 如何处理实际授权,客户端发送原始密码和用户名然后我生成令牌还是有其他方法?
  4. 我的网站在使用时如何处理?我听说这与应用使用它时的处理方式不同,例如获取域并对其进行授权。

【问题讨论】:

    标签: asp.net-mvc rest asp.net-web-api


    【解决方案1】:

    有很多方法可以对 REST 服务的用户进行身份验证。使用令牌是可能的,但仅使用 Basic Authentication 更加简单,并且几乎可以作为标准和跨平台使用。

    不要将authorizationauthentication 混淆。 [Authorize] 属性全部与授权有关,但仅在使用其他机制对用户进行身份验证之后。如果不先进行适当的身份验证,授权是完全没用的。

    检查的最佳资源是Dominick Baier,他是该主题的专家。

    【讨论】:

    • 对于基本身份验证,这是这样做的方法。使用 HTTPS,因为编码只有 base64,不是加密。
    • Dominick Baier 文章的链接已损坏
    【解决方案2】:

    我认为代币将是一个可靠的方法。表单身份验证基于 Web 的 cookie。不过,对于所有非浏览器客户端来说,这并不是最理想的情况。

    我的建议是创建一个自定义 AuthorizationFilterAttribute 并覆盖 OnAuthorization 方法。在该方法中,您可以在客户端提供有效凭据后检查是否存在您颁发给客户端的令牌。您可以在要验证的任何方法或控制器上使用此属性。这是您可能会参考的示例

     public class AuthorizeTokenAttribute : AuthorizationFilterAttribute 
    {      
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            if (actionContext != null)
            {                
                    if (!AuthorizeRequest(actionContext.ControllerContext.Request))
                    {
                        actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized) { RequestMessage = actionContext.ControllerContext.Request }; 
                    }
                    return;
            }
        }
    
        private bool AuthorizeRequest(System.Net.Http.HttpRequestMessage request)
        {
            bool authorized = false;
            if (request.Headers.Contains(Constants.TOKEN_HEADER))
            {               
                var tokenValue = request.Headers.GetValues("TOKEN_HEADER");
                if (tokenValue.Count() == 1) {
                    var value = tokenValue.FirstOrDefault();               
                   //Token validation logic here
                   //set authorized variable accordingly
                }                
            }
            return authorized;
        } }
    

    TOKEN_HEADER 只是一个字符串,表示客户端应为经过身份验证的请求传回的 HTTP 标头。

    让我们来看看吧

    1. 客户端请求安全数据
    2. 客户端未授权,返回带有未授权状态码的响应
    3. 客户端发送凭据进行身份验证,应通过 HTTPS 进行保护
    4. 验证后,客户端会通过 HTTP 标头或任何适合您的方式接收令牌
    5. 客户端再次尝试请求安全数据,这次将令牌附加到请求中
    6. AuthorizeTokenAttribute 将验证令牌并允许执行操作。

    另外,请查看 John Petersen 的这篇文章。 Making your ASP.NET Web API’s secure

    【讨论】:

    • 谢谢,这帮助很大,您建议如何在身份验证期间生成令牌?为用户生成一个 guid 并将其存储在数据库中?
    • 我想这取决于你。您可以使用 Guid 或 Hash 或某种类型的唯一值。取决于什么对您的应用真正有意义
    • 在您的代码注释中,您说“相应地设置授权变量”......授权变量将在哪里设置?在 Request.Properties 上?其他地方?
    • 还可以查看 John Petersen 的这篇更新帖子,他使用 Http 消息处理程序而不是操作过滤器 codebetter.com/johnvpetersen/2012/04/04/…
    • API 应该有一些允许身份验证/授权工作流的端点。就像您有一个网站登录页面
    【解决方案3】:

    我用了一个很简单的方法:

    1. 使用其唯一的 accessId 和 accessKey(例如 MD5 哈希 GUID 值)定义访问配置文件
    2. 将此类访问配置文件存储在数据库中
    3. 每个请求(GET/POST/等)必须提供accessId、queryHash(MD5哈希值代表查询)和签名(queryHash的MD5哈希值+accessKey)。当然,客户需要将 accessKey 保存在安全的地方!!!
    4. 服务器收到请求会检查accessId和签名使用相同的计算算法来拒绝或授予访问(认证)
    5. 可以使用访问配置文件根据请求类型进行进一步授权

    采用这种方法的服务使用新的 ASP.NET MVC Web API 可以服务于任何类型的客户端:浏览器/javascript 和本机(桌面或移动)等。

    【讨论】:

    • 您可能会考虑比 MD5 更强大的东西。在这一点上,它可以很快被破解,想想几分钟或几小时。您应该使用更强大的东西进行散列,例如 SHA256/512,或者最好使用计算速度较慢的东西,例如 bCrypt。 codinghorror.com/blog/2007/09/rainbow-hash-cracking.htmlcodinghorror.com/blog/2012/04/speed-hashing.htmlsecurity.stackexchange.com/questions/211eweek.com/c/a/Security/…
    • 这是一些有用的信息@EBarr(我为你 +1 了),但我认为在这种情况下,他使用 MD5 是安全的,因为他加密的内容对于彩虹来说太大且晦涩难懂表。
    • @Grinn 彩虹表是如此 2005;-)。当然 md5 可能做到了。然而,如今,在强大的 GPU 上,Md5 可以在几分钟内被暴力破解。例如,亚马逊 ec2 GPU 盒只需几美元。
    • @EBarr:我没有意识到这一点。谢谢。
    【解决方案4】:

    U 可以使用 ActionFilterAttribute 并覆盖 OnActionExecuting 方法。 稍后在 global.cs 中注册此过滤器以将此过滤器应用于 Application Start 方法中的所有此类操作

    var config = GlobalConfiguration.Configuration; config.Filters.Add(new CustomAuthAttribute ());

    { 命名空间海关 { 公共类 CustomAuthAttribute : ActionFilterAttribute

    {
    
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            // To inforce HTTPS if desired , else comment out the code
            if (!String.Equals(actionContext.Request.RequestUri.Scheme, "https", StringComparison.OrdinalIgnoreCase))
            {
                actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
                {
                    Content = new StringContent("HTTPS Required")
                };
                return;
            }
    
           // get toekn from the header
    
            var userToken = actionContext.Request.Headers.GetValues("UserToken");
             // Customer Logic to check the validity of the token.
            // U can have some DB logic to check , custom STS behind or some loca cache used to compare the values
    
    
        }
    
    
    }
    

    } }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 2017-10-22
      • 1970-01-01
      • 2013-08-06
      • 2015-09-17
      • 2017-08-02
      • 2023-04-08
      相关资源
      最近更新 更多