1

Я разрабатываю приложение для Android и веб-службу, которые общаются. Моя веб-служба находится в WEB API 2 с аутентификацией на предъявителя маркера.Ошибка 401 на WEB API 2, когда есть много запросов с устройства Android

Моя проблема заключается в том, что, когда я отправить слишком много запросов (~ 20 запроса в течение 15 секунд) на мой веб-службы из моего Android App, ответ WS с

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

Это произойдет только на сервере (Amen hoster) И с устройства Android. Например, если я попытаюсь с Postman, все будет хорошо. Так что это связано с моим производственным сервером и/или моим запросом на приложение для Android.

Код для доступа к веб-службе

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(); 

Поставщик проверки подлинности на моем веб-службы по умолчанию один. Без изменений.

Запрос от моего Android App (не работает каждый раз)

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 

То, что я пробовал:

  • Воспроизвести эту ошибку в местных: она отлично работает на локальном сервере (веб и SQL серверов) из Android App или от Почтальон
  • проверить, что маркер был правильно отправлен в каждом запросов
  • Запрос от Android то же самое каждый раз, когда
  • Попробовал добавить отсутствующий заголовок в мой запрос на приложение для Android.

Я потратил два дня на эту проблему и прочитал много сообщений о stackoverflow, но никто мне не помогает. Спасибо за помощь.

UPDATE 1:

С Скрипач я увидел, что в запросе GET от Postman, они были заголовок 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"} 

Скрипач и Почтальон сохранили это печенье, и они автоматически поместить его в запросах к API (например, на «Запрос от Почтальон» блок кода). Когда я удаляю cookie из запроса Postman GET, он не работает (как и мое приложение для Android).

Теперь возникает вопрос: почему WEB API 2 отправляет cookie вместо использования токена? И почему маркер отлично работает в первых запросах и не работает должным образом для следующих запросов?

+0

Одно из отличий между двумя запросами - это заголовок Cache-Control. Вы пробовали настроить это на свои Android-запросы? – elevine

+0

Привет, подъем, спасибо за чтение. Да, я пытался с или без Cache-Control, и нет никакой разницы. – JohnB

ответ

0

Наконец, я получил ответ:

Моя веб-служба отправляет Cookie с именем «dadaproaffinity» в первый раз, когда я прошу запроса. Этот Cookie автоматически помещался на следующий запрос Postman, но не на Android HttpUrlConnection. Итак, я просто беру этот Cookie, и теперь я просто добавляю этот Cookie по каждому запросу с Token.

Но: Этот файл cookie отправлен IIS, а не моим веб-сервисом! Вот почему он работает на локальном, но не на производственном сервере. Я googled этот cookie, и об этом очень мало ответов. Единственное, что я могу найти на английском языке:

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

У кого-нибудь есть дополнительная информация об этом печенье IIS?

1

Согласно ASP.NET WebAPI2 flow, в нижней части этой страницы вы видите, что ваши запросы всегда аутентифицированы, но иногда не могут быть авторизованы.

Так что imo, AuthorizationFilter [Авторизовать] отклоняет некоторые ваши запросы по неизвестной причине. Я предлагаю вам сбросить запрос, полученный вашим API, а также идентификатор претензий, прикрепленный к токену. Попытайтесь выяснить, существуют ли различия между ними, когда у вас есть успешный ответ, и когда у вас есть 401.

Таким образом, вы можете определить, является ли ваш запрос неправильным, если это идентификатор претензии это не хорошо или если это AuthorizationFilter, который отказывает вам по другой причине (например, слишком много запросов или еще).

Удачи вам!

UPDATE 1 В соответствии с вашим новым входом, я думаю, что ваш Web API настроен для использования как маркеров и проверки подлинности печенья.

Что я вижу здесь, у вас есть два решения: 1 °/Сохраните возвращенный файл cookie в приложении Android и используйте его для следующих вызовов. Самый простой и быстрый способ решить вашу проблему, не изменяя весь ваш API, но вы сохраняете файл cookie авторизации: это может привести к проблеме безопасности (атаки CSRF).

2 °/Вы можете проверить, как настроены фильтры проверки подлинности и авторизации, чтобы отключить аутентификацию cookie и полагаться только на аутентификацию по токенам: это приведет к тому, что все запросы и ваш API будут использовать только токен и не даст вам пострадать от CSRF атаки. Более сложно, потому что вам нужно вникнуть в конфигурацию веб-API.

Проверьте следующие ссылки (извините, так как я не хватает репутации еще размещать более 2 ссылок на пост, вы найдете их как текст в конце моего ответа):

  • ASP.net Secure Web API 2.2 [2]: из главы «Конфигурирование сервера авторизации» внизу
  • Статья MSDN по безопасности веб-API [3]: более общая и техническая информация о безопасности веб-api, как защитить его и атаки CRSF

  • StackOverflow .NET cookie и токены auth [4]: Проверьте ответ Дэвида Банистера, я думаю, что это именно то, что вы хотите сделать: используйте только токен для всех ваших вызовов API.

  • StackOverflow Авторизоваться фильтр и аутентификации [5]: Более подробная информация о таких механизмах для вашего API

И наконец

  • аутентификации Cookie с веб-API и 401 кодов [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/вопросы/22568409/mvc-net-cookie-authenticated-system-acessing-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/

+0

Спасибо, это поможет мне найти новую подсказку. Проверьте мое сообщение обновить – JohnB

+0

Здравствуйте, JohnB, я обновил свой ответ. Надеюсь, это поможет вам. – RynnHeldeD

+0

Спасибо за вашу помощь, я нашел решение! – JohnB