簡體   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