public async Task <ExternalLoginInfo> LoginFromModel(ExternalLoginModel model) { try { await GoogleJsonWebSignature.ValidateAsync(model.IdToken, new GoogleJsonWebSignature.ValidationSettings { ExpirationTimeClockTolerance = TimeSpan.FromSeconds(30) }); } catch (Exception ex) { throw new ExternalLoginException($"Google authentication failed: {ex.Message}", ex); } var tokenInfoReq = new Oauth2Service.TokeninfoRequest(_oauth2Service) { IdToken = model.IdToken }; var tokenInfo = await tokenInfoReq.ExecuteAsync(); return(new ExternalLoginInfo { Provider = this, UserId = tokenInfo.UserId, UserEmail = tokenInfo.Email }); }
public async Task <ActionResult> ExternalLogin([FromBody] ExternalLoginModel model) { if (!this.ModelState.IsValid) { return(BadRequest(new { Errors = this.ModelState.Errors() })); } var loginProvider = _loginProviders(model.Provider); if (loginProvider == null) { this.ModelState.AddModelError("Provider", $"External authentication provider {model.Provider} not supported"); return(BadRequest(new { Errors = this.ModelState.Errors() })); } var externalLoginInfo = (ExternalLoginInfo)null; try { externalLoginInfo = await loginProvider.LoginFromModel(model); } catch (ExternalLoginException ex) { this.ModelState.AddModelError("IdToken", ex.Message); return(Unauthorized(new { Errors = this.ModelState.Errors() })); } var loginInfo = new UserLoginInfo( loginProvider.Name, externalLoginInfo.UserId, loginProvider.Name ); var user = await _userManager.FindByEmailAsync(externalLoginInfo.UserEmail); if (user == null) { user = new AppUser { Id = Guid.NewGuid(), UserName = externalLoginInfo.UserEmail, Email = externalLoginInfo.UserEmail }; var createUserResult = await _userManager .CreateAsync(user); if (_userManager.Users.Count() == 1) { await _userManager.AddToRoleAsync(user, AppRole.AdminRole); } } // Issue access token await _userManager.AddLoginAsync(user, loginInfo); await _signInManager.SignInAsync(user, false); var accessToken = _jwtIssuer.IssueToken( user, await _userManager.GetRolesAsync(user) ); // Issue refresh token await _userManager.RemoveAuthenticationTokenAsync( user, RefreshTokenProvider.Name, RefreshTokenProvider.Purpose ); var refreeshToken = await _userManager.GenerateUserTokenAsync( user, RefreshTokenProvider.Name, RefreshTokenProvider.Purpose ); await _userManager.SetAuthenticationTokenAsync( user, RefreshTokenProvider.Name, RefreshTokenProvider.Purpose, refreeshToken ); return(Ok(new { AccessToken = accessToken, RefreshToken = refreeshToken })); }