11
votes

Authentification croisée ASP.NET MVC

J'ai deux applications Web différentes construites avec ASP.NET MVC. Cette application peut ne pas fonctionner dans le même serveur ni dans le même domaine.

J'aimerais que si un utilisateur se connecte à l'un d'entre eux, il faut automatiquement être de connexion dans l'autre. La même chose devrait fonctionner avec la déconnexion.

Lequel pensez-vous est la meilleure solution? Connaissez-vous un exemple de code?

merci!

--- édité avec plus d'informations ---

Scénario de cas d'utilisation:

L'utilisateur dispose de l'application Web ouverte sur un onglet, et à un moment donné de l'application, il existe un lien qui redirige l'utilisateur à l'application Web B . S'il est connecté sur A , je voudrais lui montrer la page complète, et s'il n'est pas, rediriger le formulaire de connexion.

pourquoi j'ai besoin de le faire:

Applications A et B sont déjà construits. Apparemment, la seule façon d'accéder à B clique sur la liaison située dans A , qui est uniquement montrée si vous avez déjà été enregistré. Le problème est que si vous connaissez l'URL de certaines page de B (sont longues et complexes, mais toujours), vous pouvez l'écrire sur le navigateur et accéder à B , ce qu'il signifie un problème de sécurité.


10 commentaires

Votre base de données est-elle centralisée à la fois pour l'application?


Non, ils ont différentes bases de données.


Partageront-ils les mêmes détails de connexion sur les deux applications? Sera-ils partager le même ASPnetdB? Vous attendez-vous à ce qu'ils disposent des deux applications ouvertes en même temps dans différents onglets de navigateur ou dans une autre instance du navigateur? Pouvez-vous fournir un scénario de cas d'utilisation? tbh cela ressemble à une mauvaise idée.


@Ignacio êtes-vous sérieux? Est-ce que ça marche?


OK, j'aurais peut-être dû fournir plus d'informations. L'utilisateur dispose d'une application Web ouverte sur un onglet et, à un moment donné de l'application, il existe un lien qui redirige l'utilisateur à la deuxième application Web. S'il est connecté dans la première application, je voudrais lui montrer la page complète et s'il n'est pas, rediriger le formulaire de connexion.


OK, vous pouvez donc transmettre des identifiants ou des courriels de l'application A à l'application B de toute façon par localDB ou de cookie. Si le même e-mail ou l'ID utilisateur est disponible sur la deuxième base de données, laissez-lui vous connecter ou bien demander de vous connecter.


L'utilisation des cookies n'est pas une option, car les applications sont dans différents domaines. Voir Stackoverflow.com/Questtions/4781353/...


Qu'en est-il d'utiliser window.postMessage - il permet un domaine croisé? développeur.mozilla.org/en-us/docs/web/ API / fenêtre / PostMessage


@Nikolay Comme j'ai compris que la méthode PostMessage ne fonctionne que si les deux applications sont ouvertes en même temps et dans différents onglets / fenêtres. Lorsque l'utilisateur se connecte dans l'application A, l'autre n'est pas ouvert (en cours d'exécution, mais que la migration ne soit pas ouverte dans un onglet). Peut-être que j'ai oublié le doc, dis-moi si je me trompe.


Que diriez-vous d'une connexion unique (SSO)? Simple-Talk.com/dotnet/asp.net/... Stackoverflow.com/questions/15128624/... Auth0.com/docs/Tutorials/aspnet-mvc4-enterprise-Providers


6 Réponses :


4
votes

Je pense que ce que vous êtes après est CAS (service d'authentification central) https://fr.wikipedia.org/wiki/central_authentication_service

Il existe un nombre de fournisseurs de CAS disponibles. Je vous recommanderais de vérifier cette sortie https://wiki.jasig.org/display/cas/home

Il vous donnera un certain nombre de solutions hors de la case pour activer services Web écrits dans une langue spécifique ou sur la base d'un cadre, utiliser CAS. Cela vous aidera à mettre en œuvre une solution SSO dans une question d'heures


0 commentaires

8
votes

Ma réponse peut ne pas être le meilleur, mais vous pouvez utiliser un mécanisme délicat comme

  1. Chaque fois que vous allez sur une autre application, vous devez passer un jeton de l'application A à B.
  2. validez ce jeton sur le site B.
  3. et autorisé cet utilisateur basé sur jeton. (Je veux dire appliquer une connexion silencieuse ou backdoor)

0 commentaires

4
votes

Merci à la réponse de @kaushik merci strong> j'ai mis en œuvre un code qui corrige mon problème. Je posterai ici la solution que cela fonctionne pour moi, même si ce n'est pas l'optimus.

Tout d'abord, j'ai mis en œuvre dans A fort> méthode pour faire une demande de poste à B fort>. À l'intérieur de cette méthode, je prends l'identifiant de l'utilisateur et je fais un hash fort> de celui-ci avec d'autres paramètres et mots de passe. Ensuite, j'envoie à B fort> l'ID utilisateur, le hachage et un booléen à choisir entre la connexion et la déconnexion. P>

public class ExternalAuthenticationController : Controller
        {

            public ActionResult Index()
            {
                return View();
            }

            public ActionResult Login(string id, string hash, string login)
            {
               // Create the combine string
               string data = //user id + same stuff than in A;

               // Create the hash of the combine string
               HashAlgorithm algorithm = MD5.Create();
               byte[] hashArray =    algorithm.ComputeHash(Encoding.UTF8.GetBytes(data));
               StringBuilder sb = new StringBuilder();
               foreach (byte b in hashArray)
                  sb.Append(b.ToString("X2"));
               string originalHash = sb.ToString();

               // Compare the two hash. If they are the same, create the variable
               if (hash.CompareTo(originalHash) == 0)
               {

               if (System.Web.HttpContext.Current.Application["Auth"] == null)
               {
                   System.Web.HttpContext.Current.Application["Auth"] = false;
               }

               if (Convert.ToBoolean(login))
               {
                   System.Web.HttpContext.Current.Application["Auth"] = true;
               }

              else
              {
                  System.Web.HttpContext.Current.Application["Auth"] = false;
              }
             }
         }


6 commentaires

Oui ça marche pour moi. À qui devrais-je donner la prime? L'une des réponses donne une bonne solution qui aident probablement plus de personnes et l'autre me guider à une solution même quand elle n'est pas pleine ...


Je pense que je ne peux pas la diviser, et avec la réputation que j'ai perdue avec cette prime, j'ai perdu la privilège de commencer une nouvelle haha


Blague une partie, si vous pensez que mon idée vous a aidé à obtenir une solution pour votre problème, vous pouvez me donner votre prime. Après tout, c'est votre décision (:


@Ignacio MD5 Les HASHS ne sont pas sécurisés - ils sont assez faciles à repérer et pas cher à la force brute, d'autant plus que le jeton sécurisé est essentiellement juste un MD5 des détails de l'utilisateur. Au lieu de cela, utilisez plutôt un hachage de force lent et coûteux à la force brute comme PBKDF2 (.NET a pris en charge avec rfc2898trivebytes ). De plus, vous n'avez pas de validation de la source de la demande - Vraiment que vous souhaitez que l'application B n'accepte jamais les demandes de connexion à partir de l'application A. S'ils ont tous deux accès à la même dB, cela est le plus facile avec une clé, stockée dans la DB et Changé régulièrement, que B peut utiliser pour vérifier que la demande est venue de A.


@Keith merci de vous, je ne savais pas cela à propos de MD5, je vais le changer. En ce qui concerne la validation, ils ne partagent pas la BBDD. L'architecture du système complet est probablement mauvaise conception, mais elle ne peut pas être changée maintenant.


@Ignacio sans DB partagée Vous devriez toujours pouvoir faire quelque chose - ajoutez une signature à vos données utilisateur à l'aide d'une clé privée sur A et de la clé publique correspondante sur B pour le vérifier.



5
votes

Vous pouvez mettre en œuvre OAuth dans un projet. Vous pouvez obtenir plus d'aide ici: http://www.openauthentication.org/about


0 commentaires

5
votes

6
votes

Je suppose que vous ne pouvez pas communiquer entre les applications A et B à l'aide d'un magasin partagé. (Cela pourrait permettre une implémentation de session partagée).

La manière la plus standard de l'industrie (OpenID Connect) de faire, c'est comme si certaines des autres réponses ont fait allusion à. Je vais essayer de donner plus de détails pour vous mettre sur la bonne voie.

Les deux applications A et B devraient relier le processus d'authentification à une tierce partie fiduciée (qui pourrait être hébergée à une application différente de A, B ou à une autre application) - appelons-le C

Lorsque l'utilisateur arrive à A ou B (peu importe que B a des URL bizarres compliquées, elle peut toujours bloquer celles-ci) sa demande doit contenir un jeton d'autorisation. Si ce n'est pas le cas, elle n'est pas authentifiée et serait redirigée vers C et présentée avec un mécanisme de connexion - Selon le formulaire Utilisateur / Pass.

Après une connexion réussie, elle est redirigée vers A / B (en fonction de son origine) pour compléter ce qu'elle faisait avec le jeton d'authentification. Maintenant, avoir le jeton d'authentification présent, elle est authentifiée.

Si elle est authentifiée avec A puis redirigée vers B, cette redirection doit également contenir le jeton, B saurait faire confiance à ce jeton.

Maintenant, s'il s'ouvre juste ouvre un nouvel onglet, B ne verrais aucun jeton, et elle serait donc redirigée à c, seulement être redirigée (elle est déjà authentifiée, rappelez-vous?) à b avec le jeton avec le jeton , et maintenant tout va bien.

Ce que j'ai décrit est un flux commun utilisant OpenID Connect, et si vous utilisez .net, je suggère vraiment d'utiliser ItalyServer de ThinkTecture à Faites le travail difficile pour vous et soyez votre "C".

Une autre option, est de payer pour un tel "C" hébergé en tant qu'application SaaS - Check Out Auth0


0 commentaires