public static ProfileViewModel CreateModel(ExternalLoginInfo loginInfo) { if (loginInfo == null) throw new ArgumentNullException("loginInfo"); var model = new ProfileViewModel(); model.Name = loginInfo.ExternalIdentity.Name; model.Email = loginInfo.Email; var claim = loginInfo.ExternalIdentity.Claims.FirstOrDefault(c => c.Type == "urn:facebook:first_name"); if (claim != null) model.FirstName = claim.Value; claim = loginInfo.ExternalIdentity.Claims.FirstOrDefault(c => c.Type == "urn:facebook:last_name"); if (claim != null) model.LastName = claim.Value; claim = loginInfo.ExternalIdentity.Claims.FirstOrDefault(c => c.Type == "urn:facebook:gender"); if (claim != null) model.Gender = claim.Value; DateTime birthDay = DateTime.MinValue; claim = loginInfo.ExternalIdentity.Claims.FirstOrDefault(c => c.Type == "urn:facebook:birthday"); if (claim != null && DateTime.TryParseExact(claim.Value, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out birthDay)) model.BirthDay = birthDay; return model; }
public async Task AssociateLoginToUserAsync(string email, ExternalLoginInfo externalLoginInfo) { if (string.IsNullOrWhiteSpace(email)) return; var user = await _userManager.FindByNameAsync(email); if (user == null) return; await _userManager.AddLoginAsync(user.Id, externalLoginInfo.Login); }
private ActionResult ProcessSignInStatus(string returnUrl, SignInStatus result, ExternalLoginInfo loginInfo) { switch (result) { case SignInStatus.Success: return this.RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return this.View("Lockout"); default: this.CreateAndSignInNewUser(loginInfo); return this.RedirectToLocal(returnUrl); } }
public static async Task<ApplicationUser> CreateUserFromIdentityAsync(this ApplicationUserManager manager, ExternalLoginInfo externalLogin) { var user = new ApplicationUser { UserName = externalLogin.DefaultUserName, Email = externalLogin.Email }; foreach(var claim in externalLogin.ExternalIdentity.Claims.Where(c=>c.Type.StartsWith("urn:github:"))) user.Claims.Add(new IdentityUserClaim() {ClaimType = claim.Type, ClaimValue = claim.Value, UserId = user.Id}); var result = await manager.CreateAsync(user); return result.Succeeded ? user : null; }
public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var verifiedAccessToken = await VerifyExternalAccessToken(model.Provider, model.ExternalAccessToken); if (verifiedAccessToken == null) { return BadRequest("Invalid Provider or External Access Token"); } IdentityUser user = null; user = await _repo.FindAsync(new UserLoginInfo(model.Provider, verifiedAccessToken.user_id)); bool hasRegistered = user != null; if (hasRegistered) { return BadRequest("External user is already registered"); } user = new IdentityUser() { UserName = model.UserName }; IdentityResult result = await _repo.CreateAsync(user); if (!result.Succeeded) { return GetErrorResult(result); } var info = new ExternalLoginInfo() { DefaultUserName = model.UserName, Login = new UserLoginInfo(model.Provider, verifiedAccessToken.user_id) }; result = await _repo.AddLoginAsync(user.Id, info.Login); if (!result.Succeeded) { return GetErrorResult(result); } //generate access token response var accessTokenResponse = GenerateLocalAccessTokenResponse(model.UserName); return Ok(accessTokenResponse); }
public SignInStatus ExternalSignIn( ExternalLoginInfo loginInfo, bool isPersistent) { var user = _userManager.Find(loginInfo.Login); if (user == null) { return SignInStatus.Failure; } if (_userManager.IsLockedOut(user.Id)) { return SignInStatus.LockedOut; } return SignInOrTwoFactor(user, isPersistent); }
private void CreateAndSignInNewUser(ExternalLoginInfo loginInfo) { var user = new User { UserName = loginInfo.DefaultUserName, Email = loginInfo.Email }; IdentityResult identityResult = this.usersManager.Create(user); if (!identityResult.Succeeded) { return; } identityResult = this.usersManager.AddLogin(user.Id, loginInfo.Login); if (identityResult.Succeeded) { this.loginManager.SignIn(user, false, false); } }
public async Task VerifyAccountControllerExternalLoginWithTokensFlow() { // Setup the external cookie like it would look from a real OAuth2 var externalId = "<externalId>"; var authScheme = "<authScheme>"; var externalIdentity = new ClaimsIdentity(); externalIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, externalId)); var externalPrincipal = new ClaimsPrincipal(externalIdentity); var externalLogin = new ExternalLoginInfo(externalPrincipal, authScheme, externalId, "displayname") { AuthenticationTokens = new[] { new AuthenticationToken { Name = "refresh_token", Value = "refresh" }, new AuthenticationToken { Name = "access_token", Value = "access" } } }; var auth = new Mock<AuthenticationManager>(); auth.Setup(a => a.AuthenticateAsync(It.IsAny<AuthenticateContext>())).Returns(Task.FromResult(0)); var context = new Mock<HttpContext>(); context.Setup(c => c.Authentication).Returns(auth.Object).Verifiable(); var contextAccessor = new Mock<IHttpContextAccessor>(); contextAccessor.Setup(a => a.HttpContext).Returns(context.Object); var services = new ServiceCollection(); services.AddLogging(); services.AddSingleton(contextAccessor.Object); services.AddIdentity<TestUser, TestRole>(); services.AddSingleton<IUserStore<TestUser>, InMemoryStore<TestUser, TestRole>>(); services.AddSingleton<IRoleStore<TestRole>, InMemoryStore<TestUser, TestRole>>(); var app = new ApplicationBuilder(services.BuildServiceProvider()); app.UseCookieAuthentication(); // Act var user = new TestUser { UserName = "******" }; var userManager = app.ApplicationServices.GetRequiredService<UserManager<TestUser>>(); var signInManager = app.ApplicationServices.GetRequiredService<SignInManager<TestUser>>(); IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user)); IdentityResultAssert.IsSuccess(await userManager.AddLoginAsync(user, new UserLoginInfo(authScheme, externalId, "whatever"))); IdentityResultAssert.IsSuccess(await signInManager.UpdateExternalAuthenticationTokensAsync(externalLogin)); Assert.Equal("refresh", await userManager.GetAuthenticationTokenAsync(user, authScheme, "refresh_token")); Assert.Equal("access", await userManager.GetAuthenticationTokenAsync(user, authScheme, "access_token")); }
public static async Task UpdateClaimsFromExternalIdentityAsync(this ApplicationUserManager manager, ApplicationUser user, ExternalLoginInfo externalLogin) { foreach (var claim in user.Claims .Where(c=> c.ClaimType.StartsWith("urn:github")) .Select(c => new Claim(c.ClaimType, c.ClaimValue)) .ToList()) { await manager.RemoveClaimAsync(user.Id, claim); } foreach (var claim in externalLogin.ExternalIdentity.Claims .Where(c => c.Type.StartsWith("urn:github:")) .Select(c=>new Claim(c.Type, c.Value)) .ToList()) { await manager.AddClaimAsync(user.Id, claim); } }
public ActionResult ExternalSignIn(string provider, string returnUrl) { #if DEBUG if (provider == "demo") { var signInInfo = new ExternalLoginInfo { DefaultUserName = "******", Email = "*****@*****.**", ExternalIdentity = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.NameIdentifier, "abc123") }), Login = new UserLoginInfo("demo", "abc123") }; return ExternalSignInCore(returnUrl, signInInfo); } #endif // Request a redirect to the external sign in provider return new ChallengeResult(provider, Url.Action("ExternalSignInCallback", "Account", new { ReturnUrl = returnUrl })); }
public static async Task<ExternalLoginInfo> GetExternalLoginInfoWithBeaerAsync(this IAuthenticationManager manager) { ExternalLoginInfo loginInfo = null; var result = await manager.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer); if (result != null && result.Identity != null) { var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier); if (idClaim != null) { loginInfo = new ExternalLoginInfo() { DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""), Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value) }; } } return loginInfo; }
private ActionResult ExternalSignInCore(string returnUrl, ExternalLoginInfo signInInfo) { if (signInInfo == null) return RedirectToAction("SignIn"); var login = signInInfo.Login; var claimsIdentity = new ClaimsIdentity(signInInfo.ExternalIdentity.Claims, DefaultAuthenticationTypes.ApplicationCookie.ToString()); claimsIdentity.AddClaim(new Claim(CustomClaimTypes.IdentityProvider, login.LoginProvider)); claimsIdentity.AddClaim(new Claim(CustomClaimTypes.HasedUserId, (login.LoginProvider + "|" + login.ProviderKey + "|" + AppSettings.Salt).ToMD5())); this.AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); #region Summary: // Add information to the response environment that will cause the appropriate // authentication middleware to grant a claims-based identity to the recipient // of the response. The exact mechanism of this may vary. Examples include // setting a cookie, to adding a fragment on the redirect url, or producing // an OAuth2 access code or token response. // // Parameters: // properties: // Contains additional properties the middleware are expected to persist along // with the claims. These values will be returned as the AuthenticateResult.properties // collection when AuthenticateAsync is called on subsequent requests. // // identities: // Determines which claims are granted to the signed in user. The ClaimsIdentity.AuthenticationType // property is compared to the middleware's Options.AuthenticationType value // to determine which claims are granted by which middleware. The recommended // use is to have a single ClaimsIdentity which has the AuthenticationType matching // a specific middleware. #endregion this.AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = false }, claimsIdentity); return RedirectToLocal(returnUrl); }
public async Task GetExternalLoginTest() { var mockManager = new Mock<IAuthenticationManager>(); var props = new AuthenticationProperties(); var loginInfo = new ExternalLoginInfo { Login = new UserLoginInfo("loginProvider", "key"), DefaultUserName = "******" }; var identity = CreateIdentity(loginInfo); mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) .Returns(Task.FromResult(new AuthenticateResult(identity, props, new AuthenticationDescription()))); var manager = mockManager.Object; var externalInfo = await manager.GetExternalLoginInfoAsync(); Assert.NotNull(externalInfo); Assert.Equal(identity, externalInfo.ExternalIdentity); Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); Assert.Equal("HaoKung", externalInfo.DefaultUserName); }
public async Task GetExternalIdentityTest() { var mockManager = new Mock<IAuthenticationManager>(); var props = new AuthenticationProperties(); var loginInfo = new ExternalLoginInfo { Login = new UserLoginInfo("loginProvider", "key"), DefaultUserName = "******" }; mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) .Returns( Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, new AuthenticationDescription()))); var manager = mockManager.Object; var id = await manager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); Assert.NotNull(id); var idClaim = id.FindFirst(ClaimTypes.NameIdentifier); Assert.NotNull(idClaim); Assert.Equal(loginInfo.Login.LoginProvider, idClaim.Issuer); Assert.Equal(loginInfo.Login.ProviderKey, idClaim.Value); Assert.Equal(loginInfo.DefaultUserName, id.Name); }
public Task<SignInStatus> ExternalSignInAsync(ExternalLoginInfo loginInfo, bool isPersistent = false) { return _singInManager.ExternalSignInAsync(loginInfo, isPersistent); }
public static string[] CreateAndLoginUser(string username, string email, string name, IEnumerable <Claim> claims, ExternalLoginInfo externalLoginInfo, string userClass = null) { var manager = GetUserManager(); var user = GetIdentityUser(username, email, name, userClass); AddClaimsToUser(user, claims); var result = manager.CreateAsync(user).Result; if (result.Succeeded) { result = manager.AddLoginAsync(user, externalLoginInfo).Result; if (result.Succeeded) { ServiceLocator.Current.GetInstance <IMiniSessionService>().CommitChanges(); SignIn(externalLoginInfo, isPersistent: false); // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 // var code = manager.GenerateEmailConfirmationToken(user.Id); // Send this link via email: IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id) //IdentityHelper.RedirectToReturnUrl(returnUrl, HttpContext.Current.Response); return(new string[0]); } } return(ReportErrors(result.Errors)); }
protected Claim GetClaim(ExternalLoginInfo info, string accessTokenKey) { Claim claim = info.ExternalIdentity.Claims.FirstOrDefault(x => x.Type == accessTokenKey); return(claim); }
private async Task <string> GenerateUsername(ExternalLoginInfo info) { var now = new TimeSpan(_clock.UtcNow.Ticks) - new TimeSpan(DateTime.UnixEpoch.Ticks); var ret = string.Concat("u" + Convert.ToInt32(now.TotalSeconds).ToString()); var registrationSettings = (await _siteService.GetSiteSettingsAsync()).As <RegistrationSettings>(); var externalClaims = info == null ? null : info.Principal.GetSerializableClaims(); if (registrationSettings.UseScriptToGenerateUsername) { var context = new { userName = string.Empty, loginProvider = info?.LoginProvider, externalClaims }; var jsonSerializerSettings = new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() }; var script = $"js: function generateUsername(context) {{\n{registrationSettings.GenerateUsernameScript}\n}}\nvar context = {JsonConvert.SerializeObject(context, jsonSerializerSettings)};\ngenerateUsername(context);\nreturn context;"; try { dynamic evaluationResult = _scriptingManager.Evaluate(script, null, null, null); if (evaluationResult?.userName == null) { throw new Exception("GenerateUsernameScript did not return a username"); } return(evaluationResult.userName); } catch (Exception ex) { _logger.LogError(ex, "Error evaluating GenerateUsernameScript({context})", context); } } else { var userNames = new Dictionary <Type, string>(); foreach (var item in _externalLoginHandlers) { try { var userName = await item.GenerateUserName(info.LoginProvider, externalClaims.ToArray()); if (!string.IsNullOrWhiteSpace(userName)) { if (userNames.Count == 0) { ret = userName; } userNames.Add(item.GetType(), userName); } } catch (Exception ex) { _logger.LogError(ex, "{externalLoginHandler} - IExternalLoginHandler.GenerateUserName threw an exception", item.GetType()); } } if (userNames.Count > 1) { _logger.LogWarning("More than one IExternalLoginHandler generated username. Used first one registered, {externalLoginHandler}", userNames.FirstOrDefault().Key); } } return(ret); }
public async Task <IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } ApplicationUser user; //if (model.Provider != "Twitter") //{ // var verifiedAccessToken = await VerifyExternalAccessToken(model.Provider, model.ExternalAccessToken); // if (verifiedAccessToken == null) // { // return BadRequest("Invalid Provider or External Access Token"+model.ExternalAccessToken +"provider"+ model.Provider ); // } // model.UserId = verifiedAccessToken.user_id; // user = await _repo.FindAsync(new UserLoginInfo(model.Provider, model.UserId)); //} //else { user = await _repo.FindAsync(new UserLoginInfo(model.Provider, model.UserId)); } var hasRegistered = user != null; if (hasRegistered) { // return BadRequest("External user is already registered"); var token = GenerateLocalAccessTokenResponseUpdate(user); return(Ok(token)); } if (string.IsNullOrWhiteSpace(model.Name)) { model.Name = model.Provider + "User"; } user = new ApplicationUser { UserName = model.UserName, FullName = model.Name }; var result = await _repo.CreateAsync(user); if (!result.Succeeded) { return(GetErrorResult(result)); } var info = new ExternalLoginInfo { DefaultUserName = model.UserName, Login = new UserLoginInfo(model.Provider, model.UserId) }; result = await _repo.AddLoginAsync(user.Id, info.Login); if (!result.Succeeded) { return(GetErrorResult(result)); } //generate access token response user = await _repo.FindAsync(new UserLoginInfo(model.Provider, model.UserId)); var accessTokenResponse = GenerateLocalAccessTokenResponseUpdate(user); return(Ok(accessTokenResponse)); }
public async Task <object> Register([FromBody] RegisterModel model) { ExternalLoginInfo externalLoginInfo = null; if (model.LinkExternalLogin) { externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync(); if (externalLoginInfo == null) { ModelState.AddModelError(string.Empty, "Unsuccessful login with service"); } else { var existingLogin = await _userManager.FindByLoginAsync(externalLoginInfo.LoginProvider, externalLoginInfo.ProviderKey); if (existingLogin != null) { ModelState.AddModelError(string.Empty, "An account is already associated with this login server."); } } } if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.UserName, Email = model.Email }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); var callbackUrl = Url.RouteUrl("confirmemail", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme); await _emailSender.SendEmailAsync(model.Email, "Confirm your account", "Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>"); // add the external login to the account if (externalLoginInfo != null) { var addLoginResult = await _userManager.AddLoginAsync(user, externalLoginInfo); if (!addLoginResult.Succeeded) { foreach (var error in addLoginResult.Errors) { // TODO: log } } } await _signInManager.SignInAsync(user, false); return(new { success = true, user = ReactBoilerplate.Models.Api.User.From(user) }); } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } return(new { success = false, errors = GetModelState() }); }
private async Task <IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model) { _logger.Debug("ini RegisterExternal - process"); if (!ModelState.IsValid) { _logger.Debug("RegisterExternal - ModelState inIsValid"); return(BadRequest(ModelState)); } var verifiedAccessToken = await Helpers.VerifyExternalAccessToken(model.Provider, model.ExternalAccessToken); if (verifiedAccessToken == null) { _logger.Debug("RegisterExternal - Invalid Provider or External Access Token"); return(BadRequest("Invalid Provider or External Access Token")); } User user = await _appUserManager.FindAsync(new UserLoginInfo(model.Provider, verifiedAccessToken.user_id)); bool hasRegistered = user != null; if (hasRegistered) { _logger.Debug("RegisterExternal - External user is already registered"); return(BadRequest("External user is already registered")); } user = new User { UserName = model.UserName, Email = model.Email }; IdentityResult result = await _appUserManager.CreateAsync(user); if (!result.Succeeded) { _logger.Debug("RegisterExternal -CreateAsync- result fail"); return(GetErrorResult(result)); } _appUserManager.AddToRole(user.Id, "member"); _appUserManager.AddClaim(user.Id, new Claim(ClaimTypes.Authentication, model.Provider)); var info = new ExternalLoginInfo { DefaultUserName = model.UserName, Login = new UserLoginInfo(model.Provider, verifiedAccessToken.user_id) }; result = await _appUserManager.AddLoginAsync(user.Id, info.Login); if (!result.Succeeded) { _logger.Debug("RegisterExternal -AddLoginAsync- result fail"); return(GetErrorResult(result)); } //generate access token response ClaimsIdentity identity = _appUserManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie); var accessTokenResponse = Helpers.GenerateLocalAccessTokenResponse(user.UserName, identity); _logger.Debug(string.Format("RegisterExternal - Ok,idUser:{0},email:{1}", user.Id, user.Email)); _appUserManager.Update(user); return(Ok(accessTokenResponse)); }
public static ApplicationExternalLoginInfo ToApplicationExternalLoginInfo(this ExternalLoginInfo externalLoginInfo) { return(externalLoginInfo == null ? null : new ApplicationExternalLoginInfo { DefaultUserName = externalLoginInfo.DefaultUserName, Email = externalLoginInfo.Email, ExternalIdentity = externalLoginInfo.ExternalIdentity, Login = externalLoginInfo.Login.ToApplicationUserLoginInfo() }); }
public async Task<IActionResult> ExternalLoginCallback(string returnUrl) { var errors = new List<string>(); ExternalLoginInfo loginInfo = await _memberSignInManager.GetExternalLoginInfoAsync(); if (loginInfo is null) { errors.Add("Invalid response from the login provider"); } else { SignInResult result = await _memberSignInManager.ExternalLoginSignInAsync(loginInfo, false); if (result == SignInResult.Success) { // Update any authentication tokens if succeeded await _memberSignInManager.UpdateExternalAuthenticationTokensAsync(loginInfo); return RedirectToLocal(returnUrl); } if (result == SignInResult.TwoFactorRequired) { MemberIdentityUser attemptedUser = await _memberManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey); if (attemptedUser == null) { return new ValidationErrorResult( $"No local user found for the login provider {loginInfo.LoginProvider} - {loginInfo.ProviderKey}"); } // create a with information to display a custom two factor send code view var verifyResponse = new ObjectResult(new { userId = attemptedUser.Id }) { StatusCode = StatusCodes.Status402PaymentRequired }; return verifyResponse; } if (result == SignInResult.LockedOut) { errors.Add( $"The local member {loginInfo.Principal.Identity.Name} for the external provider {loginInfo.ProviderDisplayName} is locked out."); } else if (result == SignInResult.NotAllowed) { // This occurs when SignInManager.CanSignInAsync fails which is when RequireConfirmedEmail , RequireConfirmedPhoneNumber or RequireConfirmedAccount fails // however since we don't enforce those rules (yet) this shouldn't happen. errors.Add( $"The member {loginInfo.Principal.Identity.Name} for the external provider {loginInfo.ProviderDisplayName} has not confirmed their details and cannot sign in."); } else if (result == SignInResult.Failed) { // Failed only occurs when the user does not exist errors.Add("The requested provider (" + loginInfo.LoginProvider + ") has not been linked to an account, the provider must be linked before it can be used."); } else if (result == MemberSignInManager.ExternalLoginSignInResult.NotAllowed) { // This occurs when the external provider has approved the login but custom logic in OnExternalLogin has denined it. errors.Add( $"The user {loginInfo.Principal.Identity.Name} for the external provider {loginInfo.ProviderDisplayName} has not been accepted and cannot sign in."); } else if (result == MemberSignInManager.AutoLinkSignInResult.FailedNotLinked) { errors.Add("The requested provider (" + loginInfo.LoginProvider + ") has not been linked to an account, the provider must be linked from the back office."); } else if (result == MemberSignInManager.AutoLinkSignInResult.FailedNoEmail) { errors.Add( $"The requested provider ({loginInfo.LoginProvider}) has not provided the email claim {ClaimTypes.Email}, the account cannot be linked."); } else if (result is MemberSignInManager.AutoLinkSignInResult autoLinkSignInResult && autoLinkSignInResult.Errors.Count > 0) { errors.AddRange(autoLinkSignInResult.Errors); }
public SignInStatus ExternalSignIn(ExternalLoginInfo loginInfo, HttpContextBase context) { if (loginInfo.Login.LoginProvider == "Facebook") { var user = usersDao.FindByFacebookKey(loginInfo.Login.ProviderKey); if (user != null) { var ident = new ClaimsIdentity( new[] { new Claim(ClaimTypes.NameIdentifier, user.username), new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"), new Claim(ClaimTypes.Name, user.username) }, DefaultAuthenticationTypes.ApplicationCookie); context.GetOwinContext().Authentication.SignIn( new AuthenticationProperties { IsPersistent = false }, ident); return(SignInStatus.Success); } } if (loginInfo.Login.LoginProvider == "Google") { var user = usersDao.FindByGoogleKey(loginInfo.Login.ProviderKey); if (user != null) { var ident = new ClaimsIdentity( new[] { new Claim(ClaimTypes.NameIdentifier, user.username), new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"), new Claim(ClaimTypes.Name, user.username) }, DefaultAuthenticationTypes.ApplicationCookie); context.GetOwinContext().Authentication.SignIn( new AuthenticationProperties { IsPersistent = false }, ident); return(SignInStatus.Success); } } if (loginInfo.Email != null) { var emailUser = usersDao.GetUserByName(loginInfo.Email); if (emailUser != null) { bool login = false; if (loginInfo.Login.LoginProvider == "Facebook") { emailUser.fbkey = loginInfo.Login.ProviderKey; usersDao.updateUser(emailUser); login = true; } if (loginInfo.Login.LoginProvider == "Google") { emailUser.gkey = loginInfo.Login.ProviderKey; usersDao.updateUser(emailUser); login = true; } if (login) { var ident = new ClaimsIdentity( new[] { new Claim(ClaimTypes.NameIdentifier, emailUser.username), new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"), new Claim(ClaimTypes.Name, emailUser.username) }, DefaultAuthenticationTypes.ApplicationCookie); context.GetOwinContext().Authentication.SignIn( new AuthenticationProperties { IsPersistent = false }, ident); return(SignInStatus.Success); } } } return(SignInStatus.Failure); }
public async Task <ActionResult> MainPage() { ExternalLoginInfo loginInfo = await AuthManager.GetExternalLoginInfoAsync(); return(View(GetData("MainPage", loginInfo))); }
private async Task AddClaimsForNewUser(ExternalLoginInfo info, GGCharityUser user) { foreach (var claim in info.ExternalIdentity.Claims) { if (!claim.Type.Equals(ClaimTypes.NameIdentifier)) { await Data.PerformAsync(async () => { await UserManager.AddClaimAsync(user.Id, claim); }); } } }
private bool IsUcdLogin(ExternalLoginInfo info) { return(info.LoginProvider.Equals("UCDavis", StringComparison.OrdinalIgnoreCase)); }
public virtual async Task <ActionResult> Register(RegisterViewModel model) { try { CheckSelfRegistrationIsEnabled(); if (!model.IsExternalLogin && UseCaptchaOnRegistration()) { var recaptchaHelper = this.GetRecaptchaVerificationHelper(); if (recaptchaHelper.Response.IsNullOrEmpty()) { throw new UserFriendlyException(L("CaptchaCanNotBeEmpty")); } if (recaptchaHelper.VerifyRecaptchaResponse() != RecaptchaVerificationResult.Success) { throw new UserFriendlyException(L("IncorrectCaptchaAnswer")); } } if (!_multiTenancyConfig.IsEnabled) { model.TenancyName = Tenant.DefaultTenantName; } else if (model.TenancyName.IsNullOrEmpty()) { throw new UserFriendlyException(L("TenantNameCanNotBeEmpty")); } CurrentUnitOfWork.SetTenantId(null); var tenant = await GetActiveTenantAsync(model.TenancyName); CurrentUnitOfWork.SetTenantId(tenant.Id); if (!await SettingManager.GetSettingValueForTenantAsync <bool>(AppSettings.UserManagement.AllowSelfRegistration, tenant.Id)) { throw new UserFriendlyException(L("SelfUserRegistrationIsDisabledMessage_Detail")); } //Getting tenant-specific settings var isNewRegisteredUserActiveByDefault = await SettingManager.GetSettingValueForTenantAsync <bool>(AppSettings.UserManagement.IsNewRegisteredUserActiveByDefault, tenant.Id); var isEmailConfirmationRequiredForLogin = await SettingManager.GetSettingValueForTenantAsync <bool>(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin, tenant.Id); var user = new User { TenantId = tenant.Id, Name = model.Name, Surname = model.Surname, EmailAddress = model.EmailAddress, IsActive = isNewRegisteredUserActiveByDefault }; ExternalLoginInfo externalLoginInfo = null; if (model.IsExternalLogin) { externalLoginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); if (externalLoginInfo == null) { throw new ApplicationException("Can not external login!"); } user.Logins = new List <UserLogin> { new UserLogin { LoginProvider = externalLoginInfo.Login.LoginProvider, ProviderKey = externalLoginInfo.Login.ProviderKey, TenantId = tenant.Id } }; model.UserName = model.EmailAddress; model.Password = Authorization.Users.User.CreateRandomPassword(); if (string.Equals(externalLoginInfo.Email, model.EmailAddress, StringComparison.InvariantCultureIgnoreCase)) { user.IsEmailConfirmed = true; } } else { if (model.UserName.IsNullOrEmpty() || model.Password.IsNullOrEmpty()) { throw new UserFriendlyException(L("FormIsNotValidMessage")); } } user.UserName = model.UserName; user.Password = new PasswordHasher().HashPassword(model.Password); user.Roles = new List <UserRole>(); foreach (var defaultRole in await _roleManager.Roles.Where(r => r.IsDefault).ToListAsync()) { user.Roles.Add(new UserRole(tenant.Id, user.Id, defaultRole.Id)); } CheckErrors(await _userManager.CreateAsync(user)); await _unitOfWorkManager.Current.SaveChangesAsync(); if (!user.IsEmailConfirmed) { user.SetNewEmailConfirmationCode(); await _userEmailer.SendEmailActivationLinkAsync(user); } //Notifications await _notificationSubscriptionManager.SubscribeToAllAvailableNotificationsAsync(user.ToUserIdentifier()); await _appNotifier.WelcomeToTheApplicationAsync(user); await _appNotifier.NewUserRegisteredAsync(user); //Directly login if possible if (user.IsActive && (user.IsEmailConfirmed || !isEmailConfirmationRequiredForLogin)) { AbpLoginResult <Tenant, User> loginResult; if (externalLoginInfo != null) { loginResult = await _loginManager.LoginAsync(externalLoginInfo.Login, tenant.TenancyName); } else { loginResult = await GetLoginResultAsync(user.UserName, model.Password, tenant.TenancyName); } if (loginResult.Result == AbpLoginResultType.Success) { await SignInAsync(loginResult.User, loginResult.Identity); return(Redirect(Url.Action("Index", "Application"))); } Logger.Warn("New registered user could not be login. This should not be normally. login result: " + loginResult.Result); } return(View("RegisterResult", new RegisterResultViewModel { TenancyName = tenant.TenancyName, NameAndSurname = user.Name + " " + user.Surname, UserName = user.UserName, EmailAddress = user.EmailAddress, IsActive = user.IsActive, IsEmailConfirmationRequired = isEmailConfirmationRequiredForLogin })); } catch (UserFriendlyException ex) { ViewBag.IsMultiTenancyEnabled = _multiTenancyConfig.IsEnabled; ViewBag.UseCaptcha = !model.IsExternalLogin && UseCaptchaOnRegistration(); ViewBag.ErrorMessage = ex.Message; return(View("Register", model)); } }
public async Task <bool> IsLoginAsync(ExternalLoginInfo externalLoginInfo) { return((await _userManager.FindAsync(externalLoginInfo.Login)) != null); }
public async Task <ActionResult> Register(RegisterViewModel model) { try { ExternalLoginInfo externalLoginInfo = null; if (model.IsExternalLogin) { externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync(); if (externalLoginInfo == null) { throw new Exception("Can not external login!"); } model.UserName = model.EmailAddress; model.Password = Authorization.Users.User.CreateRandomPassword(); } else { if (model.UserName.IsNullOrEmpty() || model.Password.IsNullOrEmpty()) { throw new UserFriendlyException(L("FormIsNotValidMessage")); } } var user = await _userRegistrationManager.RegisterAsync( model.Name, model.Surname, model.EmailAddress, model.UserName, model.Password, true //Assumed email address is always confirmed. Change this if you want to implement email confirmation. ); //Getting tenant-specific settings var isEmailConfirmationRequiredForLogin = await SettingManager.GetSettingValueAsync <bool>(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin); if (model.IsExternalLogin) { Debug.Assert(externalLoginInfo != null); if (string.Equals(externalLoginInfo.Principal.FindFirstValue(ClaimTypes.Email), model.EmailAddress, StringComparison.OrdinalIgnoreCase)) { user.IsEmailConfirmed = true; } user.Logins = new List <UserLogin> { new UserLogin { LoginProvider = externalLoginInfo.LoginProvider, ProviderKey = externalLoginInfo.ProviderKey, TenantId = user.TenantId } }; } await _unitOfWorkManager.Current.SaveChangesAsync(); Debug.Assert(user.TenantId != null); var tenant = await _tenantManager.GetByIdAsync(user.TenantId.Value); //Directly login if possible if (user.IsActive && (user.IsEmailConfirmed || !isEmailConfirmationRequiredForLogin)) { AbpLoginResult <Tenant, User> loginResult; if (externalLoginInfo != null) { loginResult = await _logInManager.LoginAsync(externalLoginInfo, tenant.TenancyName); } else { loginResult = await GetLoginResultAsync(user.UserName, model.Password, tenant.TenancyName); } if (loginResult.Result == AbpLoginResultType.Success) { await _signInManager.SignInAsync(loginResult.Identity, false); return(Redirect(GetAppHomeUrl())); } Logger.Warn("New registered user could not be login. This should not be normally. login result: " + loginResult.Result); } return(View("RegisterResult", new RegisterResultViewModel { TenancyName = tenant.TenancyName, NameAndSurname = user.Name + " " + user.Surname, UserName = user.UserName, EmailAddress = user.EmailAddress, IsEmailConfirmed = user.IsEmailConfirmed, IsActive = user.IsActive, IsEmailConfirmationRequiredForLogin = isEmailConfirmationRequiredForLogin })); } catch (UserFriendlyException ex) { ViewBag.ErrorMessage = ex.Message; return(View("Register", model)); } }
private static bool IsEmailRetrievedFromExternalLogin(ExternalLoginInfo externalLoginInfo) { return(externalLoginInfo.Principal.FindFirstValue(AbpClaimTypes.Email) != null); }
private async Task <IActionResult> ExternalSignInAsync(ExternalLoginInfo loginInfo, Func <IActionResult> response) { if (loginInfo == null) { throw new ArgumentNullException(nameof(loginInfo)); } if (response == null) { throw new ArgumentNullException(nameof(response)); } // Sign in the user with this external login provider (which auto links, etc...) SignInResult result = await _signInManager.ExternalLoginSignInAsync(loginInfo, isPersistent : false, bypassTwoFactor : _securitySettings.Value.UserBypassTwoFactorForExternalLogins); var errors = new List <string>(); if (result == SignInResult.Success) { // Update any authentication tokens if succeeded await _signInManager.UpdateExternalAuthenticationTokensAsync(loginInfo); // Check if we are in an upgrade state, if so we need to redirect if (_runtimeState.Level == Core.RuntimeLevel.Upgrade) { // redirect to the the installer return(Redirect("/")); } } else if (result == SignInResult.TwoFactorRequired) { var attemptedUser = await _userManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey); if (attemptedUser == null) { return(new ValidationErrorResult($"No local user found for the login provider {loginInfo.LoginProvider} - {loginInfo.ProviderKey}")); } var twofactorView = _backOfficeTwoFactorOptions.GetTwoFactorView(attemptedUser.UserName); if (twofactorView.IsNullOrWhiteSpace()) { return(new ValidationErrorResult($"The registered {typeof(IBackOfficeTwoFactorOptions)} of type {_backOfficeTwoFactorOptions.GetType()} did not return a view for two factor auth ")); } // create a with information to display a custom two factor send code view var verifyResponse = new ObjectResult(new { twoFactorView = twofactorView, userId = attemptedUser.Id }) { StatusCode = StatusCodes.Status402PaymentRequired }; return(verifyResponse); } else if (result == SignInResult.LockedOut) { errors.Add($"The local user {loginInfo.Principal.Identity.Name} for the external provider {loginInfo.ProviderDisplayName} is locked out."); } else if (result == SignInResult.NotAllowed) { // This occurs when SignInManager.CanSignInAsync fails which is when RequireConfirmedEmail , RequireConfirmedPhoneNumber or RequireConfirmedAccount fails // however since we don't enforce those rules (yet) this shouldn't happen. errors.Add($"The user {loginInfo.Principal.Identity.Name} for the external provider {loginInfo.ProviderDisplayName} has not confirmed their details and cannot sign in."); } else if (result == SignInResult.Failed) { // Failed only occurs when the user does not exist errors.Add("The requested provider (" + loginInfo.LoginProvider + ") has not been linked to an account, the provider must be linked from the back office."); } else if (result == ExternalLoginSignInResult.NotAllowed) { // This occurs when the external provider has approved the login but custom logic in OnExternalLogin has denined it. errors.Add($"The user {loginInfo.Principal.Identity.Name} for the external provider {loginInfo.ProviderDisplayName} has not been accepted and cannot sign in."); } else if (result == AutoLinkSignInResult.FailedNotLinked) { errors.Add("The requested provider (" + loginInfo.LoginProvider + ") has not been linked to an account, the provider must be linked from the back office."); } else if (result == AutoLinkSignInResult.FailedNoEmail) { errors.Add($"The requested provider ({loginInfo.LoginProvider}) has not provided the email claim {ClaimTypes.Email}, the account cannot be linked."); } else if (result is AutoLinkSignInResult autoLinkSignInResult && autoLinkSignInResult.Errors.Count > 0) { errors.AddRange(autoLinkSignInResult.Errors); }
/// <summary> /// Gets the <see cref="YotiUserProfile"/> provided by Yoti after a successful login /// </summary> /// <param name="loginInfo">The <see cref="ExternalLoginInfo"/> retrieved after an external login event.</param> /// <returns>The <see cref="YotiUserProfile"/> or null if this was not a Yoti login.</returns> public static YotiUserProfile GetYotiProfile(this ExternalLoginInfo loginInfo) { if (loginInfo.Login.LoginProvider != Constants.DefaultAuthenticationType) { return(null); } var profile = new YotiUserProfile(); foreach (Claim claim in loginInfo.ExternalIdentity.Claims) { switch (claim.Type) { case ClaimTypes.NameIdentifier: profile.Id = claim.Value; break; case "selfie": TypeEnum imageType; if (Enum.TryParse(claim.ValueType, out imageType)) { profile.Selfie = new Image { Type = imageType, Data = Convert.FromBase64String(claim.Value) }; } break; case "given_names": profile.GivenNames = claim.Value; break; case "family_name": profile.FamilyName = claim.Value; break; case "full_name": profile.FullName = claim.Value; break; case "phone_number": profile.MobileNumber = claim.Value; break; case "email_address": profile.EmailAddress = claim.Value; break; case "date_of_birth": { if (DateTime.TryParseExact(claim.Value, "yyyy-MM-dd", CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out DateTime date)) { profile.DateOfBirth = date; } } break; case "postal_address": profile.Address = claim.Value; break; case "gender": profile.Gender = claim.Value; break; case "nationality": profile.Nationality = claim.Value; break; default: if (claim.Type.StartsWith(Constants.AttributeAgeOver) || claim.Type.StartsWith(Constants.AttributeAgeUnder)) { bool parsed = Boolean.TryParse(claim.Value, out bool IsAgeVerified); if (!parsed) { throw new FormatException( String.Format( "'{0}' value was unable to be parsed into a bool", claim.Value)); } profile.IsAgeVerified = IsAgeVerified; break; } else { if (Enum.TryParse(claim.ValueType, out YotiAttributeValue.TypeEnum valueType)) { profile.OtherAttributes.Add(claim.Type, new YotiAttributeValue(valueType, claim.Value)); } break; } } } return(profile); }
public async Task <IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null) { try { // Check if the External Provider returned an error and act accordingly if (remoteError != null) { throw new Exception(remoteError); } // Extract the login info obtained from the External Provider ExternalLoginInfo info = await SignInManager.GetExternalLoginInfoAsync(); if (info == null) { // if there's none, emit an error throw new Exception("ERROR: No login info available."); } // Check if this user already registered himself with this external provider before var user = await UserManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey); if (user == null) { // If we reach this point, it means that this user never tried to logged in // using this external provider. However, it could have used other providers // and /or have a local account. // We can find out if that's the case by looking for his e-mail address. // Retrieve the 'emailaddress' claim var emailKey = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"; var email = info.Principal.FindFirst(emailKey).Value; // Lookup if there's an username with this e-mail address in the Db user = await UserManager.FindByEmailAsync(email); if (user == null) { // No user has been found: register a new user using the info retrieved from the provider DateTime now = DateTime.Now; // Create a unique username using the 'nameidentifier' claim var idKey = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"; var username = String.Format("{0}{1}", info.LoginProvider, info.Principal.FindFirst(idKey).Value); user = new ApplicationUser() { UserName = username, Email = email, CreatedDate = now, LastModifiedDate = now }; // Add the user to the Db with a random password await UserManager.CreateAsync(user, "Pass4External"); // Assign the user to the 'Registered' role. await UserManager.AddToRoleAsync(user, "Registered"); // Remove Lockout and E-Mail confirmation user.EmailConfirmed = true; user.LockoutEnabled = false; } // Register this external provider to the user await UserManager.AddLoginAsync(user, info); // Persist everything into the Db await DbContext.SaveChangesAsync(); } // create the auth JSON object var auth = new { type = "External", providerName = info.LoginProvider }; // output a <SCRIPT> tag to call a JS function registered into the parent window global scope return(Content( "<script type=\"text/javascript\">" + "window.opener.externalProviderLogin(" + JsonConvert.SerializeObject(auth) + ");" + "window.close();" + "</script>", "text/html" )); } catch (Exception ex) { // return a HTTP Status 400 (Bad Request) to the client return(BadRequest(new { Error = ex.Message })); } }
private async Task<ExternalLoginConfirmationViewModel> GetExternalLoginModel(AuthenticateResult result, ExternalLoginInfo loginInfo) { string name = null; string email = null; if (loginInfo.Login.LoginProvider == "Facebook") { name = GetClaimValue(result.Identity, "urn:facebook:name"); } else if (loginInfo.Login.LoginProvider == "Google") { name = GetClaimValue(result.Identity, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"); email = GetClaimValue(result.Identity, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"); } else if (loginInfo.Login.LoginProvider == "Twitter") { var userInfo = await GetUserDataFromTwitter(loginInfo.DefaultUserName); if (userInfo != null) { name = userInfo.FullName; } } var userName = loginInfo.DefaultUserName + loginInfo.Login.LoginProvider; userName += name ?? ""; Regex rgx = new Regex("[^a-zA-Z0-9]"); userName = rgx.Replace(userName, ""); return new ExternalLoginConfirmationViewModel() { UserName = userName, Name = name, Email = email }; }
private static async Task UpdateUserTokenAsync(BuildAssetRegistryContext dbContext, UserManager <ApplicationUser> userManager, ApplicationUser user, ExternalLoginInfo info) { try { await userManager.SetAuthenticationTokenAsync( user, info.LoginProvider, "access_token", info.AuthenticationTokens.First(t => t.Name == "access_token").Value); } catch (DbUpdateConcurrencyException) { // If we have a concurrent modification exception that means another request updated this token, we can abandon our update and reload the data from the DB foreach (EntityEntry entry in dbContext.ChangeTracker.Entries()) { await entry.ReloadAsync(); } } }
public async Task <ActionResult> Register(RegisterViewModel model) { try { if (!model.IsExternalLogin && UseCaptchaOnRegistration()) { await _recaptchaValidator.ValidateAsync(HttpContext.Request.Form[RecaptchaValidator.RecaptchaResponseKey]); } ExternalLoginInfo externalLoginInfo = null; if (model.IsExternalLogin) { externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync(); if (externalLoginInfo == null) { throw new Exception("Can not external login!"); } using (var providerManager = _externalLoginInfoManagerFactory.GetExternalLoginInfoManager(externalLoginInfo.LoginProvider)) { model.UserName = providerManager.Object.GetUserNameFromClaims(externalLoginInfo.Principal.Claims.ToList()); } model.Password = await _userManager.CreateRandomPassword(); } else { if (model.UserName.IsNullOrEmpty() || model.Password.IsNullOrEmpty()) { throw new UserFriendlyException(L("FormIsNotValidMessage")); } } var user = await _userRegistrationManager.RegisterAsync( model.Name, model.Surname, model.EmailAddress, model.UserName, model.Password, false, _appUrlService.CreateEmailActivationUrlFormat(AbpSession.TenantId) ); //Getting tenant-specific settings var isEmailConfirmationRequiredForLogin = await SettingManager.GetSettingValueAsync <bool>(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin); if (model.IsExternalLogin) { Debug.Assert(externalLoginInfo != null); if (string.Equals(externalLoginInfo.Principal.FindFirstValue(ClaimTypes.Email), model.EmailAddress, StringComparison.OrdinalIgnoreCase)) { user.IsEmailConfirmed = true; } user.Logins = new List <UserLogin> { new UserLogin { LoginProvider = externalLoginInfo.LoginProvider, ProviderKey = externalLoginInfo.ProviderKey, TenantId = user.TenantId } }; } await _unitOfWorkManager.Current.SaveChangesAsync(); Debug.Assert(user.TenantId != null); var tenant = await _tenantManager.GetByIdAsync(user.TenantId.Value); //Directly login if possible if (user.IsActive && (user.IsEmailConfirmed || !isEmailConfirmationRequiredForLogin)) { AbpLoginResult <Tenant, User> loginResult; if (externalLoginInfo != null) { loginResult = await _logInManager.LoginAsync(externalLoginInfo, tenant.TenancyName); } else { loginResult = await GetLoginResultAsync(user.UserName, model.Password, tenant.TenancyName); } if (loginResult.Result == AbpLoginResultType.Success) { await _signInManager.SignInAsync(loginResult.Identity, false); if (!string.IsNullOrEmpty(model.SingleSignIn) && model.SingleSignIn.Equals("true", StringComparison.OrdinalIgnoreCase) && loginResult.Result == AbpLoginResultType.Success) { var returnUrl = NormalizeReturnUrl(model.ReturnUrl); loginResult.User.SetSignInToken(); returnUrl = AddSingleSignInParametersToReturnUrl(returnUrl, loginResult.User.SignInToken, loginResult.User.Id, loginResult.User.TenantId); return(Redirect(returnUrl)); } return(Redirect(GetAppHomeUrl())); } Logger.Warn("New registered user could not be login. This should not be normally. login result: " + loginResult.Result); } return(View("RegisterResult", new RegisterResultViewModel { TenancyName = tenant.TenancyName, NameAndSurname = user.Name + " " + user.Surname, UserName = user.UserName, EmailAddress = user.EmailAddress, IsActive = user.IsActive, IsEmailConfirmationRequired = isEmailConfirmationRequiredForLogin })); } catch (UserFriendlyException ex) { ViewBag.UseCaptcha = !model.IsExternalLogin && UseCaptchaOnRegistration(); ViewBag.ErrorMessage = ex.Message; model.PasswordComplexitySetting = await _passwordComplexitySettingStore.GetSettingsAsync(); return(View("Register", model)); } }
private void ConfigureAuthServices(IServiceCollection services) { services.AddIdentity <ApplicationUser, IdentityRole <int> >( options => { options.Lockout.AllowedForNewUsers = false; }) .AddEntityFrameworkStores <BuildAssetRegistryContext>(); services.AddContextAwareAuthenticationScheme(o => { o.SelectScheme = p => p.StartsWithSegments("/api") ? PersonalAccessTokenDefaults.AuthenticationScheme : IdentityConstants.ApplicationScheme; }); services.AddAuthentication() .AddGitHubOAuth(Configuration.GetSection("GitHubAuthentication"), GitHubScheme) .AddPersonalAccessToken <ApplicationUser>( options => { options.Events = new PersonalAccessTokenEvents <ApplicationUser> { OnSetTokenHash = async context => { var dbContext = context.HttpContext.RequestServices .GetRequiredService <BuildAssetRegistryContext>(); int userId = context.User.Id; var token = new ApplicationUserPersonalAccessToken { ApplicationUserId = userId, Name = context.Name, Hash = context.Hash, Created = DateTimeOffset.UtcNow }; await dbContext.Set <ApplicationUserPersonalAccessToken>().AddAsync(token); await dbContext.SaveChangesAsync(); return(token.Id); }, OnGetTokenHash = async context => { var dbContext = context.HttpContext.RequestServices .GetRequiredService <BuildAssetRegistryContext>(); ApplicationUserPersonalAccessToken token = await dbContext .Set <ApplicationUserPersonalAccessToken>() .Where(t => t.Id == context.TokenId) .Include(t => t.ApplicationUser) .FirstOrDefaultAsync(); if (token != null) { context.Success(token.Hash, token.ApplicationUser); } }, OnValidatePrincipal = async context => { ApplicationUser user = context.User; var dbContext = context.HttpContext.RequestServices .GetRequiredService <BuildAssetRegistryContext>(); var userManager = context.HttpContext.RequestServices .GetRequiredService <UserManager <ApplicationUser> >(); var signInManager = context.HttpContext.RequestServices .GetRequiredService <SignInManager <ApplicationUser> >(); var gitHubClaimResolver = context.HttpContext.RequestServices .GetRequiredService <GitHubClaimResolver>(); await UpdateUserIfNeededAsync(user, dbContext, userManager, signInManager, gitHubClaimResolver); ClaimsPrincipal principal = await signInManager.CreateUserPrincipalAsync(user); context.ReplacePrincipal(principal); } }; }); services.ConfigureExternalCookie( options => { options.ExpireTimeSpan = TimeSpan.FromMinutes(30); options.ReturnUrlParameter = "returnUrl"; options.LoginPath = "/Account/SignIn"; options.Events = new CookieAuthenticationEvents { OnRedirectToLogin = ctx => { if (ctx.Request.Path.StartsWithSegments("/api")) { ctx.Response.StatusCode = 401; return(Task.CompletedTask); } ctx.Response.Redirect(ctx.RedirectUri); return(Task.CompletedTask); }, OnRedirectToAccessDenied = ctx => { ctx.Response.StatusCode = 403; return(Task.CompletedTask); }, }; }); services.ConfigureApplicationCookie( options => { options.ExpireTimeSpan = LoginCookieLifetime; options.SlidingExpiration = true; options.Events = new CookieAuthenticationEvents { OnSigningIn = async ctx => { var dbContext = ctx.HttpContext.RequestServices .GetRequiredService <BuildAssetRegistryContext>(); var signInManager = ctx.HttpContext.RequestServices .GetRequiredService <SignInManager <ApplicationUser> >(); var userManager = ctx.HttpContext.RequestServices .GetRequiredService <UserManager <ApplicationUser> >(); ExternalLoginInfo info = await signInManager.GetExternalLoginInfoAsync(); var user = await userManager.GetUserAsync(ctx.Principal); await UpdateUserTokenAsync(dbContext, userManager, user, info); IdentityOptions identityOptions = ctx.HttpContext.RequestServices .GetRequiredService <IOptions <IdentityOptions> >() .Value; // replace the ClaimsPrincipal we are about to serialize to the cookie with a reference Claim claim = ctx.Principal.Claims.First( c => c.Type == identityOptions.ClaimsIdentity.UserIdClaimType); Claim[] claims = { claim }; var identity = new ClaimsIdentity(claims, IdentityConstants.ApplicationScheme); ctx.Principal = new ClaimsPrincipal(identity); }, OnValidatePrincipal = async ctx => { var dbContext = ctx.HttpContext.RequestServices .GetRequiredService <BuildAssetRegistryContext>(); var userManager = ctx.HttpContext.RequestServices .GetRequiredService <UserManager <ApplicationUser> >(); var signInManager = ctx.HttpContext.RequestServices .GetRequiredService <SignInManager <ApplicationUser> >(); var gitHubClaimResolver = ctx.HttpContext.RequestServices .GetRequiredService <GitHubClaimResolver>(); // extract the userId from the ClaimsPrincipal and read the user from the Db ApplicationUser user = await userManager.GetUserAsync(ctx.Principal); if (user == null) { ctx.RejectPrincipal(); } else { await UpdateUserIfNeededAsync(user, dbContext, userManager, signInManager, gitHubClaimResolver); ClaimsPrincipal principal = await signInManager.CreateUserPrincipalAsync(user); ctx.ReplacePrincipal(principal); } } }; }); services.AddAuthorization( options => { options.AddPolicy( MsftAuthorizationPolicyName, policy => { policy.RequireAuthenticatedUser(); if (!HostingEnvironment.IsDevelopment()) { policy.RequireRole("github:team:dotnet:dnceng", "github:team:dotnet:arcade-contrib"); } }); }); services.Configure <MvcOptions>( options => { options.Conventions.Add(new DefaultAuthorizeActionModelConvention(MsftAuthorizationPolicyName)); }); }
public virtual async Task <ActionResult> Register(RegisterViewModel model) { try { CheckModelState(); //Get tenancy name and tenant if (!_multiTenancyConfig.IsEnabled) { model.TenancyName = Tenant.DefaultTenantName; } else if (model.TenancyName.IsNullOrEmpty()) { throw new UserFriendlyException(L("TenantNameCanNotBeEmpty")); } var tenant = await GetActiveTenantAsync(model.TenancyName); //Create user var user = new User { TenantId = tenant.Id, Name = model.Name, Surname = model.Surname, EmailAddress = model.EmailAddress, IsActive = true }; //Get external login info if possible ExternalLoginInfo externalLoginInfo = null; if (model.IsExternalLogin) { externalLoginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); if (externalLoginInfo == null) { throw new ApplicationException("Can not external login!"); } user.Logins = new List <UserLogin> { new UserLogin { TenantId = tenant.Id, LoginProvider = externalLoginInfo.Login.LoginProvider, ProviderKey = externalLoginInfo.Login.ProviderKey } }; if (model.UserName.IsNullOrEmpty()) { model.UserName = model.EmailAddress; } model.Password = Users.User.CreateRandomPassword(); if (string.Equals(externalLoginInfo.Email, model.EmailAddress, StringComparison.InvariantCultureIgnoreCase)) { user.IsEmailConfirmed = true; } } else { //Username and Password are required if not external login if (model.UserName.IsNullOrEmpty() || model.Password.IsNullOrEmpty()) { throw new UserFriendlyException(L("FormIsNotValidMessage")); } } user.UserName = model.UserName; user.Password = new PasswordHasher().HashPassword(model.Password); //Switch to the tenant _unitOfWorkManager.Current.EnableFilter(AbpDataFilters.MayHaveTenant); //TODO: Needed? _unitOfWorkManager.Current.SetTenantId(tenant.Id); //Add default roles user.Roles = new List <UserRole>(); foreach (var defaultRole in await _roleManager.Roles.Where(r => r.IsDefault).ToListAsync()) { user.Roles.Add(new UserRole { RoleId = defaultRole.Id }); } //Save user CheckErrors(await _userManager.CreateAsync(user)); await _unitOfWorkManager.Current.SaveChangesAsync(); //Directly login if possible if (user.IsActive) { AbpLoginResult <Tenant, User> loginResult; if (externalLoginInfo != null) { loginResult = await _logInManager.LoginAsync(externalLoginInfo.Login, tenant.TenancyName); } else { loginResult = await GetLoginResultAsync(user.UserName, model.Password, tenant.TenancyName); } if (loginResult.Result == AbpLoginResultType.Success) { await SignInAsync(loginResult.User, loginResult.Identity); return(Redirect(Url.Action("Index", "Home"))); } Logger.Warn("New registered user could not be login. This should not be normally. login result: " + loginResult.Result); } //If can not login, show a register result page return(View("RegisterResult", new RegisterResultViewModel { TenancyName = tenant.TenancyName, NameAndSurname = user.Name + " " + user.Surname, UserName = user.UserName, EmailAddress = user.EmailAddress, IsActive = user.IsActive })); } catch (UserFriendlyException ex) { ViewBag.IsMultiTenancyEnabled = _multiTenancyConfig.IsEnabled; ViewBag.ErrorMessage = ex.Message; return(View("Register", model)); } }
public async Task <SignInStatus> EfetuarLoginExterno(ExternalLoginInfo login, bool rememberMe) { return(await _signInManager.ExternalSignInAsync(login, rememberMe)); }
public void GetExternalLoginNullIfXsrfFailsSyncTest() { var mockManager = new Mock<IAuthenticationManager>(); var props = new AuthenticationProperties(); props.Dictionary["xsrfKey"] = "Hao"; var loginInfo = new ExternalLoginInfo { Login = new UserLoginInfo("loginProvider", "key"), DefaultUserName = "******" }; mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) .Returns( Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, new AuthenticationDescription()))); var manager = mockManager.Object; var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "NotHao"); Assert.Null(externalInfo); }
public async Task <IdentityResult> TryCreateAccountForExternalUser(Guid siteId, ExternalLoginInfo info) { if (info == null || info.Principal == null) { return(null); } var email = info.Principal.FindFirstValue(ClaimTypes.Email); if (string.IsNullOrWhiteSpace(email)) { return(null); // not enough info } var userName = await SuggestLoginNameFromEmail(Site.Id, email); var user = new SiteUser { SiteId = Site.Id, UserName = userName, Email = email, FirstName = info.Principal.FindFirstValue(ClaimTypes.GivenName), LastName = info.Principal.FindFirstValue(ClaimTypes.Surname), AccountApproved = Site.RequireApprovalBeforeLogin ? false : true }; //https://github.com/joeaudette/cloudscribe/issues/346 user.DisplayName = _displayNameResolver.ResolveDisplayName(user); var result = await CreateAsync(user as TUser); if (result.Succeeded) { result = await AddLoginAsync(user as TUser, info); } return(result); }
public static ClaimsIdentity CreateIdentity(ExternalLoginInfo info) { return new ClaimsIdentity( new[] { new Claim(ClaimTypes.NameIdentifier, info.Login.ProviderKey, null, info.Login.LoginProvider), new Claim(ClaimTypes.Name, info.DefaultUserName) }, info.Login.LoginProvider); }
private static void AddInfo(ExternalLoginInfo loginInfo, string steamID) { using (var context = new SteamLoginContext()) { var s = new SteamLogin { Id= 0, SteamId = steamID, UserName = loginInfo.DefaultUserName }; context.Login.Add(s); var res = context.SaveChanges(); } }
private Task LoadNewUserDataAsync(GGCharityUser user, ExternalLoginInfo loginInfo) { if (loginInfo.Login.LoginProvider == BattleNetProviderId) { Trace.TraceInformation("Beginning to load BattleNet info for user {0}", user.UserName); var accessTokenClaim = loginInfo.ExternalIdentity.Claims.Where(c => c.Type == @"urn:battlenet:accesstoken").Single(); return LoadBattleNetUserDataAsync(user, accessTokenClaim.Value); } else { throw new NotSupportedException(); } }
private async Task<ExternalLoginInfo> AuthenticationManager_GetExternalLoginInfoAsync_Workaround() { ExternalLoginInfo loginInfo = null; var result = await AuthenticationManager.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie); if (result != null && result.Identity != null) { var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier); if (idClaim != null) { loginInfo = new ExternalLoginInfo() { DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""), Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value) }; } } return loginInfo; }
public async Task <IActionResult> VerifyCode(VerifyCodeViewModel model, string returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; switch (model.Type) { case VerificationTypes.Registration: SetPageContent("verifycode"); break; case VerificationTypes.PasswordRenewal: SetPageContent("verifycode-newpass"); break; } if (!ModelState.IsValid) { return(View(model)); } User user = null; ExternalLoginInfo externalLoginInfo = null; var userId = _userManager.GetUserId(User); var isExternal = false; var isTwoFactor = false; if (!string.IsNullOrWhiteSpace(userId)) { user = await _userManager.FindByIdAsync(userId); } else { user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); if (user != null) { isTwoFactor = true; } else { externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync(); if (externalLoginInfo != null) { isExternal = true; user = await _userManager.FindByLoginAsync(externalLoginInfo.LoginProvider, externalLoginInfo.ProviderKey); } } } if (!(user.VerifyCodeExpireDate.HasValue && user.VerifyCodeExpireDate.Value >= DateTime.Now)) { ModelState.AddModelError("", "Onay kodunu size ayrılan sürede girmediniz! Lütfen tekrar deneyiniz."); return(View(model)); } if (user.VerifyCode == model.Code) { if (!isExternal && !isTwoFactor) { await _signInManager.SignInAsync(user, false); if (_signInManager.IsSignedIn(User)) { user.TwoFactorEnabled = false; user.LockoutEnabled = false; await _userManager.UpdateAsync(user); _notificationService.AddNotification(user.Id, NotificationTypes.CellPhoneVerified); return(RedirectToLocal(returnUrl)); } var isLockedOut = await _userManager.IsLockedOutAsync(user); if (isLockedOut) { return(Redirect("~/uyelikpasif")); } else { ModelState.AddModelError("", "Lütfen tekrar deneyiniz."); return(View(model)); } } if (isTwoFactor) { user.TwoFactorEnabled = false; user.LockoutEnabled = false; await _userManager.UpdateAsync(user); return(SetTransactionResult( "Üyeliğiniz aktif edilmiştir. Üye giriş ekranına yönlendirileceksiniz.", Url.RouteUrl("login"), TransactionType.Success )); } if (isExternal) { user.TwoFactorEnabled = false; user.LockoutEnabled = false; await _userManager.UpdateAsync(user); var result = await _signInManager.ExternalLoginSignInAsync(externalLoginInfo.LoginProvider, externalLoginInfo.ProviderKey, isPersistent : false); if (result.Succeeded) { return(RedirectToLocal(returnUrl)); } if (result.IsLockedOut) { return(Redirect("~/uyelikpasif")); } } } ModelState.AddModelError("", "Hatalı onay kodu girdiniz! Lütfen tekrar deneyiniz."); return(View(model)); }
public async Task<HttpResponseMessage> PostGoogle(ExternalInfo externalInfo) { GoogleOAuth2Handler auth2AuthenticationHandler = new GoogleOAuth2Handler(new HttpClient()); var googleOAuthProfile = await auth2AuthenticationHandler.ProcessToken(externalInfo.Code, externalInfo.RedirectUri); var clameIdentity = googleOAuthProfile.Id; var email = googleOAuthProfile.Emails.First().Email; ApplicationUser appUser = await UserManager.FindAsync(new UserLoginInfo("Google", clameIdentity)); bool hasRegisteredWithAccount = appUser != null; if (!hasRegisteredWithAccount) { var info = new ExternalLoginInfo { DefaultUserName = email, Login = new UserLoginInfo("Google", clameIdentity) }; try { if (User.Identity.IsAuthenticated) { appUser = await UserManager.FindByIdAsync(User.Identity.GetUserId()); if (string.IsNullOrEmpty(appUser.Picture)) { appUser.Picture = googleOAuthProfile.Image.Url; await UserManager.UpdateAsync(appUser); } } else { appUser = new ApplicationUser { UserName = email, Email = email, DisplayName = googleOAuthProfile.DisplayName, Picture = googleOAuthProfile.Image.Url }; UserManager.Create(appUser); } UserManager.AddLogin(appUser.Id, info.Login); } catch (Exception exception) { return Request.CreateResponse(HttpStatusCode.InternalServerError, new HttpError(exception, true)); } } var accessTokenResponse = GenerateLocalAccessTokenResponse(appUser); return Request.CreateResponse(HttpStatusCode.OK, accessTokenResponse); }
private ActionResult ValidateAndReturnProperView(SignInStatus result, string returnUrl, ExternalLoginInfo loginInfo) { 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 }); } }
public async Task <IActionResult> Post([FromBody] User model) { if (string.IsNullOrEmpty(model.Username)) { return(this.BadRequest(new { Message = $"Cannot create a user without a username" })); } var user = new ApplicationUser(model.Username); // optional properties user.Email = model.Email ?? user.Email; user.PhoneNumber = model.PhoneNumber ?? user.PhoneNumber; if (model.Roles != null) { foreach (var role in model.Roles) { if (!await this.roleManager.RoleExistsAsync(role)) { return(this.BadRequest(new { Message = $"Cannot create a user with the role '{role}' when that role does not exist" })); } } } var addUserResult = string.IsNullOrEmpty(model.Password) ? await this.userManager.CreateAsync(user) : await this.userManager.CreateAsync(user, model.Password); if (!addUserResult.Succeeded) { if (addUserResult.Errors.Any(error => error.Code == "DuplicateUserName")) { return(this.StatusCode((int)HttpStatusCode.Conflict, new { Message = "User already exists" })); } return(this.StatusCode((int)HttpStatusCode.InternalServerError, new { Message = addUserResult.ToString() })); } if (!string.IsNullOrEmpty(model.ExternalLoginProvider)) { var claims = new[] { new Claim(JwtClaimTypes.Name, model.Username) }; var identity = new ClaimsIdentity(claims, model.ExternalLoginProvider, "name", "role"); var principal = new ClaimsPrincipal(identity); var info = new ExternalLoginInfo(principal, model.ExternalLoginProvider, model.Username, model.Username); var addLoginResult = await this.userManager.AddLoginAsync(user, info); if (!addLoginResult.Succeeded) { return(this.StatusCode((int)HttpStatusCode.InternalServerError, new { Message = addLoginResult.ToString() })); } } if (model.Roles != null) { var addToRolesResult = await this.userManager.AddToRolesAsync(user, model.Roles); if (!addToRolesResult.Succeeded) { return(this.StatusCode((int)HttpStatusCode.InternalServerError, new { Message = addToRolesResult.ToString() })); } } var callbackUrl = default(string); if (string.IsNullOrEmpty(model.Password) && !string.IsNullOrEmpty(model.Email)) { var code = await this.userManager.GeneratePasswordResetTokenAsync(user); callbackUrl = this.Url.CompleteRegistrationLink(user.Id, code, this.Request.Scheme); if (model.SendConfirmationEmail == true) { await this.emailSender.SendActivationEmailAsync(model.Email, callbackUrl); } } return(this.Created( new Uri(this.HttpContext.GetIdentityServerRelativeUrl("~/api/users/" + model.Username)), callbackUrl != null ? new { registrationLink = callbackUrl } : null)); }
public async Task<ActionResult> ExternalLoginCallback(string returnUrl) { // no - it simplifies it // var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); var result = await AuthenticationManager.AuthenticateAsync("ExternalCookie"); var emailClaim = result.Identity.Claims.FirstOrDefault( c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"); var email = emailClaim != null ? emailClaim.Value : ""; ExternalLoginInfo loginInfo = null; Claim nameClaim = result.Identity.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"); if (nameClaim != null) { string str = result.Identity.Name.Replace(" ", ""); loginInfo = new ExternalLoginInfo() { Login = new UserLoginInfo(nameClaim.Issuer, nameClaim.Value), DefaultUserName = str }; } if (loginInfo == null) { return RedirectToAction("Login"); } // 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) { await SignInAsync(user, isPersistent: false); return RedirectToLocal(returnUrl); } else { // 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 { UserName = loginInfo.DefaultUserName }); } }
private async Task <IActionResult> LoggedInActionResult(IUser user, string returnUrl = null, ExternalLoginInfo info = null) { var workflowManager = HttpContext.RequestServices.GetService <IWorkflowManager>(); if (workflowManager != null) { var input = new Dictionary <string, object>(); input["UserName"] = user.UserName; input["ExternalClaims"] = info == null?Enumerable.Empty <SerializableClaim>() : info.Principal.GetSerializableClaims(); input["Roles"] = ((User)user).RoleNames; input["Provider"] = info?.LoginProvider; await workflowManager.TriggerEventAsync(nameof(Workflows.Activities.UserLoggedInEvent), input : input, correlationId : ((User)user).UserId); } return(RedirectToLocal(returnUrl)); }
public async Task<SignInStatus> ExternalSignIn( ExternalLoginInfo loginInfo, bool isPersistent) { var user = await UserManager.FindAsync(loginInfo.Login); if (user == null) { return SignInStatus.Failure; } if (await UserManager.IsLockedOutAsync(user.Id)) { return SignInStatus.LockedOut; } return await SignInOrTwoFactor(user, isPersistent); }
private async Task<ActionResult> AddUserAndLoginToDb(AppUser user, ExternalLoginInfo loginInfo) { var result = await UserManager.CreateAsync(user); if (!result.Succeeded) { //return View("Error", new List<string> { "Brugernavn eller Email er i brug. Hvis du tidligere har logget på normalt eller med facebook, så prøv venligst samme metode" }); return RedirectToAction("SignUp", new { model = new CreateModel(), socialError = "Brugernavn eller email eksisterer allerede. Opret venligst en ny bruger" }); } result = await UserManager.AddLoginAsync(user.Id, loginInfo.Login); if (!result.Succeeded) { return View("Error", result.Errors); } return null; }
private static string GetLastName(ExternalLoginInfo info) { var name = info?.Principal?.Identity?.Name; return((name?.Contains(" ") ?? false) ? name.Substring(name.LastIndexOf(" ")).Trim() : name); }
private AppUser CreateUser(ExternalLoginInfo loginInfo) { return new AppUser { Email = loginInfo.Email ?? "*****@*****.**", UserName = loginInfo.DefaultUserName, }; }
private async Task<ActionResult> SignInUser(AppUser user, ExternalLoginInfo loginInfo) { var ident = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); ident.AddClaims(loginInfo.ExternalIdentity.Claims); AuthManager.SignIn(new AuthenticationProperties { IsPersistent = false }, ident); return null; }
public async Task <IActionResult> ExternalLoginCallBack(string returnUrl = null, string remoteError = null) { returnUrl = returnUrl ?? Url.Content("~/"); var loginViewModel = new LoginViewModel { ReturnUrl = returnUrl, ExternalLogins = (await signInManager.GetExternalAuthenticationSchemesAsync()).ToList() }; if (remoteError != null) { ModelState.AddModelError(string.Empty, $"Error from external provider: {remoteError}"); return(View("Login", loginViewModel)); } ExternalLoginInfo info = await signInManager.GetExternalLoginInfoAsync(); if (info == null) { ModelState.AddModelError(string.Empty, $"Error loading external login information."); return(View("Login", loginViewModel)); } var email = info.Principal.FindFirstValue(ClaimTypes.Email); ApplicationUser user = null; if (email != null) { user = await userManager.FindByEmailAsync(email); if (user != null && !user.EmailConfirmed) { ModelState.AddModelError(string.Empty, "Email not confirmed yet"); return(View("Login", loginViewModel)); } } var signInResult = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent : false, bypassTwoFactor : true); if (signInResult.Succeeded) { return(LocalRedirect(returnUrl)); } else { if (email != null) { if (user == null) { user = new ApplicationUser { UserName = info.Principal.FindFirstValue(ClaimTypes.Email), Email = info.Principal.FindFirstValue(ClaimTypes.Email) }; await userManager.CreateAsync(user); var token = await userManager.GenerateEmailConfirmationTokenAsync(user); var confirmationLink = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, token = token }, Request.Scheme); logger.Log(LogLevel.Warning, confirmationLink); ViewBag.ErrorTitle = "Registration succesful"; ViewBag.ErrorMessage = "Before you can login, please confirm your email, by clicking on the confirmation link we have emailed you"; return(View("Error")); } await userManager.AddLoginAsync(user, info); await signInManager.SignInAsync(user, isPersistent : false); return(LocalRedirect(returnUrl)); } ViewBag.ErrorTitle = $"Email claim not received from: {info.LoginProvider}"; ViewBag.ErrorMessage = "Please contact support on [email protected]"; return(View("Error")); } }
private async Task<ActionResult> RegisterView(ExternalLoginInfo loginInfo, string tenancyName = null) { var name = loginInfo.DefaultUserName; var surname = loginInfo.DefaultUserName; var extractedNameAndSurname = TryExtractNameAndSurnameFromClaims(loginInfo.ExternalIdentity.Claims.ToList(), ref name, ref surname); var viewModel = new RegisterViewModel { TenancyName = tenancyName, EmailAddress = loginInfo.Email, Name = name, Surname = surname, IsExternalLogin = true }; if (!tenancyName.IsNullOrEmpty() && extractedNameAndSurname) { return await Register(viewModel); } return RegisterView(viewModel); }
public async Task <IActionResult> OnPostConfirmationAsync(string returnUrl = null) { returnUrl ??= this.Url.Content("~/"); // Get the information about the user from the external login provider ExternalLoginInfo info = await this.signInManager.GetExternalLoginInfoAsync( ).ConfigureAwait(false); if (info == null) { this.ErrorMessage = "Error loading external login information during confirmation."; return(this.RedirectToPage("./Login", new { ReturnUrl = returnUrl })); } if (this.ModelState.IsValid) { HeimdallUser user = new HeimdallUser { UserName = this.Input.Email, Email = this.Input.Email }; IdentityResult result = await this.userManager.CreateAsync(user).ConfigureAwait(false); if (result.Succeeded) { result = await this.userManager.AddLoginAsync(user, info).ConfigureAwait(false); if (result.Succeeded) { this.logger.LogInformation( "User created an account using {Name} provider.", info.LoginProvider); string userId = await this.userManager.GetUserIdAsync(user).ConfigureAwait(false); string code = await this.userManager.GenerateEmailConfirmationTokenAsync(user) .ConfigureAwait(false); code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); string callbackUrl = this.Url.Page( "/Account/ConfirmEmail", null, new { area = "Identity", userId, code }, this.Request.Scheme); await this.emailSender.SendEmailAsync( this.Input.Email, "Confirm your email", $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode( callbackUrl )}'>clicking here</a>.") .ConfigureAwait(false); // If account confirmation is required, we need to show the link if we don't have a real email sender if (this.userManager.Options.SignIn.RequireConfirmedAccount) { return(this.RedirectToPage("./RegisterConfirmation", new { this.Input.Email })); } await this.signInManager.SignInAsync(user, false, info.LoginProvider).ConfigureAwait(false); return(this.LocalRedirect(returnUrl)); } } foreach (IdentityError error in result.Errors) { this.ModelState.AddModelError(string.Empty, error.Description); } } this.ProviderDisplayName = info.ProviderDisplayName; this.ReturnUrl = returnUrl; return(this.Page( )); }