2014-10-23 14 views
10

मैं उनकी भूमिका के आधार पर पृष्ठ के लिए उपयोगकर्ता अनुप्रेषित कोशिश कर रहा हूँ,ASP.NET MVC 5 पहचान 2 लॉग इन रीडायरेक्ट

यह है कि ASP.NET MVC 5 के साथ आते लॉगिन समारोह के डिफ़ॉल्ट कार्यान्वयन है :,

[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) 
{ 
    if (ModelState.IsValid) 
    { 
     var user = await UserManager.FindAsync(model.UserName, model.Password); 
     if (user != null) 
     { 
      await SignInAsync(user, model.RememberMe); 

      //role Employer go to Employer page 
      if (UserManager.IsInRole(user.Id, "Employer")) 
      { 
       return RedirectToAction("Index", "Employer"); 
      } 
      //role Admin go to Admin page 
      else if (UserManager.IsInRole(user.Id, "Admin")) 
      { 
       return RedirectToAction("Index", "Admin"); 
      } 
      else 
      { 
       //no role 
       return RedirectToAction("Index", "Home"); 
      } 
     } 
     else 
     { 
      ModelState.AddModelError("", "Invalid username or password."); 
     } 
    } 

    // If we got this far, something failed, redisplay form 
    return View(model); 
} 

लेकिन वहाँ एक समस्या है, हालांकि साइट th करने के लिए मुझे पुनः निर्देशित किया जाता है:

[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) 
{ 
    if (ModelState.IsValid) 
    { 
     var user = await UserManager.FindAsync(model.UserName, model.Password); 
     if (user != null) 
     { 
      await SignInAsync(user, model.RememberMe); 
      return RedirectToLocal(returnUrl); 
     } 
     else 
     { 
      ModelState.AddModelError("", "Invalid username or password."); 
     } 
    } 

    // If we got this far, something failed, redisplay form 
    return View(model); 
} 

private ActionResult RedirectToLocal(string returnUrl) 
{ 
    if (Url.IsLocalUrl(returnUrl)) 
    { 
     return Redirect(returnUrl); 
    } 
    else 
    { 
     return RedirectToAction("Index", "Employer"); 
    } 
} 

मैं उनकी भूमिका के आधार पर उपयोगकर्ता रीडायरेक्ट करने के लिए सक्षम होना चाहते हैं, मैं इसे इस तरह से करने की कोशिश की ई सही पृष्ठ, अगर मैं url foo.com/admin में टाइप करके नेविगेट करता हूं, जब मैं किसी व्यवस्थापक खाते से लॉग इन नहीं करता हूं, तो साइट मुझे url foo.com/Account/Login?ReturnUrl=%2Fadmin के साथ लॉगिन पृष्ठ पर लाती है , जो अपेक्षित व्यवहार है।

अगर मैं इस समय नियोक्ता खाते से लॉगिन करता हूं, तो यह मुझे नियोक्ता के पृष्ठ पर रीडायरेक्ट करेगा और मुझे नियोक्ता के रूप में लॉग इन करेगा, जो गलत नहीं है, लेकिन यह मामला नहीं होना चाहिए, साइट का उल्लेख होना चाहिए मुझे इसके बजाय एक व्यवस्थापक खाते से लॉगिन करना चाहिए क्योंकि वापसी यूआरएल "व्यवस्थापक" है। मुझे आशा है कि मैं समझ में आ रहा हूं।

उत्तर

16

क्यों नहीं आप जांचते हैं कि आपके कस्टम रीडायरेक्ट से पहले कोई वापसी यूआरएल है या नहीं?

[HttpPost] 
    [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) 
    { 
     if (ModelState.IsValid) 
     { 
       var user = await UserManager.FindAsync(model.UserName, model.Password); 
       if (user != null) 
       { 
        await SignInAsync(user, model.RememberMe); 
        if (String.IsNullOrEmpty(returnUrl)) 
        { 
         if (UserManager.IsInRole(user.Id, "Employer")) 
         { 
          return RedirectToAction("Index", "Employer"); 
         } 
         //role Admin go to Admin page 
         if (UserManager.IsInRole(user.Id, "Admin")) 
         { 
          return RedirectToAction("Index", "Admin"); 
         } 
        } 
        else 
        { 
         return RedirectToLocal(returnUrl); 
        } 
       } 
       else 
       { 
        ModelState.AddModelError("", "Invalid username or password."); 
       } 
     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 

इस तरह यदि आप इसे 401 फेंक होगा foo.com/admin और प्रवेश पर रीडायरेक्ट पर जाएँ। फिर यदि आप नियोक्ता के रूप में लॉग इन करते हैं तो यह 401 फेंक देगा और आपको फिर से लॉगिन करने के लिए रीडायरेक्ट करेगा।

टिप्पणियों से: "क्या मैं अभी रीडायरेक्ट (returnUrl) कर सकता हूं और RedirectToLocal एक्शन विधि को हटा सकता हूं?"

RedirectToLocal(returnUrl) विधि जांच Url.IsLocalUrl(returnUrl)। इसलिए ओपन रीडायरेक्ट अटैक को रोकने के लिए इसकी आवश्यकता है।

+0

हाय, आप कृपया व्याख्या कर सकते हैं क्यों किसी और बयान RedirectToLocal (returnUrl) वापसी; जरूरत है? – Mindless

+0

क्या मैं अभी रीडायरेक्ट (returnUrl) कर सकता हूं और RedirectToLocal एक्शन विधि को हटा सकता हूं? – Mindless

+0

आपको जांच के कारण की आवश्यकता है अगर (यूआरएल।IsLocalUrl (returnUrl)) – tmg

1

2008 में लिखा गया लेख [this] लेख के बावजूद, इस समस्या के समाधान के साथ मुझे मदद मिली। यह आपके कोड विधि को छेड़छाड़ किए बिना उपयोगकर्ताओं को लॉगिन पर रीडायरेक्ट करने के लिए आवश्यक सभी कोड नमूने देता है। यदि आप एक नई भूमिका जोड़ते हैं और उपयोगकर्ताओं को उस भूमिका के साथ रीडायरेक्ट करना चाहते हैं, तो यह web.config में एक लाइन जोड़ने जैसा आसान है।

मैं एक गोचा में आया था। अपने लेख में उन्होंने निम्नलिखित कोड जो आप अपने AccountController जाते थे (या जहाँ भी आप रीडायरेक्ट प्रदर्शन करने के लिए चाहते हैं):

/// <summary> 
/// Redirect the user to a specific URL, as specified in the web.config, depending on their role. 
/// If a user belongs to multiple roles, the first matching role in the web.config is used. 
/// Prioritize the role list by listing higher-level roles at the top. 
/// </summary> 
/// <param name="username">Username to check the roles for</param> 
private void RedirectLogin(string username) 
{ 
    LoginRedirectByRoleSection roleRedirectSection = (LoginRedirectByRoleSection)ConfigurationManager.GetSection("loginRedirectByRole"); 
    foreach (RoleRedirect roleRedirect in roleRedirectSection.RoleRedirects) 
    { 
     if (Roles.IsUserInRole(username, roleRedirect.Role)) 
     { 
      Response.Redirect(roleRedirect.Url); 
     } 
    } 
} 

मेरा आवेदन एक भूमिका प्रदाता खोजने के लिए असफल रहा था, और जब मैं वेब में एक जोड़ा .config, मुझे अपनी भूमिकाओं को खोजने में मुश्किल हो रही थी। मैं भूमिका प्रदाता खाई और UserManager का उपयोग उपयोगकर्ता और भूमिकाओं प्राप्त करने के लिए करने का फैसला किया:

/// <summary> 
    /// Redirect the user to a specific URL, as specified in the web.config, depending on their role. 
    /// If a user belongs to multiple roles, the first matching role in the web.config is used. 
    /// Prioritize the role list by listing higher-level roles at the top. 
    /// </summary> 
    /// <param name="username">Username to check the roles for</param> 
    private void RedirectLogin(string username) 
    { 
     LoginRedirectByRoleSection roleRedirectSection = (LoginRedirectByRoleSection)ConfigurationManager.GetSection("loginRedirectByRole"); 
     var user = UserManager.FindByName(username); 
     var rolesForUser = UserManager.GetRoles(user.Id); 
     foreach (RoleRedirect roleRedirect in roleRedirectSection.RoleRedirects) 
     { 
      if (rolesForUser.Contains(roleRedirect.Role)) 
      { 
       Response.Redirect(roleRedirect.Url); 
      } 
     } 
    } 
संबंधित मुद्दे