public async Task ShouldAllowAdminImpersonateOthers()
        {
            const string userName = "******";
            var          claims   = new[]
            {
                new Claim(ClaimTypes.Name, userName),
                new Claim(ClaimTypes.Role, UserRoles.Admin)
            };
            var jwtAuthManager = _serviceProvider.GetRequiredService <IJwtAuthManager>();
            var jwtResult      = jwtAuthManager.GenerateTokens(userName, claims, DateTime.Now.AddMinutes(-1));

            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(JwtBearerDefaults.AuthenticationScheme, jwtResult.AccessToken);
            var request = new ImpersonationRequest {
                UserName = "******"
            };
            var response = await _httpClient.PostAsync("api/account/impersonation",
                                                       new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, MediaTypeNames.Application.Json));

            var responseContent = await response.Content.ReadAsStringAsync();

            var result = JsonSerializer.Deserialize <LoginResult>(responseContent);

            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
            Assert.AreEqual(request.UserName, result.UserName);
            Assert.AreEqual(userName, result.OriginalUserName);
            Assert.AreEqual(UserRoles.BasicUser, result.Role);
            Assert.IsFalse(string.IsNullOrWhiteSpace(result.AccessToken));
            Assert.IsFalse(string.IsNullOrWhiteSpace(result.RefreshToken));

            var(principal, jwtSecurityToken) = jwtAuthManager.DecodeJwtToken(result.AccessToken);
            Assert.AreEqual(request.UserName, principal.Identity.Name);
            Assert.AreEqual(UserRoles.BasicUser, principal.FindFirst(ClaimTypes.Role).Value);
            Assert.AreEqual(userName, principal.FindFirst("OriginalUserName").Value);
            Assert.IsNotNull(jwtSecurityToken);
        }
Пример #2
0
        /// <inheritdoc />
        public async Task <Uri> GetImpersonationUrlAsync(ImpersonationRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            var body = new
            {
                protocol        = request.Protocol,
                impersonator_id = request.ImpersonatorId,
                client_id       = request.ClientId,
                response_type   = request.ResponseType,
                state           = request.State
            };

            var response = await connection.SendAsync <string>(
                HttpMethod.Post,
                BuildUri($"users/{request.ImpersonateId}/impersonate"),
                body,
                BuildHeaders(request.Token)
                ).ConfigureAwait(false);

            return(new Uri(response));
        }
        public async Task ShouldReturnBadRequestIfStopImpersonationWhenNotImpersonating()
        {
            const string userName = "******";
            var          claims   = new[]
            {
                new Claim(ClaimTypes.Name, userName),
                new Claim(ClaimTypes.Role, UserRoles.BasicUser)
            };
            var jwtAuthManager = _serviceProvider.GetRequiredService <IJwtAuthManager>();
            var jwtResult      = jwtAuthManager.GenerateTokens(userName, claims, DateTime.Now.AddMinutes(-1));

            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(JwtBearerDefaults.AuthenticationScheme, jwtResult.AccessToken);
            var request = new ImpersonationRequest {
                UserName = "******"
            };
            var response = await _httpClient.PostAsync("api/account/stop-impersonation",
                                                       new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, MediaTypeNames.Application.Json));

            Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);
        }
        /// <summary>
        /// Generates a link that can be used once to log in as a specific user.
        /// </summary>
        /// <param name="request">The <see cref="ImpersonationRequest"/> containing the details of the user to impersonate.</param>
        /// <returns>A <see cref="Uri"/> which can be used to sign in as the specified user.</returns>
        public async Task <Uri> GetImpersonationUrlAsync(ImpersonationRequest request)
        {
            string url = await Connection.PostAsync <string>("users/{impersonate_id}/impersonate",
                                                             new
            {
                protocol        = request.Protocol,
                impersonator_id = request.ImpersonatorId,
                client_id       = request.ClientId,
                response_type   = request.ResponseType,
                state           = request.State
            }, null, null,
                                                             new Dictionary <string, string>
            {
                { "impersonate_id", request.ImpersonateId }
            },
                                                             new Dictionary <string, object>
            {
                { "Authorization", $"Bearer {request.Token}" }
            }, null).ConfigureAwait(false);

            return(new Uri(url));
        }
Пример #5
0
        public async Task <ActionResult <LoginResult> > Impersonate([FromBody] ImpersonationRequest request)
        {
            var email = User.Identity.Name;

            _logger.LogInformation($"User [{email}] is trying to impersonate [{request.Email}].");

            var impersonatedRole = await _userService.GetUserRoleAsync(request.Email);

            if (string.IsNullOrWhiteSpace(impersonatedRole))
            {
                _logger.LogInformation($"User [{email}] failed to impersonate [{request.Email}] due to the target user not found.");
                return(BadRequest($"The target user [{request.Email}] is not found."));
            }
            if (impersonatedRole == Policies.Admin)
            {
                _logger.LogInformation($"User [{email}] is not allowed to impersonate another Admin.");
                return(BadRequest("This action is not supported."));
            }

            var claims = new[]
            {
                new Claim(ClaimTypes.Name, request.Email),
                new Claim(ClaimTypes.Role, impersonatedRole),
                new Claim("OriginalEmail", email)
            };

            var jwtResult = await _jwtAuthManager.GenerateTokensAsync(request.Email, claims, DateTime.Now);

            _logger.LogInformation($"User [{request.Email}] is impersonating [{request.Email}] in the system.");

            return(new LoginResult
            {
                Email = request.Email,
                Role = impersonatedRole,
                OriginalEmail = email,
                AccessToken = jwtResult.AccessToken,
                RefreshToken = jwtResult.RefreshToken.TokenString
            });
        }
Пример #6
0
        public ActionResult Impersonate([FromBody] ImpersonationRequest request)
        {
            var userName = User.Identity.Name;

            _logger.LogInformation($"User [{userName}] is trying to impersonate [{request.UserName}].");

            var impersonatedRole = _userService.GetUserRole(request.UserName);

            if (string.IsNullOrWhiteSpace(impersonatedRole))
            {
                _logger.LogInformation($"User [{userName}] failed to impersonate [{request.UserName}] due to the target user not found.");
                return(BadRequest($"The target user [{request.UserName}] is not found."));
            }
            if (impersonatedRole == UserRoles.Admin)
            {
                _logger.LogInformation($"User [{userName}] is not allowed to impersonate another Admin.");
                return(BadRequest("This action is not supported."));
            }

            var claims = new[]
            {
                new Claim(ClaimTypes.Name, request.UserName),
                new Claim(ClaimTypes.Role, impersonatedRole),
                new Claim("OriginalUserName", userName)
            };

            var jwtResult = _jwtAuthManager.GenerateTokens(request.UserName, claims, DateTime.Now);

            _logger.LogInformation($"User [{request.UserName}] is impersonating [{request.UserName}] in the system.");
            return(Ok(new LoginResult
            {
                UserName = request.UserName,
                Role = impersonatedRole,
                OriginalUserName = userName,
                AccessToken = jwtResult.AccessToken,
                RefreshToken = jwtResult.RefreshToken.TokenString
            }));
        }
 public Task <Uri> GetImpersonationUrlAsync(ImpersonationRequest request)
 {
     return(_inner.GetImpersonationUrlAsync(request));
 }
 public Task <Uri> GetImpersonationUrlAsync(ImpersonationRequest request, CancellationToken cancellationToken = default)
 {
     return(_inner.GetImpersonationUrlAsync(request, cancellationToken));
 }