繁体   English   中英

来自 Android 设备的大量请求时,WEB API 2 上的错误 401

[英]Error 401 on WEB API 2 when there is lot of request from Android device

我正在开发一个 Android 应用程序和一个通信的 Web 服务。 我的 Web 服务位于带有令牌承载身份验证的 WEB API 2 中。

我的问题是,当我从我的 Android 应用程序向我的 Web 服务发送太多请求(15 秒内约 20 个请求)时,WS 响应与

    “401” : “Authorization has been denied for this request”

这仅发生在生产服务器(Amen 主机)和 Android 设备上。 例如,如果我尝试使用 Postman,则一切正常。 所以它与我的生产服务器和/或我的 android 应用程序请求有关。

访问 Web 服务的代码

    URL obj = new URL(SERVEUR_URL + url);
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    con.setRequestMethod("GET");
    con.setRequestProperty("Authorization", "Bearer " + token);
    con.setRequestProperty("Content-Type", "application/json");

    int responseCode = con.getResponseCode();
    String responseMessage = con.getResponseMessage();

我的 Web 服务上的身份验证提供程序是默认的。 没有修改。

来自我的 Android 应用程序的请求(并非每次都有效)

    GET http://api.xxxx.com/api/Weesps/GetAvailableWeesps HTTP/1.1
    Authorization: Bearer XXXX
    Content-Type: application/json
    User-Agent: Dalvik/2.1.0 (Linux; U; Android 6.0; Google Nexus 5X - 6.0.0 - API 23 - 1080x1920 Build/MRA58K)
    Host: api.xxxx.com
    Connection: Keep-Alive
    Accept-Encoding: gzip

来自邮递员的请求(每次都工作)

    GET http://api.xxxx.com/api/Weesps/GetAvailableWeesps HTTP/1.1
    Host: api.xxxx.com
    Connection: keep-alive
    Authorization: Bearer XXXX
    Cache-Control: no-cache
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36         (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
    Postman-Token: bca55154-775d-9709-7a8b-4793393890ad
    Accept: */*
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
    Cookie: dadaproaffinity=14ff51cc869a14d3552485cb4ceee1faa1be7165cc5d4b0e2b19370f11afcbea

我尝试过的:

  • 在本地重现此错误:它可以在来自 android 应用程序或 Postman 的本地服务器(Web 和 SQL 服务器)上正常工作
  • 我检查令牌是否在每个请求中正确发送
  • 来自Android的请求每次都是一样的
  • 试图将缺少的标头添加到我的 android 应用请求中

我花了两天时间解决这个问题并阅读了许多 stackoverflow 帖子,但没有人帮助我。 谢谢你的帮助。

更新 1:

使用 Fiddler,我在 Postman 的 GET 请求中看到,它们是一个 Cookie 标头。 当我们要求不记名令牌时发送此 cookie。

来自服务器的令牌响应示例

    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Length: 691
    Content-Type: application/json;charset=UTF-8
    Expires: -1
    Server: Microsoft-IIS/8.5
    Set-Cookie: .AspNet.Cookies=XXXX; path=/; HttpOnly
    X-Powered-By: ASP.NET
    X-Powered-By: ARR/2.5
    Date: Tue, 31 May 2016 16:55:39 GMT

            {"access_token":"XXXX","token_type":"bearer","expires_in":1209599,"userName":"Foo",".issued":"Tue, 31 May 2016 16:55:40 GMT",".expires":"Tue, 14 Jun 2016 16:55:40 GMT"}

Fiddler 和 Postman 保存了这个 cookie,他们自动将它放入 API 请求中(“来自 Postman 的请求”代码块中的示例)。 当我从 Postman GET 请求中删除 cookie 时,它​​不起作用(就像我的 android 应用程序一样)。

现在,问题是:为什么 WEB API 2 发送 cookie 而不是仅使用令牌? 以及为什么令牌在第一个请求中工作得很好,而在接下来的请求中却不能正常工作?

根据您可以在该页面底部看到的ASP.NET WebAPI2 流程,您的请求似乎总是经过身份验证,但有时无法获得授权。

所以imo, AuthorizationFilter[Authorize] 出于未知原因拒绝了您的一些请求。 我的建议是转储 API 收到的请求以及附加到令牌的声明身份。 尝试看看当您有成功响应时和当您有 401 时它们之间是否存在差异。

这样,您就可以确定是您的请求格式不正确,是声明标识不好还是 AuthorizationFilter 由于其他原因(例如查询过多或其他)拒绝您。

祝你好运 !

更新 1根据您的新输入,我认为您的 Web API 配置为同时使用令牌和 cookie 身份验证。

我在这里看到的是您有两种解决方案:1°/ 将返回的 cookie 存储在您的 Android 应用程序中,并将其用于下一次调用。 在不更改所有 API 的情况下解决问题的最简单和最快的方法,但您存储了一个授权 cookie:它可能导致安全问题(CSRF 攻击)。

2°/ 您可以检查您的身份验证和授权过滤器如何设置为禁用 cookie 身份验证并仅依赖令牌身份验证:因此它将强制所有请求和您的 API 仅使用令牌并防止您遭受 CSRF 攻击。 更复杂,因为您必须深入研究 Web API 配置。

检查以下链接(抱歉,因为我还没有足够的声誉来发布超过 2 个链接,您会在我的答案末尾找到它们作为文本):

  • ASP.net Secure a Web API 2.2[2] :来自底部的“配置授权服务器”一章
  • 关于 Web API 安全性的 MSDN 文章 [3]:有关 Web API 安全性、如何保护它和 CRSF 攻击的更多一般和技术信息

  • StackOverflow .NET cookie 和令牌身份验证 [4]:检查 David Banister 的回答,我认为这正是您想要做的:仅对所有 API 调用使用令牌。

  • StackOverflow 授权过滤器和身份验证 [5]:有关 API 此类机制的更多信息

最后

  • 使用 Web API 和 401 代码进行 Cookie 身份验证 [6] :听起来像是您的实际问题,不是吗?

希望对你有帮助,祝你好运!

// 链接

2:www.asp.net/web-api/overview/security/individual-accounts-in-web-api

3:msdn.microsoft.com/en-us/magazine/dn201748.aspx

4:stackoverflow.com/questions/22568409/mvc-net-cookie-authenticated-system-accessing-a-web-api-with-token-authenticatio

5:stackoverflow.com/questions/21231751/authorize-filter-and-authentication

6:brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/

最后,我得到了我的答案:

当我第一次请求请求时,我的 Web 服务会发送一个名为“dadaproaffinity”的 Cookie。 此 Cookie 由 Postman 自动放置在以下请求中,但不是由 Android HttpUrlConnection 放置。 所以,我只是拿了这个 Cookie,现在我只是在每个带有令牌的请求上添加这个 Cookie。

但是:这个 cookie 是由 IIS 发送的,而不是由我的 Web 服务发送的! 这就是为什么它适用于本地但不适用于生产服务器。 我在谷歌上搜索了这个 cookie,关于它的回复很少。 我在英语中找到的唯一一个是:

    Technical Cookie of IIS Server hosting the site.
    Need to route to the correct server session, in order to keep it active

有没有人有关于这个 IIS Cookie 的更多信息?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM