From 070bf04a20f472d7de58a20d0c431a6bbf62c176 Mon Sep 17 00:00:00 2001 From: Alper Ebicoglu Date: Wed, 3 Jan 2018 11:07:57 +0300 Subject: [PATCH] Added facebook login... --- src/AbpDesk/AbpDesk.Web.Mvc/Startup.cs | 9 ++ src/AbpDesk/Web_PlugIns/AbpDesk.MongoBlog.dll | Bin 15360 -> 15360 bytes .../Pages/Account/ExternalLogin.cshtml | 29 ++++ .../Pages/Account/ExternalLogin.cshtml.cs | 133 ++++++++++++++++++ .../Pages/Account/Login.cshtml | 74 +++++++--- .../Pages/Account/Login.cshtml.cs | 8 +- .../Identity/EfCoreIdentityUserRepository.cs | 5 +- 7 files changed, 236 insertions(+), 22 deletions(-) create mode 100644 src/Volo.Abp.Account.Web/Pages/Account/ExternalLogin.cshtml create mode 100644 src/Volo.Abp.Account.Web/Pages/Account/ExternalLogin.cshtml.cs 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 e8b4663419530366f7417b0973d815e710d5722c..9dae5160a2294a65da6e60c34129019fefb30883 100644 GIT binary patch delta 44 zcmV+{0Mq|~cz}42hy=Eviu|#RvJwFSvp*A&6A(C8HL7VHt4N*vm3hQ^G1Rl*CLk5L CN)u!N delta 46 zcmV+}0MY+|cz}42hy;%7FOIQ{vJ#Wp5(=|O6NnQK(@`iD+3*%gr$Vbf|0emEv*0Em E73Pl=g#Z8m 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
-
-
-
- - +
+
+ +
+ + +
+
+ + +
+
+ +
+ + + + -
- - -
-
- -
- - - -
+ +
+
+

Use another service to log in.

+
+ @{ + if ((Model.ExternalLogins?.Count ?? 0) == 0) + { +
+

+ There are no external authentication services configured. See this article + for details on setting up this ASP.NET application to support logging in via external services. +

+
+ } + else + { +
+
+

+ @foreach (var provider in Model.ExternalLogins) + { + + } +

+
+
+ } + } +
+
+
\ No newline at end of file diff --git a/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs b/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs index 7a8fc7b14d..39a3e40bb7 100644 --- a/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs +++ b/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs @@ -1,6 +1,9 @@ using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; +using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Volo.Abp.Identity; @@ -15,6 +18,8 @@ namespace Volo.Abp.Account.Web.Pages.Account public string ReturnUrlHash { get; set; } //TODO: Try to automatically bind from querystring! + public IList ExternalLogins { get; set; } + private readonly SignInManager _signInManager; public LoginModel(SignInManager signInManager) @@ -22,10 +27,11 @@ namespace Volo.Abp.Account.Web.Pages.Account _signInManager = signInManager; } - public void OnGet(string returnUrl = "", string returnUrlHash = "") + public async Task OnGetAsync(string returnUrl = "", string returnUrlHash = "") { ReturnUrl = returnUrl; ReturnUrlHash = returnUrl; + ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); } //TODO: Bind input to a property instead of getting as parameter..? diff --git a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs index 70b301e125..8deac6bef1 100644 --- a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs +++ b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs @@ -37,7 +37,10 @@ namespace Volo.Abp.Identity public async Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken) { //TODO: This should be changed since loginProvider, providerKey are not PKs. - var userLogin = await DbContext.UserLogins.FindAsync(new object[] { loginProvider, providerKey }, cancellationToken); + var userLogin = await DbContext.UserLogins + .Where(login => login.LoginProvider == loginProvider && login.ProviderKey == providerKey) + .FirstOrDefaultAsync(cancellationToken); + if (userLogin == null) { return null;