Aperçu
Je cherche à créer une API (REST) pour mon application. L'objectif initial / principal sera la consommation par les applications mobiles (iPhone, Android, Symbian, etc.). J'ai étudié différents mécanismes d'authentification et d'autorisation pour les API Web (en étudiant d'autres implémentations). J'ai la tête tournée vers la plupart des concepts fondamentaux mais je suis toujours à la recherche de conseils dans quelques domaines. La dernière chose que je veux faire est de réinventer la roue, mais je ne trouve aucune solution standard qui corresponde à mes critères (cependant mes critères peuvent être erronés, alors n'hésitez pas à critiquer cela aussi). De plus, je souhaite que l'API soit la même pour toutes les plates-formes / applications qui la consomment.
oAuth
Je vais aller de l'avant et rejeter mon objection à oAuth car je sais que ce sera probablement la première solution proposée. Pour les applications mobiles (ou plus spécifiquement les applications non Web), il semble tout simplement erroné de quitter l'application (pour accéder à un navigateur Web) pour l'authentification. De plus, il n'y a aucun moyen (à ma connaissance) pour le navigateur de renvoyer le rappel à l'application (en particulier multiplateforme). Je connais quelques applications qui font cela, mais cela ne semble pas juste et donne une pause dans l'application UX.
Exigences
- L'utilisateur entre le nom d'utilisateur / mot de passe dans l'application.
- Chaque appel d'API est identifié par l'application appelante.
- Les frais généraux sont réduits au minimum et l'aspect authentification est intuitif pour les développeurs.
- Le mécanisme est sécurisé tant pour l'utilisateur final (ses informations de connexion ne sont pas exposées) que pour le développeur (leurs informations d'identification d'application ne sont pas exposées).
- Si possible, ne pas exiger https (en aucun cas une exigence stricte).
Mes réflexions actuelles sur la mise en œuvre
Un développeur externe demandera un compte API. Ils recevront un apikey et un apisecret. Chaque demande nécessitera au moins trois paramètres.
- apikey - remis au développeur lors de l'enregistrement
- horodatage - sert également d'identifiant unique pour chaque message pour un apikey donné
- hash - un hachage de l'horodatage + l'apisecret
L'apikey est nécessaire pour identifier l'application émettrice de la demande. L'horodatage agit de la même manière que oauth_nonce et évite / atténue les attaques de relecture. Le hachage garantit que la demande a effectivement été émise par le propriétaire de l'apikey donné.
Pour les demandes authentifiées (celles effectuées pour le compte d'un utilisateur), je suis toujours indécis entre une route access_token ou un combo de hachage nom d'utilisateur et mot de passe. Quoi qu'il en soit, à un moment donné, un combo nom d'utilisateur / mot de passe sera requis. Donc, quand c'est le cas, un hachage de plusieurs informations (apikey, apisecret, horodatage) + le mot de passe serait utilisé. J'aimerais avoir des commentaires sur cet aspect. FYI, ils devraient d'abord hacher le mot de passe, car je ne stocke pas les mots de passe dans mon système sans hachage.
Conclusion
Pour info, il ne s'agit pas d'une demande sur la façon de créer / structurer l'API en général, mais uniquement sur la façon de gérer l'authentification et l'autorisation à partir uniquement d'une application.
Pensées aléatoires / questions bonus
Pour les API qui ne nécessitent qu'un apikey dans le cadre de la demande, comment empêcher quelqu'un d'autre que le propriétaire de l'apikey de pouvoir voir l'apikey (depuis envoyé en clair) et faire des demandes excessives pour les pousser au-delà des limites d'utilisation? Peut-être que je réfléchis juste à cela, mais ne devrait-il pas y avoir quelque chose pour authentifier qu'une demande a été vérifiée auprès du propriétaire de l'apikey? Dans mon cas, c'était le but de l'apisecret, il n'est jamais montré / transmis sans être haché.
En parlant de hachage, qu'en est-il de md5 vs hmac-sha1? Est-ce vraiment important que toutes les valeurs soient hachées avec des données suffisamment longues (c.-à-d. Apisecret)?
J'avais déjà envisagé d'ajouter un sel par utilisateur / ligne au hachage de mot de passe de mes utilisateurs. Si je devais faire cela, comment l'application pourrait-elle créer un hachage correspondant sans connaître le sel utilisé?
Réponses:
La façon dont je pense faire la partie connexion de ceci dans mes projets est:
avant de se connecter, l'utilisateur demande un
login_token
au serveur. Ceux-ci sont générés et stockés sur le serveur sur demande, et ont probablement une durée de vie limitée.pour se connecter, l'application calcule le hachage du mot de passe de l'utilisateur, puis hache le mot de passe avec le
login_token
pour obtenir une valeur, puis renvoie à la fois lelogin_token
hachage et le hachage combiné.Le serveur vérifie
login_token
celui qu'il a généré, le supprimant de sa liste delogin_token
s valides . Le serveur combine ensuite son hachage stocké du mot de passe de l'utilisateur avec lelogin_token
et s'assure qu'il correspond au jeton combiné soumis. Si cela correspond, vous avez authentifié votre utilisateur.Les avantages de ceci sont que vous ne stockez jamais le mot de passe de l'utilisateur sur le serveur, le mot de passe n'est jamais passé en clair, le hachage du mot de passe n'est transmis qu'en clair lors de la création du compte (bien qu'il puisse y avoir des moyens de contourner cela), et cela devrait être à l'abri des attaques de relecture car le
login_token
est supprimé de la base de données lors de l'utilisation.la source
C'est tout un tas de questions en une, je suppose que pas mal de gens n'ont pas réussi à les lire jusqu'au bout :)
Mon expérience de l'authentification de service Web est que les gens la surengine généralement, et les problèmes ne sont que les mêmes que ceux que vous rencontriez sur une page Web. Les options très simples possibles incluraient https pour l'étape de connexion, retourner un jeton, exiger qu'il soit inclus avec les demandes futures. Vous pouvez également utiliser l'authentification de base http, et simplement passer des éléments dans l'en-tête. Pour plus de sécurité, faites régulièrement pivoter / expirez les jetons, vérifiez que les demandes proviennent du même bloc IP (cela peut devenir compliqué lorsque les utilisateurs mobiles se déplacent entre les cellules), combinez-les avec une clé API ou similaire. Sinon, effectuez l'étape «demande de clé» de oauth (quelqu'un l'a déjà suggéré dans une réponse précédente et c'est une bonne idée) avant d'authentifier l'utilisateur, et utilisez-la comme clé requise pour générer le jeton d'accès.
Une alternative que je n'ai pas encore utilisée mais dont j'ai beaucoup entendu parler comme une alternative conviviale à oAuth est xAuth . Jetez-y un coup d'œil et si vous l'utilisez, je serais vraiment intéressé de savoir quelles sont vos impressions.
Pour le hachage, sha1 est un peu meilleur, mais ne vous en faites pas - tout ce que les périphériques peuvent facilement (et rapidement dans un sens des performances) implémenter est probablement bien.
J'espère que cela aide, bonne chance :)
la source
Vous recherchez donc une sorte de mécanisme d'authentification côté serveur qui gérera les aspects d'authentification et d'autorisation d'une application mobile?
En supposant que c'est le cas, je l'aborderais comme suit (mais seulement parce que je suis un développeur Java, donc un gars C # le ferait différemment):
Le service d'authentification et d'autorisation RESTful
La bibliothèque / application de sécurité côté client
Alors maintenant que la vue de 30 000 pieds est complète, comment procédez-vous? Eh bien, il n'est pas si difficile de créer un système d'authentification et d'autorisation basé sur les technologies répertoriées côté serveur avec un client navigateur. En combinaison avec HTTPS, les frameworks fourniront un processus sécurisé basé sur un jeton partagé (généralement présenté comme un cookie) généré par le processus d'authentification et utilisé chaque fois que l'utilisateur souhaite faire quelque chose. Ce jeton est présenté par le client au serveur à chaque fois qu'une demande a lieu.
Dans le cas de l'application mobile locale, il semble que vous recherchiez une solution qui effectue les opérations suivantes:
Quoi que vous fassiez, n'essayez pas d'inventer votre propre protocole de sécurité ou d'utiliser la sécurité par l'obscurité. Vous ne pourrez jamais écrire un meilleur algorithme pour cela que ceux qui sont actuellement disponibles et gratuits. De plus, les gens font confiance à des algorithmes bien connus. Donc, si vous dites que votre bibliothèque de sécurité fournit une autorisation et une authentification pour les applications mobiles locales en utilisant une combinaison de jetons cryptés SSL, HTTPS, SpringSecurity et AES, vous aurez immédiatement une crédibilité sur le marché.
J'espère que cela vous aidera et bonne chance dans votre entreprise. Si vous souhaitez plus d'informations, faites-le moi savoir - j'ai écrit pas mal d'applications Web basées sur Spring Security, les ACL et autres.
la source
Twitter a résolu le problème des applications externes dans oAuth en prenant en charge une variante qu'ils appellent xAuth . Malheureusement, il existe déjà une pléthore d'autres schémas portant ce nom, il peut donc être difficile à résoudre.
Le protocole est oAuth, sauf qu'il ignore la phase de demande de jeton et émet simplement immédiatement une paire de jetons d'accès dès réception d'un nom d'utilisateur et d'un mot de passe. ( À partir de l' étape E ici .) Cette première demande et réponse doivent être sécurisées- il envoie le nom d'utilisateur et le mot de passe en texte clair et reçoit le jeton d'accès et le jeton secret. Une fois la paire de jetons d'accès configurée, le fait que l'échange de jetons initial se soit fait via le modèle oAuth ou le modèle xAuth n'a pas d'importance pour le client et le serveur pour le reste de la session. Cela présente l'avantage de pouvoir tirer parti de l'infrastructure oAuth existante et d'avoir pratiquement la même implémentation pour les applications mobiles / Web / de bureau. Le principal inconvénient est que l'application a accès au nom d'utilisateur et au mot de passe du client, mais il semble que vos exigences exigent cette approche.
Dans tous les cas, j'aimerais être d'accord avec votre intuition et celle de plusieurs autres répondants ici: n'essayez pas de construire quelque chose de nouveau à partir de zéro. Les protocoles de sécurité peuvent être faciles à démarrer mais sont toujours difficiles à bien faire, et plus ils deviennent compliqués, moins vos développeurs tiers sont susceptibles de pouvoir les mettre en œuvre contre eux. Votre protocole hypothétique est très similaire à o (x) Auth - api_key / api_secret, nonce, sha1 hashing - mais au lieu de pouvoir utiliser l'une des nombreuses bibliothèques existantes, vos développeurs vont devoir lancer la leur.
la source
Super tard à la fête mais je voulais ajouter quelques points supplémentaires à considérer pour toute personne intéressée par cette question. Je travaille pour une entreprise qui propose des solutions de sécurité API mobiles ( approv ), donc tout ce domaine est vraiment pertinent pour mes intérêts.
Pour commencer, la chose la plus importante à prendre en compte lors de la tentative de sécurisation d'une API mobile est de savoir combien cela vaut pour vous. . La bonne solution pour une banque est différente de la bonne solution pour quelqu'un qui ne fait que s'amuser.
Dans la solution proposée, vous mentionnez qu'un minimum de trois paramètres sera requis:
L'implication de ceci est que pour certains appels d'API, aucun nom d'utilisateur / mot de passe n'est requis. Cela peut être utile pour les applications où vous ne souhaitez pas forcer une connexion (navigation dans les boutiques en ligne par exemple).
Il s'agit d'un problème légèrement différent de celui de l'authentification des utilisateurs et s'apparente davantage à l'authentification ou à l'attestation du logiciel. Il n'y a pas d'utilisateur, mais vous voulez toujours vous assurer qu'il n'y a pas d'accès malveillant à votre API. Vous utilisez donc votre secret API pour signer le trafic et identifier le code d'accès à l'API comme authentique. Le problème potentiel de cette solution est que vous devez ensuite révéler le secret de chaque version de l'application. Si quelqu'un peut extraire le secret, il peut utiliser votre API, se faire passer pour votre logiciel mais faire ce qu'il veut.
Pour contrer cette menace, vous pouvez faire un tas de choses en fonction de la valeur des données. L'obfuscation est un moyen simple de rendre plus difficile l'extraction du secret. Il existe des outils qui le feront pour vous, plus encore pour Android, mais vous devez toujours avoir du code qui génère votre hachage et une personne suffisamment qualifiée peut toujours simplement appeler la fonction qui effectue le hachage directement.
Un autre moyen de limiter l'utilisation excessive d'une API qui ne nécessite pas de connexion consiste à limiter le trafic et potentiellement identifier et bloquer les adresses IP suspectes. La quantité d'effort que vous souhaitez déployer dépendra en grande partie de la valeur de vos données.
Au-delà de cela, vous pouvez facilement commencer à entrer dans le domaine de mon travail quotidien. Quoi qu'il en soit, c'est un autre aspect de la sécurisation des API que je pense être important et que je voulais signaler.
la source