2015-03-12 7 views
9

मैं Startup.Auth.cs में ऐसा करके एक तरह से सफल रहा हूँ दायरक्या एक एएसपी.नेट एमवीसी अनुप्रयोग में एज़ूर एडी और व्यक्तिगत खाता प्रमाणीकरण दोनों संभव है?

// Configure the db context and user manager to use a single instance per request 
     app.CreatePerOwinContext(ApplicationDbContext.Create); 
     app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
     app.Properties["Microsoft.Owin.Security.Constants.DefaultSignInAsAuthenticationType"] = "ExternalCookie"; 

     // Configure the sign in cookie 
     app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      Provider = new CookieAuthenticationProvider 
      { 
       OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
        validateInterval: TimeSpan.FromMinutes(30), 
        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) 
      } 
     }); 

     app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 

     app.UseOpenIdConnectAuthentication(
      new OpenIdConnectAuthenticationOptions 
      { 
       ClientId = clientId, 
       Authority = authority, 
       PostLogoutRedirectUri = postLogoutRedirectUri 
      }); 

चुनौती मैं है, जब कोई उपयोगकर्ता साइन आउट रहता है, और एक गैर प्रवेश पृष्ठ हिट करने के लिए कोशिश करता है की तरह कहते हैं कि http://mywebsite/users/management है http://mywebsite/account/login के बजाय एप्लिकेशन स्वचालित रूप से Azure AD साइन-इन पृष्ठ पर रीडायरेक्ट करता है, जो सही नहीं है। क्योंकि ऐसे उपयोगकर्ता हो सकते हैं जिनके पास Azure AD पर खाता नहीं है। यहां तक ​​कि यदि हम एडी साइन इन पेज में उचित उपयोगकर्ता आईडी और पासवर्ड देते हैं और साइन-इन पर क्लिक करते हैं, तो यह http://login.windows.net के भीतर विभिन्न यूआरएल के बीच रीडायरेक्ट रखता है और हमारी वेबसाइट पर कभी भी नहीं जाता है। मुझे यकीन है कि मैं गलत यहाँ क्या कर रहा हूँ नहीं कर रहा हूँ

  AuthenticationManager.SignOut(new string[] { DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.ApplicationCookie, OpenIdConnectAuthenticationDefaults.AuthenticationType }); 
     return RedirectToAction("Login", "Account"); 

-

यहाँ लॉगआउट कोड है।

संपादित करें 1 मेरे ExternalLoginCallback विधि

public async Task<ActionResult> ExternalLoginCallback(string returnUrl) 
    { 
     var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); 
     if (loginInfo == null) 
     { 
      return RedirectToAction("Login"); 
     } 

     var claims = new List<Claim>(); 
     claims.Add(new Claim(ClaimTypes.Sid, "Office365")); 

     // Sign in the user with this external login provider if the user already has a login 

     var user = await UserManager.FindByEmailAsync(loginInfo.ExternalIdentity.Name); 

     if (user != null && user.IsActive == true && user.EmailConfirmed == true) 
     { 
      var result = await UserManager.AddLoginAsync(user.Id, loginInfo.Login); 

      if (result.Succeeded) 
      { 
       if (claims != null) 
       { 
        var userIdentity = await user.GenerateUserIdentityAsync(UserManager); 
        userIdentity.AddClaims(claims); 
       } 
      } 

      await SignInAsync(user, isPersistent: true); 
      Session[AppConstants.General.UserID] = user.Id; 

      string fullName = string.Format("{0} {1}",user.FirstName,user.LastName); 
      Session[AppConstants.General.UserFullName] = fullName; 

      return RedirectToLocal(returnUrl); 
     } 
     else 
     { 
      // If the user does not have an account, tell that to the user. 
      ViewBag.ReturnUrl = returnUrl; 
      ViewBag.LoginProvider = loginInfo.Login.LoginProvider; 
      return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email }); 
     } 
    } 

उत्तर

8

इस

app.UseOpenIdConnectAuthentication(
      new OpenIdConnectAuthenticationOptions 
      { 
       ClientId = ClientId, 
       Authority = Authority,     
       Notifications = new OpenIdConnectAuthenticationNotifications() 
       { 


        RedirectToIdentityProvider = (context) => 
        { 

         if (context.Request.Path.Value == "/Account/ExternalLogin" || (context.Request.Path.Value == "/Account/LogOff" && context.Request.User.Identity.IsExternalUser())) 
         { 
          // This ensures that the address used for sign in and sign out is picked up dynamically from the request 
          // this allows you to deploy your app (to Azure Web Sites, for example)without having to change settings 
          // Remember that the base URL of the address used here must be provisioned in Azure AD beforehand. 
          string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase; 
          context.ProtocolMessage.RedirectUri = appBaseUrl + "/"; 
          context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl; 
         } 
         else 
         { 
          //This is to avoid being redirected to the microsoft login page when deep linking and not logged in 
          context.State = Microsoft.Owin.Security.Notifications.NotificationResultState.Skipped; 
          context.HandleResponse(); 
         } 
         return Task.FromResult(0); 
        }, 
       } 
      }); 

संपादित करें का प्रयास करें:

इस विस्तार विधि भूल

public static class IdentityExtensions 
{ 
    public static bool IsExternalUser(this IIdentity identity) 
    { 
     ClaimsIdentity ci = identity as ClaimsIdentity; 

     if (ci != null && ci.IsAuthenticated == true) 
     { 
      var value = ci.FindFirstValue(ClaimTypes.Sid); 
      if (value != null && value == "Office365") 
      { 
       return true; 
      } 
     } 
     return false; 
    } 
} 

संपादित करें 2:

आपको बाहरी लॉजिक कॉलबैक (खाता नियंत्रक) में कुछ कस्टम तर्क होना चाहिए उदा। सिड दावा जोड़ें। इस मामले में यह जांचने के लिए तर्क भी है कि उपयोगकर्ता बाहरी लॉगिन की अनुमति देता है या नहीं।

// GET: /Account/ExternalLoginCallback 
    [AllowAnonymous] 
    public async Task<ActionResult> ExternalLoginCallback(string returnUrl, string urlHash) 
    { 
     var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); 
     if (loginInfo == null) 
     { 
      return RedirectToAction("Login"); 
     } 

     var claims = new List<Claim>(); 
     claims.Add(new Claim(ClaimTypes.Sid, "Office365")); 

     // Sign in the user with this external login provider if the user already has a login 
     var user = await UserManager.FindAsync(loginInfo.Login); 
     if (user == null) 
     { 
      user = await UserManager.FindByNameAsync(loginInfo.DefaultUserName); 

      if (user != null) 
      { 
       if(user.AllowExternalLogin == false) 
       { 
        ModelState.AddModelError("", String.Format("User {0} not allowed to authenticate with Office 365.", loginInfo.DefaultUserName)); 
        return View("Login"); 
       } 
       var result = await UserManager.AddLoginAsync(user.Id, loginInfo.Login); 

       if (result.Succeeded) 
       { 
        if (claims != null) 
        { 
         var userIdentity = await user.GenerateUserIdentityAsync(UserManager); 
         userIdentity.AddClaims(claims); 
        } 
        await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 
       } 
       return RedirectToLocal(returnUrl); 
      } 
      else 
      { 
       ModelState.AddModelError("", String.Format("User {0} not found.", loginInfo.DefaultUserName)); 
       return View("Login"); 
      } 
     } 
     else 
     { 

      if (user.AllowExternalLogin == false) 
      { 
       ModelState.AddModelError("", String.Format("User {0} not allowed to authenticate with Office 365.", loginInfo.DefaultUserName)); 
       return View("Login"); 
      } 

      if (claims != null) 
      { 
       var userIdentity = await user.GenerateUserIdentityAsync(UserManager); 
       userIdentity.AddClaims(claims); 
      } 
      await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 
      return RedirectToLocal(returnUrl); 
     } 
    } 
+0

मैं इस कोशिश की, लेकिन मेरे लिए चर "मूल्य" जब में एक बाहरी उपयोगकर्ता के लॉग रिक्त है। यह मेरे दूसरे app.UseCookieAuthentication() सेटिंग के कारण है? असल में, मैंने अपने ऐप को बदल दिया। OpenIdConnectAuthentication() का उपयोग करें और बाकी के साथ रखें। क्या यह सही है? –

+0

आप सही हैं। Answere में EDIT 2 देखें। यदि आप –

+0

चाहते हैं तो आप निश्चित रूप से बाहरी लॉजिक कॉलबैक फ़ंक्शन को सरल बना सकते हैं, लेकिन मुझे इस लाइन पर शून्य मिलती है - 'कोड' var value = ci.FindFirstValue (System.Security.Claims.ClaimTypes.Sid); –

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