ASP.NET MVC Single Sign-on et des Rôles
J'ai de base de l'authentification Unique de travail à travers MVC 2 sites (appeler SiteA et SiteB) à l'aide de quelque chose le long des lignes de la méthode suivante:
http://forums.asp.net/p/1023838/2614630.aspx
Ils sont sur des sous-domaines d'un même domaine et de partager de hachage\clés de chiffrement, etc dans le web.config. J'ai modifié le cookie de sorte qu'il est accessible à tous les Sites sur le même domaine. Tout cela semble fonctionner ok.
Les sites sont sur des serveurs distincts sans accès à la même base de données SQL, de sorte que seulement le SiteA détient le login de l'utilisateur de détails. SiteB a une base de données des membres, mais avec vide utilisateurs.
Cela fonctionne très bien pour mon requises au scénario qui est:
1) l'Utilisateur se connecte à SiteA
2) La charge de l'application des données de SiteA (en AJAX) et SiteB (par AJAX à l'aide de JSONP)
J'ai l'ouverture de session suivant l'Action sur mon AccountController SiteA, qui est l'endroit où la "magie" opère:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, model.RememberMe);
//modify the Domain attribute of the cookie to the second level of domain
//Add roles
string[] roles = Roles.GetRolesForUser(model.UserName);
HttpCookie cookie = FormsAuthentication.GetAuthCookie(User.Identity.Name, false);
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
//Store roles inside the Forms cookie.
FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(ticket.Version, model.UserName,
ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, String.Join("|", roles), ticket.CookiePath);
cookie.Value = FormsAuthentication.Encrypt(newticket);
cookie.HttpOnly = false;
cookie.Domain = ConfigurationManager.AppSettings["Level2DomainName"];
Response.Cookies.Remove(cookie.Name);
Response.AppendCookie(cookie);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
Ce n'est quelques choses que je n'ai pas strictement besoin pour le scénario initial, mais se rapporte à ma question. Il insère la liste des Rôles de l'utilisateur lors de la connexion à SiteA dans le UserData de la ticket d'authentification. C'est ensuite "restauré" sur SiteB par la suite dans le mondial.asax:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (Context.Request.IsAuthenticated)
{
FormsIdentity ident = (FormsIdentity) Context.User.Identity;
string[] arrRoles = ident.Ticket.UserData.Split(new[] {'|'});
Context.User = new System.Security.Principal.GenericPrincipal(ident, arrRoles);
}
}
Toutes les choses ci-dessus fonctionne jusqu'à ce que je ajouter des Rôles dans le mélange. Les choses fonctionnent bien si j'ai seulement décorer mon Contrôleurs\Actions sur SiteB [Autoriser] attributs. Mais dès que j'ajoute [Autoriser(rôles="TestAdmin")] les utilisateurs peuvent accéder n'est plus que l'Action du Contrôleur. Évidemment, j'ai ajouté à l'utilisateur de la TestAdmin Rôle.
Si je déboguer le mondial.asax code sur SiteB, ça à l'air bon comme je l'ai quitter le mondial.asax code, MAIS quand j'ai atteint un point de rupture dans le contrôleur lui-même le Contrôleur.L'utilisateur et le Contrôleur.HttpContext.L'utilisateur est maintenant un Système.Web.De sécurité.RolePrincipal sans le rôle plus défini.
Donc ma question est: est-ce quelqu'un a une idée de comment je peux récupérer les rôles du SiteB ou une autre façon de le faire?
OriginalL'auteur mutex | 2010-08-30
Vous devez vous connecter pour publier un commentaire.
Vous déjà travaillé dessus, mais ici nous allons:
le faire fonctionner: éteindre le rôle de manager. Son pas un comportement bizarre qu'asp.net fait que, comme vous, indiquez explicitement à utiliser look pour les rôles de l'utilisateur avec le configuration spécifiée.
une autre façon de faire: activer le gestionnaire de rôles à la fois. Utiliser le configuration de partager le cookie que vous faites dans votre code personnalisé. En fonction de votre description, vous ne devriez pas avoir à vous soucier d'essayer d'obtenir des rôles de l'utilisateur, aussi longtemps que vous utilisez une configuration correspondante pour le cookie d'authentification
devriez-vous utiliser Application_AuthorizeRequest pour définir les rôles des cookies? à mon humble avis, opinion antérieure (Authentifier) est le meilleur, je l'ai toujours fait de cette façon et n'a jamais couru dans les questions.
OriginalL'auteur eglasius
Puisque cela semble avoir stagné je peux répondre partiellement à celui-ci, avec quelques autres conclusions. Après le débogage\test un peu plus, il semble MVC2 est en train de faire quelque chose de bizarre, après avoir quitté Application_AuthenticateRequest mais avant d'entrer dans mon Contrôleur. Plus de détails ici:
http://forums.asp.net/t/1597075.aspx
Une solution de contournement consiste à utiliser Application_AuthorizeRequest au lieu de Application_AuthenticateRequest.
EDIT: je crois que j'ai trouvé la cause de mes problèmes. Sur mon MVC1 projet que j'avais roleManager désactivé mais mon test de MVC2 projet avait roleManager activé. Une fois que j'ai activé mon roleManager dans le MVC1 projet de test, le comportement entre MVC1 et MVC2 est le même. J'ai aussi une question à l'un des MVC équipe de Microsoft à l'ouvrir à ce sujet, et après revenir ici si Application_AuthorizeRequest est le bon endroit pour restaurer les Rôles de ticket d'Authentification par cookie...
OriginalL'auteur mutex