Пример #1
0
        public async Task <IActionResult> Callback()
        {
            // read external identity from the temporary cookie
            var result =
                await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants
                                                    .ExternalCookieAuthenticationScheme);

            if (result?.Succeeded != true)
            {
                throw new Exception("External authentication error");
            }

            // retrieve return URL
            var returnUrl = result.Properties.Items["returnUrl"] ?? "~/";

            // lookup our user and external provider info
            var(user, provider, providerUserId, claims) = await FindUserFromExternalProvider(result);

            foreach (var claim in claims)
            {
                _logger.LogInformation($"External provider[{provider}] info-> claim:{claim.Type}, value:{claim.Value}");
            }

            if (user == null)
            {
                // user wasn't found by provider, but maybe one exists with the same email address?
                if (provider == "Google" || provider == "Facebook")
                {
                    // email claim from Google
                    var email = claims.FirstOrDefault(c =>
                                                      c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress");
                    if (email != null)
                    {
                        var userByEmail = await _usersService.GetUserByEmailAsync(email.Value);

                        if (userByEmail != null)
                        {
                            // add Google as a provider for this user
                            await _usersService.AddUserLoginAsync(userByEmail.SubjectId, provider, providerUserId);

                            // redirect to ExternalLoginCallback
                            var continueWithUrlAfterAddingUserLogin =
                                Url.Action("Callback", new { returnUrl = returnUrl });
                            return(Redirect(continueWithUrlAfterAddingUserLogin));
                        }
                    }
                }


                var returnUrlAfterRegistration = Url.Action("Callback", new { returnUrl = returnUrl });
                var continueWithUrl            = Url.Action("RegisterUser", "UserRegistration",
                                                            new { returnUrl = returnUrlAfterRegistration, provider = provider, providerUserId = providerUserId });
                return(Redirect(continueWithUrl));
            }

            // 2-F.A
            var id = new ClaimsIdentity();

            id.AddClaim(new Claim(JwtClaimTypes.Subject, user.SubjectId));
            await HttpContext.SignInAsync(scheme : Startup.TwoFactorAuthenticationScheme,
                                          principal : new ClaimsPrincipal(id));

            await _twoFactorAuthenticationService.SendTemporaryCodeAsync(user.SubjectId);

            var redirectToAdditionalFactorUrl =
                Url.Action("AdditionalAuthenticationFactor",
                           new
            {
                returnUrl      = returnUrl,
                rememberLogin  = false,
                provider       = provider,
                providerUserId = providerUserId
            });

            if (Url.IsLocalUrl(returnUrl))
            {
                return(Redirect(redirectToAdditionalFactorUrl));
            }

            if (string.IsNullOrEmpty(returnUrl))
            {
                return(Redirect("~/"));
            }

            // user might have clicked on a malicious link - should be logged
            throw new Exception("invalid return URL");
        }