2015-06-03 16 views
8

Tôi đang cố gắng hiểu cách OAuth hoạt động, nhưng nó giống như một chương trình ảo thuật lớn, và tôi không thích điều đó.OAuth với OWIN hoạt động như thế nào trong MVC5?

Tôi đã tạo một dự án MVC5 mới và bật xác thực facebook. Điều này tất cả chỉ hoạt động tốt, tuy nhiên, tôi đang cố gắng để hiểu cách thức hoạt động này.

Đây là phần tôi bị lạc. Hãy tưởng tượng người dùng muốn đăng nhập lần đầu tiên. Phương thức này được thực thi:

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

     // Sign in the user with this external login provider if the user already has a login 
     var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false); 
     switch (result) 
     { 
      case SignInStatus.Success: 
       return RedirectToLocal(returnUrl); 
      case SignInStatus.LockedOut: 
       return View("Lockout"); 
      case SignInStatus.RequiresVerification: 
       return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false }); 
      case SignInStatus.Failure: 
      default: 
       // If the user does not have an account, then prompt the user to create an account 
       ViewBag.ReturnUrl = returnUrl; 
       ViewBag.LoginProvider = loginInfo.Login.LoginProvider; 
       return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email }); 
     } 
    } 

Mã này hiển thị trang đăng nhập FB và FB sẽ quản lý thông tin xác thực. Điều này tất cả hoạt động tốt. Nhưng sau đó, dòng này được thực hiện: var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);. Tôi có thể thấy trong loginInfo rằng tên được đặt, nhưng số result variabel được đặt thành Failure. Tại sao vậy? Người dùng vừa được xác thực bởi FB, vậy tại sao giá trị là false?

Nhưng sau đó, để cảm giác của tôi trở nên kỳ lạ hơn. Khi tôi tiếp tục chạy ứng dụng mẫu, nó yêu cầu tôi nhập một địa chỉ e-mail. Tôi nhập địa chỉ e-mail và thì đấy, tôi đã đăng nhập. Vì tôi đang khám phá toàn bộ thông tin đăng nhập này, tôi đăng xuất và tôi muốn đăng nhập lại. Vì vậy, tôi đăng xuất và đăng nhập lại bằng FB. Và đây là nơi tôi đập đầu vào tường. Khi mã truy cập lại dòng này: var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false); kết quả được đặt thành true !!

Ai đó có thể giải thích cho tôi điều gì đang xảy ra ở đây ??

Trả lời

5

Khi bạn sử dụng đăng nhập bên ngoài, SignInManager xác thực thông tin xác thực người dùng với bên ngoài (trong trường hợp này là Facebook). Nếu bên ngoài đã xác thực thành công thông tin đăng nhập thì SignInManager sẽ kiểm tra xem bản ghi người dùng có hiện diện hay không. Vì đây là lần đầu bạn đăng nhập nên không có bất kỳ hồ sơ người dùng nào khả dụng. Phần này đảm nhiệm rằng:

case SignInStatus.Failure: 
     default: 
      // If the user does not have an account, then prompt the user to create an account 
      ViewBag.ReturnUrl = returnUrl; 
      ViewBag.LoginProvider = loginInfo.Login.LoginProvider; 
      return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email }); 

Điều này cho phép bạn sử dụng địa chỉ email khác. Phổ biến nhất là sử dụng cùng một địa chỉ email!

Một số mẫu: http://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on.

+1

Cảm ơn. Tôi có thể tìm phần mà SignInManager kiểm tra xem bản ghi có ở đâu không? Điều này cảm thấy một loại phép thuật. – Martijn

+2

Tìm thấy nó trên trang web này: https://www.symbolsource.org/MyGet/Metadata/aspnetwebstacknightly/Project/Microsoft.AspNet.Identity.Owin/2.2.0-alpha1-140725/Release/Default/Microsoft.AspNet.Identity .Owin/Microsoft.AspNet.Identity.Owin/SignInManager.cs? ImageName = Microsoft.AspNet.Identity.Owin. –

+1

Có, sau khi nhìn vào nguồn, tôi tin rằng SignInStatus.Failure được đặt tên chỉ để gây nhầm lẫn. Trong khi gọi SignInManager.ExternalSignInAsync(), tôi tin rằng nó chỉ có thể được trả lại cho người dùng không tìm thấy. Nó có thể được trả lại cho các kiểu lỗi khác trong các cuộc gọi khác. – mheyman

Các vấn đề liên quan