diff --git a/src/AbpDesk/AbpDesk.Web.Mvc/Startup.cs b/src/AbpDesk/AbpDesk.Web.Mvc/Startup.cs
index 781db47760..7e0d9ad95a 100644
--- a/src/AbpDesk/AbpDesk.Web.Mvc/Startup.cs
+++ b/src/AbpDesk/AbpDesk.Web.Mvc/Startup.cs
@@ -37,6 +37,15 @@ namespace AbpDesk.Web.Mvc
//);
});
+
+ services.AddAuthentication().AddFacebook(facebookOptions =>
+ {
+ facebookOptions.AppId = "911417875702990";
+ facebookOptions.AppSecret = "adea0bff222ae340d8fb0ce3e6275d6b";
+ });
+
+
+
//TODO: This is needed because ASP.NET Core does not use IServiceProviderFactory!
return services.BuildServiceProviderFromFactory();
}
diff --git a/src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll b/src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll
index e8b4663419..9dae5160a2 100644
Binary files a/src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll and b/src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll differ
diff --git a/src/Volo.Abp.Account.Web/Pages/Account/ExternalLogin.cshtml b/src/Volo.Abp.Account.Web/Pages/Account/ExternalLogin.cshtml
new file mode 100644
index 0000000000..5817404f38
--- /dev/null
+++ b/src/Volo.Abp.Account.Web/Pages/Account/ExternalLogin.cshtml
@@ -0,0 +1,29 @@
+@page
+@model Volo.Abp.Account.Web.Pages.Account.ExternalLoginModel
+@{
+ ViewData["Title"] = "Register";
+}
+
+
@ViewData["Title"]
+Associate your @Model.LoginProvider account.
+
+
+
+ You've successfully authenticated with @Model.LoginProvider.
+ Please enter an email address for this site below and click the Register button to finish
+ logging in.
+
+
+
diff --git a/src/Volo.Abp.Account.Web/Pages/Account/ExternalLogin.cshtml.cs b/src/Volo.Abp.Account.Web/Pages/Account/ExternalLogin.cshtml.cs
new file mode 100644
index 0000000000..7e08a7a805
--- /dev/null
+++ b/src/Volo.Abp.Account.Web/Pages/Account/ExternalLogin.cshtml.cs
@@ -0,0 +1,133 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using Volo.Abp.Identity;
+using Volo.Abp.Uow;
+
+namespace Volo.Abp.Account.Web.Pages.Account
+{
+ public class ExternalLoginModel : AccountModelBase
+ {
+ private readonly SignInManager _signInManager;
+ private readonly UserManager _userManager;
+
+ public ExternalLoginModel(
+ SignInManager signInManager,
+ UserManager userManager)
+ {
+ _signInManager = signInManager;
+ _userManager = userManager;
+ }
+
+ [BindProperty]
+ public InputModel Input { get; set; }
+
+ public string LoginProvider { get; set; }
+
+ public string ReturnUrl { get; set; }
+
+ [TempData]
+ public string ErrorMessage { get; set; }
+
+ public class InputModel
+ {
+ [Required]
+ [EmailAddress]
+ public string Email { get; set; }
+ }
+
+ public IActionResult OnGetAsync()
+ {
+ return RedirectToPage("./Login");
+ }
+
+ [UnitOfWork]
+ public virtual IActionResult OnPost(string provider, string returnUrl = null)
+ {
+ // Request a redirect to the external login provider.
+ var redirectUrl = Url.Page("./ExternalLogin", pageHandler: "Callback", values: new { returnUrl });
+ var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
+ return new ChallengeResult(provider, properties);
+ }
+
+ [UnitOfWork]
+ public virtual async Task OnGetCallbackAsync(string returnUrl = null, string remoteError = null, string returnUrlHash = "")
+ {
+ if (remoteError != null)
+ {
+ ErrorMessage = $"Error from external provider: {remoteError}";
+ return RedirectToPage("./Login");
+ }
+ var info = await _signInManager.GetExternalLoginInfoAsync();
+ if (info == null)
+ {
+ return RedirectToPage("./Login");
+ }
+
+ // Sign in the user with this external login provider if the user already has a login.
+ var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
+ if (result.Succeeded)
+ {
+ return RedirectSafely(returnUrl, returnUrlHash);
+ }
+
+ if (result.IsLockedOut)
+ {
+ return RedirectToPage("./Lockout");
+ }
+
+ // If the user does not have an account, then ask the user to create an account.
+ ReturnUrl = returnUrl;
+ LoginProvider = info.LoginProvider;
+ if (info.Principal.HasClaim(c => c.Type == ClaimTypes.Email))
+ {
+ Input = new InputModel
+ {
+ Email = info.Principal.FindFirstValue(ClaimTypes.Email)
+ };
+ }
+ return Page();
+ }
+
+ [UnitOfWork]
+ public virtual async Task OnPostConfirmationAsync(string returnUrl = null, string returnUrlHash = null)
+ {
+ if (ModelState.IsValid)
+ {
+ // Get the information about the user from the external login provider
+ var info = await _signInManager.GetExternalLoginInfoAsync();
+ if (info == null)
+ {
+ throw new ApplicationException("Error loading external login information during confirmation.");
+ }
+
+ var user = new IdentityUser(GuidGenerator.Create(), Input.Email);
+
+ var result = await _userManager.CreateAsync(user);
+
+ //CheckIdentityErrors( await _userManager.CreateAsync(user));
+
+ if (result.Succeeded)
+ {
+ result = await _userManager.AddLoginAsync(user, info);
+ if (result.Succeeded)
+ {
+ await _signInManager.SignInAsync(user, isPersistent: false);
+
+ return RedirectSafely(returnUrl, returnUrlHash);
+ }
+ }
+ foreach (var error in result.Errors)
+ {
+ ModelState.AddModelError(string.Empty, error.Description);
+ }
+ }
+
+ ReturnUrl = returnUrl;
+ return Page();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml b/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml
index 24e84bfdab..62b8c70dfd 100644
--- a/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml
+++ b/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml
@@ -1,27 +1,61 @@
@page
@model Volo.Abp.Account.Web.Pages.Account.LoginModel