Пример #1
0
        public async Task <ActionResult> Post([FromBody] UserDto user)
        {
            var hasher = new PasswordHasher <MongoExternalUser>();

            try
            {
                var mongoExternalUser = await _userStore.AutoProvisionUser("IdSrv", user.Username, new List <Claim>
                {
                    new Claim(JwtClaimTypes.Name, user.Username),
                    new Claim(JwtClaimTypes.Email, user.Email)
                });

                var hash = hasher.HashPassword(mongoExternalUser, user.Password);
                await _userStore.SetPasswordHashForUser(mongoExternalUser, hash);

                return(await Task.FromResult(new OkResult()));
            }
            catch (Exception e)
            {
                if (e is UserExistsException)
                {
                    var problem = new ProblemDocument
                    {
                        ProblemType = new Uri("http://tempuri.org/errors/user-already-exists"),
                        Title       = $"User {user.Username} already exists",
                        StatusCode  = HttpStatusCode.BadRequest
                    };

                    var contentResult = new ContentResult();
                    contentResult.Content     = await new ProblemContent(problem).ReadAsStringAsync();
                    contentResult.ContentType = "application/problem+json";
                    contentResult.StatusCode  = (int?)HttpStatusCode.BadRequest;
                    return(await Task.FromResult(contentResult));
                }

                return(await Task.FromResult(new StatusCodeResult(500)));
            }
        }
        public async Task <IActionResult> ExternalLoginCallback()
        {
            // 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 claims of the external user
            var externalUser = result.Principal;
            var claims       = externalUser.Claims.ToList();

            // try to determine the unique id of the external user (issued by the provider)
            // the most common claim type for that are the sub claim and the NameIdentifier
            // depending on the external provider, some other claim type might be used
            var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject);

            if (userIdClaim == null)
            {
                userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
            }
            if (userIdClaim == null)
            {
                throw new Exception("Unknown userid");
            }

            // remove the user id claim from the claims collection and move to the userId property
            // also set the name of the external authentication provider
            claims.Remove(userIdClaim);
            var provider = result.Properties.Items["scheme"];
            var userId   = userIdClaim.Value;

            // this is where custom logic would most likely be needed to match your users from the
            // external provider's authentication result, and provision the user as you see fit.
            //
            // check if the external user is already provisioned
            var user = await _users.FindByExternalProvider(provider, userId);

            if (user == null)
            {
                // this sample simply auto-provisions new external user
                // another common approach is to start a registrations workflow first
                user = await _users.AutoProvisionUser(provider, userId, claims);
            }

            var additionalClaims = new List <Claim> {
                userIdClaim
            };

            // if the external system sent a session id claim, copy it over
            // so we can use it for single sign-out
            var sid = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);

            if (sid != null)
            {
                additionalClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));
            }

            // if the external provider issued an id_token, we'll keep it for signout
            AuthenticationProperties props = null;
            var id_token = result.Properties.GetTokenValue("id_token");

            if (id_token != null)
            {
                props = new AuthenticationProperties();
                props.StoreTokens(new[] { new AuthenticationToken {
                                              Name = "id_token", Value = id_token
                                          } });
            }


            await _events.RaiseAsync(new UserLoginSuccessEvent(provider, userId, user.Subject, user.Username));

            //Subject id has to be set
            await HttpContext.SignInAsync(user.Subject, user.Username, provider, props, additionalClaims.ToArray());

            // delete temporary cookie used during external authentication
            await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);

            // validate return URL and redirect back to authorization endpoint or a local page
            var returnUrl = result.Properties.Items["returnUrl"];

            if (_interaction.IsValidReturnUrl(returnUrl) || Url.IsLocalUrl(returnUrl))
            {
                return(Redirect(returnUrl));
            }

            return(Redirect("~/"));
        }