1

Je développe une application Android et un service Web qui communiquent. Mon service Web est dans l'API Web 2 avec l'authentification du support de jeton.Erreur 401 sur l'API WEB 2 lorsqu'il y a beaucoup de demande de l'appareil Android

Mon problème est que lorsque je vous envoie trop de demandes (~ 20 demande en 15 secondes) à mon service Web de mon application Android, la réponse WS avec

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

Cela arrive seulement sur le serveur de production (Amen Hoster) ET de l'appareil Android. Par exemple, si j'essaye avec Postman, tout fonctionne bien. C'est donc lié à mon serveur de production et/ou à ma demande d'application Android.

Le code d'accès au service 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(); 

Le fournisseur d'authentification sur mon service Web est le défaut. Pas de modifications

La demande de mon Android App (fonctionne pas à chaque fois)

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 

La demande de Postman (travail à chaque fois)

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 

Ce que j'ai essayé:

  • Reproduisez cette erreur dans loc al: il fonctionne très bien sur le serveur local (serveurs Web et SQL) à partir de l'application Android ou de Postman
  • je vérifie que le jeton a été correctement envoyé dans toutes les demandes
  • La demande d'Android est le même à chaque fois
  • Essayé Pour ajouter l'en-tête manquant à ma demande d'application android

Je passe deux jours sur ce problème et lis beaucoup de posts de stackoverflow mais personne ne m'aide. Merci pour votre aide.

MISE À JOUR 1:

Avec Fiddler je l'ai vu dans la demande GET de Postman, ils étaient un en-tête de Cookie. Ce cookie est envoyé lorsque nous demandons un jeton au porteur.

Exemple de réponse jeton du serveur

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 et Postman sauvé ce cookie et ils ont mis automatiquement dans les requêtes API (par exemple sur la « La demande de Postman » bloc de code). Lorsque je supprime le cookie de la requête Postman GET, cela ne fonctionne pas (tout comme mon application android). Maintenant, la question est la suivante: pourquoi l'API Web 2 envoie-t-elle un cookie au lieu de seulement utiliser le jeton? Et pourquoi le jeton fonctionne bien dans les premières demandes et ne fonctionne pas correctement pour les demandes suivantes?

+0

Une différence qui ressort entre les deux demandes est l'en-tête Cache-Control. Avez-vous essayé de régler cela sur vos demandes Android? – elevine

+0

Salut Elevine, merci de votre lecture. Oui, j'ai essayé avec ou sans le Cache-Control et il n'y a pas de différence – JohnB

Répondre

0

Enfin, j'ai eu ma réponse:

Mon service Web envoie un cookie nommé "dadaproaffinity" la première fois que je demande une requête. Ce cookie a été automatiquement mis à la demande suivante par Postman mais pas par Android HttpUrlConnection. Donc, je prends juste ce cookie et maintenant je viens d'ajouter ce cookie à chaque demande avec le jeton.

Mais: Ce cookie est envoyé par IIS, pas par mon service Web! C'est pourquoi cela fonctionne sur le serveur local mais pas sur le serveur de production. J'ai googlé ce cookie et il y a très peu de réponses à ce sujet. Le seul que je trouve en anglais est:

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

Quelqu'un at-il plus d'informations sur ce cookie IIS?

1

Selon ASP.NET WebAPI2 flow vous pouvez voir au bas de cette page, il semble que vos demandes sont toujours authentifiées, mais parfois ne parviennent pas à obtenir l'autorisation.

Ainsi, le AuthorizationFilter [Authorize] rejette certaines de vos demandes pour une raison inconnue. Ce que je suggère est de vider la demande que votre API reçoit ainsi que l'identité de revendications attachée au jeton. Essayez de voir s'il y a des différences entre eux quand vous avez une réponse réussie et quand vous avez un 401.

De cette façon, vous pouvez être en mesure de déterminer si c'est votre requête qui a été malformée, si c'est l'identité des revendications. ce n'est pas bon ou si c'est le AuthorizationFilter qui vous refuse pour une autre raison (comme trop de requêtes ou autre).

Bonne chance! Selon votre nouvelle entrée, je pense que votre API Web est configurée pour utiliser à la fois l'authentification par jeton et par cookie.

Ce que je vois ici, c'est que vous avez deux solutions: 1 °/Stockez le cookie retourné dans votre application Android et utilisez-le pour les prochains appels. Le moyen le plus simple et le plus rapide de résoudre votre problème sans changer toutes vos API, mais vous stockez un cookie d'autorisation: cela peut conduire à un problème de sécurité (attaques CSRF). 2 °/Vous pouvez vérifier comment vos filtres d'authentification et d'autorisation sont configurés pour désactiver l'authentification par cookie et ne compter que sur l'authentification par jeton: cela obligera toutes les requêtes et votre API à utiliser uniquement le jeton. attaques. Plus complexe parce que vous devez creuser dans votre configuration API Web.

Vérifiez les liens suivants (désolé, que je n'ai pas assez réputation encore pour poster plus de 2 liens par courrier, vous les trouverez sous forme de texte à la fin de ma réponse):

  • ASP.net Secure a Web API 2.2 [2]: dans le chapitre "Configuration du serveur d'autorisation" en bas
  • Article MSDN sur la sécurité de l'API Web [3]: Informations plus générales et techniques sur la sécurité de l'API web, comment le sécuriser et les attaques CRSF

  • StackOverflow .NET cookie et token auth entication [4]: ​​Vérifiez la réponse de David Banister, je pense que c'est exactement ce que vous voulez faire: Utilisez uniquement le jeton pour tous vos appels d'API.

  • StackOverflow filtre Autorisez et authentification [5]: Plus d'informations sur ces mécanismes pour votre API

Et enfin

  • authentification par cookie avec l'API Web et 401 codes [6]: Sons comme votre problème réel, n'est-ce pas?

J'espère que cela vous aide, bonne chance!

// Liens

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-authentifié-système-acessing-a-web-api-avec-token-authentatio

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

Merci, cela m'aide à trouver de nouveaux indices. Vérifiez ma mise à jour de poste – JohnB

+0

Bonjour JohnB, j'ai mis à jour ma réponse. J'espère que cela vous aide. – RynnHeldeD

+0

Merci pour votre aide, j'ai trouvé la solution! – JohnB