2010-08-30 14 views
8

मैं बुनियादी एकल साइन-ऑन 2 MVC साइटों (उन्हें SiteA और SiteB कहते हैं) के लिए निम्न विधि की तर्ज पर कुछ का उपयोग कर में काम कर रहे:ASP.NET MVC एकल साइन-इन और भूमिकाओं

http://forums.asp.net/p/1023838/2614630.aspx

वे एक ही डोमेन के उप-डोमेन पर हैं और web.config में हैश \ एन्क्रिप्शन कुंजी आदि साझा करते हैं। मैंने कुकी को संशोधित किया है, इसलिए यह उसी डोमेन पर सभी साइट्स तक पहुंच योग्य है। ऐसा लगता है कि यह ठीक काम कर रहा है।

साइटें पर अलग-अलग सर्वर पर समान SQL डेटाबेस तक पहुंच के बिना हैं, इसलिए केवल साइटए में उपयोगकर्ता लॉगिन विवरण हैं। साइटबी में सदस्यता डेटाबेस है, लेकिन खाली उपयोगकर्ताओं के साथ।

यह मेरा आवश्यक परिदृश्य जो है के लिए ठीक काम करता है:

1) उपयोगकर्ता SiteA

2) SiteA (AJAX द्वारा) और SiteB से आवेदन लोड डेटा में लॉग (AJAX JSONP का उपयोग करके)

[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."); 
     } 
    } 

यह कुछ सामान जो मैं सख्त नहीं करता है:

मैं SiteA के लिए मेरे AccountController है, जो जहां "जादू" होता है पर निम्नलिखित लॉगऑन क्रिया है प्रारंभिक परिदृश्य के लिए ly की ज़रूरत है, लेकिन मेरे प्रश्न से संबंधित है। यह प्रमाणीकरण टिकट के UserData में साइटए में लॉगिन पर उपयोगकर्ता के लिए भूमिका सूची डालता है। काम करता है ऊपर

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

सामान के सभी जब तक मैं मिश्रण में भूमिकाओं को जोड़ने: यह तो SiteB पर "बहाल" है Global.asax में पालन करते हुए। चीजें ठीक काम करती हैं अगर मैं केवल [प्राधिकरण] विशेषताओं के साथ साइटबी पर अपने नियंत्रकों \ क्रियाओं को सजाने के लिए तैयार हूं। लेकिन जैसे ही मैं जोड़ता हूं [प्राधिकरण (भूमिकाएं = "TestAdmin")] उपयोगकर्ता अब उस नियंत्रक कार्रवाई तक नहीं पहुंच सकते हैं। जाहिर है मैंने उपयोगकर्ता को TestAdmin भूमिका में जोड़ा है।

अगर मैं SiteB पर Global.asax कोड डीबग, यह ठीक लग रहा है के रूप में मैं Global.asax कोड छोड़, लेकिन तब जब मैं नियंत्रक अपने आप में एक को तोड़ने बिंदु मारा Controller.User और Controller.HttpContext.User है अब एक सिस्टम.Web.Security.RolePrincipal भूमिकाओं के बिना अब सेट।

तो मेरा सवाल है: क्या किसी को पता है कि मैं साइटबी पर भूमिकाओं को कैसे पुनर्स्थापित कर सकता हूं या ऐसा करने का दूसरा तरीका?

उत्तर

2

आप पहले से ही यह काम किया, लेकिन यहाँ हम चले:

यह काम करने के: भूमिका प्रबंधक बंद कर देते हैं। यह एक अजीब व्यवहार नहीं है कि एएसपीनेट ऐसा कर रहा है, क्योंकि आप स्पष्ट रूप से configuration specified के साथ उपयोगकर्ता की भूमिकाओं को देखने के लिए कह रहे हैं।

ऐसा करने का एक और तरीका: दोनों में भूमिका प्रबंधक सक्षम करें। कुकी को साझा करने के लिए configuration का उपयोग करें जैसा कि आप अपने कस्टम कोड में कर रहे हैं। अपने विवरण के आधार पर, आप के रूप में आप प्रमाणीकरण कुकी

आप Application_AuthorizeRequest भूमिकाओं कुकी सेट करने का उपयोग करना चाहिए के लिए एक मिलान विन्यास का उपयोग इसके बारे में चिंता करने के लिए उपयोगकर्ता के लिए भूमिकाओं प्राप्त करने की कोशिश है, जब तक की जरूरत नहीं करना चाहिए? imho राय पहले (प्रमाणीकरण) सबसे अच्छा है, मैंने हमेशा ऐसा किया है और मुद्दों में कभी भाग नहीं लिया।

+0

धन्यवाद। हाँ, उनमें से अधिकतर मैं पहले ही काम कर चुका हूं, लेकिन पुष्टि करना अच्छा है। :) अगर आप कुछ कारण दे सकते हैं तो मैं खुशी से इसे उत्तर के रूप में स्वीकार करूँगा Application_AhenthenticateRequest Application_AuthorizeRequest से बेहतर हो सकता है। – mutex

2

चूंकि ऐसा लगता है कि मैं कुछ अतिरिक्त निष्कर्षों के साथ आंशिक रूप से इसका उत्तर दे सकता हूं। डीबगिंग के बाद इसे थोड़ा और परीक्षण करने के बाद, ऐसा लगता है कि एमवीसी 2 एप्लिकेशन_एट प्रमाणीकरण की आवश्यकता के बाद कुछ अजीब कर रहा है लेकिन मेरे नियंत्रक में प्रवेश करने से पहले। यहाँ अधिक विवरण:

http://forums.asp.net/t/1597075.aspx

का संभावित हल Application_AuthorizeRequest बजाय Application_AuthenticateRequest उपयोग करने के लिए है।

संपादित करें: मुझे विश्वास है कि मुझे अपने मुद्दों का कारण मिला है। मेरे एमवीसी 1 प्रोजेक्ट पर मैंने भूमिका प्रबंधक अक्षम कर दिया था लेकिन मेरे परीक्षण एमवीसी 2 प्रोजेक्ट में भूमिका प्रबंधक सक्षम था। एक बार जब मैंने एमवीसी 1 परीक्षण परियोजना में अपनी भूमिका प्रबंधक को सक्षम किया, तो एमवीसी 1 और एमवीसी 2 के बीच का व्यवहार समान है। मेरे पास एमवीसी माइक्रोसॉफ्ट टीम में से एक के बारे में भी एक प्रश्न है, और अगर यहां प्रमाणीकरण टिकट कुकी से भूमिकाओं को बहाल करने के लिए Application_AuthorizeRequest सही जगह है तो वापस पोस्ट करेंगे ...