2010-03-12 17 views
22

मेरे पास एक परिदृश्य है जिससे मुझे उपयोगकर्ताओं को विंडोज प्रमाणीकरण या फॉर्म प्रमाणीकरण का उपयोग कर एएसपी.नेट एमवीसी वेब एप्लिकेशन के खिलाफ प्रमाणित करने में सक्षम होना आवश्यक है। यदि उपयोगकर्ता आंतरिक नेटवर्क पर है तो वे विंडोज प्रमाणीकरण का उपयोग करेंगे और यदि वे बाहरी रूप से कनेक्ट हो रहे हैं तो वे फॉर्म प्रमाणीकरण का उपयोग करेंगे। मैंने सवाल पूछने वाले बहुत से लोगों को देखा है कि मैं इसके लिए एएसपी.नेट एमवीसी वेब एप्लिकेशन कैसे कॉन्फ़िगर कर सकता हूं, लेकिन मुझे पूर्ण स्पष्टीकरण नहीं मिला है।एएसपी.नेट एमवीसी और मिश्रित मोड प्रमाणीकरण

कृपया कोई कोड उदाहरण के साथ विस्तृत विवरण प्रदान कर सकता है, यह कैसे किया जाएगा?

धन्यवाद।

एलन टी

उत्तर

14

यह mixed authentication mode कहा जाता है। असल में आप इसे एकल एप्लिकेशन के भीतर प्राप्त नहीं कर सकते हैं क्योंकि आईआईएस में एक बार जब आप वर्चुअल निर्देशिका के लिए Windows प्रमाणीकरण सेट अप करते हैं तो यह अब विभिन्न डोमेन से उपयोगकर्ताओं को स्वीकार नहीं करेगा। इसलिए मूल रूप से आपको दो प्रमाणीकरण, विंडोज प्रमाणीकरण के साथ पहला और फॉर्म प्रमाणीकरण का उपयोग करके दूसरा (मुख्य अनुप्रयोग) होना चाहिए। पहले एप्लिकेशन में एक ही पता होगा जो डोमेन उपयोगकर्ता के लिए प्रमाणीकरण टिकट जारी करके मुख्य एप्लिकेशन पर रीडायरेक्ट करेगा।

+0

जानकारी और लिंक के लिए धन्यवाद। मै उसे करने की एक कोशिश तो करूंगा। –

+0

यह एकीकृत मोड का उपयोग करके आईआईएस 7 में काम नहीं करेगा: http://stackoverflow.com/questions/289317/iis7-and-authentication-problems –

+0

मैंने पाया कि यह भी गैरी है। मैं अभी भी इसके लिए एक समाधान ढूंढ रहा हूं क्योंकि मेरे पास दो एमवीसी अनुप्रयोग हैं जिन्हें इस कार्यक्षमता की आवश्यकता होगी। –

13

यह किया जा सकता है। कॉन्फ़िगरेशन को उलट दें, ऐप/रूट को बेनामी और फॉर्म प्रमाणीकरण का उपयोग करने के लिए सेट करें ... इस तरह, आप उसी वेब एप्लिकेशन में मिश्रित प्रमाणीकरण को कॉन्फ़िगर कर सकते हैं, लेकिन यह मुश्किल है। तो सबसे पहले, loginUrl = "~/WinLogin/WinLogin2.aspx" के साथ प्रपत्र प्रमाणीकरण के लिए आपको ऐप कॉन्फ़िगर करें। एमवीसी में, रूटिंग आईआईएस द्वारा निर्धारित प्रमाणीकरण नियमों को ओवरराइड करता है, इसलिए एएसपीएक्स पेज का उपयोग करने की आवश्यकता है, क्योंकि आईआईएस फाइल पर प्रमाणीकरण सेट कर सकता है। रूट वेब एप्लिकेशन पर बेनामी और फॉर्म प्रमाणीकरण सक्षम करें। विंडोज प्रमाणीकरण सक्षम करें और रूट/WinLogin निर्देशिका में अनाम प्रमाणीकरण अक्षम करें। खाता/साइनइन यूआरएल पर रीडायरेक्ट करने के लिए कस्टम 401 और 401.2 त्रुटि पेज जोड़ें।

यह ऑटो साइनइन के लिए विंडोज एकीकृत प्रमाणीकरण का उपयोग करने के लिए पास-थ्रू करने में सक्षम किसी भी ब्राउज़र को अनुमति देगा। हालांकि कुछ डिवाइस क्रेडेंशियल्स (जैसे आईफोन) और साइनइन पेज पर रीडायरेक्ट किए गए ब्लैकबेरी जैसे अन्य उपकरणों के लिए संकेत दिए जाएंगे।

यह कुकी को स्पष्ट रूप से उपयोगकर्ताओं की भूमिकाओं को जोड़कर बनाता है और एक सामान्य सिद्धांत बनाता है ताकि भूमिका-आधारित प्राधिकरण का उपयोग किया जा सके।

WinLogin2.aspx में (IIS में "रूट" वेब अनुप्रयोग के तहत WinLogin निर्देशिका में, और विंडोज प्रमाणीकरण, बेनामी अक्षम, और फॉर्म सक्षम करने के लिए कॉन्फ़िगर किया गया है (जैसा कि बंद नहीं हो सकता है ... नोट IIS शिकायत करेगा जब आप विंडोज़ प्रमाणीकरण सक्षम है, बस ध्यान न दें): AccountController में

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org /TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

    <html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <title></title> 
     <script> 
      window.location.assign('../Account/Signin'); 
     </script> 
    </head> 
    <body> 

    </body> 
    </html> 

:

var logonUser = Request.ServerVariables["LOGON_USER"]; 
     if (!String.IsNullOrWhiteSpace(logonUser)) 
     { 
      if (logonUser.Split('\\').Length > 1) 
      { 
       var domain = logonUser.Split('\\')[0]; 
       var username = logonUser.Split('\\')[1]; 

       var timeout = 30; 

       var encTicket = CreateTicketWithSecurityGroups(false, username, domain, timeout); 

       var authCookie = new HttpCookie(".MVCAUTH", encTicket) { HttpOnly = true }; 
       Response.Cookies.Add(authCookie); 


      } 
      //else 
      //{ 
      // this is a redirect due to returnUrl being WinLogin page, in which logonUser will no longer have domain attached 
      // ignore as forms ticket should already exist 
      //} 

      string returnUrl = Request.QueryString["ReturnUrl"]; 

      if (returnUrl.IsEmpty()) 
      { 
       Response.Redirect("~/"); 
      } 
      else 
      { 
       Response.Redirect(returnUrl); 
      } 
     } 

     public static string CreateTicketWithSecurityGroups(bool rememberMe, string username, string domain, int timeout) 
    { 
     using (var context = new PrincipalContext(ContextType.Domain, domain)) 
     { 
      using (var principal = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username)) 
      { 
       var securityGroups = String.Join(";", principal.GetAuthorizationGroups()); 

       var ticket = 
        new FormsAuthenticationTicket(1, 
                username, 
                DateTime.UtcNow, 
                DateTime.UtcNow.AddMinutes(timeout), 
                rememberMe, 
                securityGroups, 
                "/"); 

       string encTicket = FormsAuthentication.Encrypt(ticket); 
       return encTicket; 
      } 
     } 
    } 

आईआईएस 7.5 में, त्रुटि पृष्ठ क्लिक करें, 401 पेज Redirect401.htm फ़ाइल का रास्ता फ़ाइल, इस कोड के साथ निर्धारित किया है। ..

public ActionResult SignIn() 
    { 
     return View(new SignInModel()); 
    } 

    // 
    // POST: /Account/SignIn 

    [HttpPost] 
    public ActionResult SignIn(SignInModel model, string returnUrl) 
    { 
     if (ModelState.IsValid) 
     { 
      if (Membership.ValidateUser(model.UserName, model.Password)) 
      { 
       string encTicket = CreateTicketWithSecurityGroups(model.RememberMe, model.UserName, model.Domain, FormsAuthentication.Timeout.Minutes); 

       Response.Cookies.Add(new HttpCookie(".MVCAUTH", encTicket)); 

       //var returnUrl = ""; 
       for (var i = 0; i < Request.Cookies.Count; i++) 
       { 
        HttpCookie cookie = Request.Cookies[i]; 
        if (cookie.Name == ".MVCRETURNURL") 
        { 
         returnUrl = cookie.Value; 
         break; 
        } 
       } 

       if (returnUrl.IsEmpty()) 
       { 
        return Redirect("~/"); 
       } 

       return Redirect(returnUrl); 
      } 

      ModelState.AddModelError("Log In Failure", "The username/password combination is invalid"); 
     } 

     return View(model); 
    } 

    // 
    // GET: /Account/SignOut 

    public ActionResult SignOut() 
    { 
     FormsAuthentication.SignOut(); 

     if (Request.Cookies[".MVCRETURNURL"] != null) 
     { 
      var returnUrlCookie = new HttpCookie(".MVCRETURNURL") { Expires = DateTime.Now.AddDays(-1d) }; 
      Response.Cookies.Add(returnUrlCookie); 
     } 

     // Redirect back to sign in page so user can 
     // sign in with different credentials 

     return RedirectToAction("SignIn", "Account"); 

Global.asax में:

protected void Application_BeginRequest(object sender, EventArgs e) 
    { 


     try 
     { 
      bool cookieFound = false; 

      HttpCookie authCookie = null; 

      for (int i = 0; i < Request.Cookies.Count; i++) 
      { 
       HttpCookie cookie = Request.Cookies[i]; 
       if (cookie.Name == ".MVCAUTH") 
       { 
        cookieFound = true; 
        authCookie = cookie; 
        break; 
       } 
      } 

      if (cookieFound) 
      { 
       // Extract the roles from the cookie, and assign to our current principal, which is attached to the HttpContext. 
       FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value); 
       HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(ticket), ticket.UserData.Split(';')); 
      } 



     } 
     catch (Exception ex) 
     { 
      throw; 
     } 

    } 


    protected void Application_AuthenticateRequest() 
    { 
     var returnUrl = Request.QueryString["ReturnUrl"]; 
     if (!Request.IsAuthenticated && 
      !String.IsNullOrWhiteSpace(returnUrl)) 
     { 
      var returnUrlCookie = new HttpCookie(".MVCRETURNURL", returnUrl) {HttpOnly = true}; 
      Response.Cookies.Add(returnUrlCookie); 
     } 
    } 

वेब।config

<!--<authorization> 
    <deny users="?"/> 
</authorization>--> 
<authentication mode="Forms"> 
    <forms name=".MVCAUTH" loginUrl="~/WinLogin/WinLogin2.aspx" timeout="30" enableCrossAppRedirects="true"/> 
</authentication> 
<membership defaultProvider="AspNetActiveDirectoryMembershipProvider"> 
    <providers> 
    <add name="AspNetActiveDirectoryMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider,   System.Web, Version=4.0.0.0, Culture=neutral,   PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADService" connectionProtection="Secure" enablePasswordReset="false" enableSearchMethods="true" requiresQuestionAndAnswer="true" applicationName="/" description="Default AD connection" requiresUniqueEmail="false" clientSearchTimeout="30" serverSearchTimeout="30" attributeMapPasswordQuestion="department" attributeMapPasswordAnswer="division" attributeMapEmail="mail" attributeMapUsername="sAMAccountName" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10" passwordAnswerAttemptLockoutDuration="30" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1"/> 
    </providers> 
</membership><machineKey decryptionKey="..." validationKey="..." /> </system.web><connectionStrings> <add name="ADService" connectionString="LDAP://SERVER:389"/></connectionStrings> 

क्रेडिट http://msdn.microsoft.com/en-us/library/ms972958.aspx

+1

हाय - आप Redirect401.htm फ़ाइल को अतिरिक्त स्क्रिप्ट के माध्यम से पुनर्निर्देशित करते हैं। क्या आप रीडायरेक्ट के रूप में 401.1 के लिए त्रुटि हैंडलिंग सेट करके इसे प्राप्त नहीं कर सकते? आईआईएस में इसका मतलब 401 त्रुटि पृष्ठ के लिए '302 रीडायरेक्ट के साथ प्रतिक्रिया' विकल्प में बदलना होगा। एक पूर्ण यूआरएल का उपयोग करने के लिए कहता है, लेकिन रूट रिश्तेदार भी काम करता है। –

4

यह शायद इस सवाल के तल पर कभी नहीं रहते हैं और करेंगे को बकाया पाया जा, लेकिन मैं लागू करने के लिए क्या

http://mvolo.com/iis-70-twolevel-authentication-with-forms-authentication-and-windows-authentication/

यह कम से वर्णित किया गया था कर रहा था काफी आसान और तुच्छ था। कई अनुप्रयोगों या कुकी हैक की आवश्यकता नहीं थी, केवल FormsAuthModule का विस्तार करना और कुछ web.config परिवर्तन करना।

+1

मुझे लगता है कि आपके द्वारा वर्णित परिदृश्य प्रश्न के परिदृश्य से अलग है। दो-स्तरीय प्रमाणीकरण के लिए उपयोगकर्ता को दोनों खिड़कियों के साथ-साथ फॉर्म प्रमाणीकरण के साथ प्रमाणीकृत होना आवश्यक है। हालांकि हमें आवश्यकता है कि उपयोगकर्ता के प्रकार (इंट्रानेट/इंटरनेट) के आधार पर उन्हें या तो विंडोज़ या फॉर्म आधारित प्रमाणीकरण द्वारा प्रमाणित किया जाना चाहिए – Samra

0

मुझे पता है कि यह एक पुरानी पोस्ट है - लेकिन सब कुछ इंटरनेट पर हमेशा के लिए रहता है!

वैसे भी, मुझे आईआईएस 6 से आईआईएस 8 तक पुरानी वेबसाइट लेनी पड़ी। यह एक वेबफॉर्म वेबसाइट है, लेकिन मुझे लगता है कि यह बहुत ही सरल समाधान वही है।

मुझे त्रुटि मिली: 'System.Web.Security.FormsIdentity' टाइप करने के लिए 'System.Security.Principal.WindowsIdentity' प्रकार का ऑब्जेक्ट डालने में असमर्थ।

मैंने जो कुछ किया वह वेबसाइट के लिए एक नया एप्लिकेशन पूल बना रहा था। इसे बनाते समय, मैंने प्रबंधित पाइपलाइन मोड को 'क्लासिक' पर सेट किया। (यहां और पढ़ें - http://www.hanselman.com/blog/MovingOldAppsFromIIS6ToIIS8AndWhyClassicModeExists.aspx) वेबसाइट के एप्लिकेशन पूल को आपके द्वारा बनाए गए नए पूल में सेट करना न भूलें।

संबंधित मुद्दे