Identity Server 4 User Impersonation https://ermir.net/topic-17/user-impersonation-with-identity-server-4
// | |
// Controller placed in mvc client project | |
// | |
public class AccountController : Controller | |
{ | |
[Authorize(Roles = "support")] | |
public IActionResult Impersonate(Guid id) | |
{ | |
if (id == Guid.Empty) | |
return BadRequest(); | |
var returnUrl = Url.ActionLink("Impersonated", "Account", new { challenge = true }); | |
var impersonateUrl = $"https://<YOUR SERVER URL IN HERE>/Support/Impersonate/{id}/?returnUrl={returnUrl}"; | |
return Redirect(impersonateUrl); | |
} | |
public IActionResult Impersonated(bool challenge) | |
{ | |
if (challenge) | |
{ | |
return Challenge(new AuthenticationProperties() | |
{ | |
RedirectUri = Url.Action("Index", "Home"), | |
AllowRefresh = false | |
}, "Cookies", "oidc"); | |
} | |
return View(); | |
} | |
} |
// | |
// Controller placed in identity server project | |
// | |
[SecurityHeaders] | |
[Authorize(Roles = "support")] | |
public class SupportController : Controller | |
{ | |
private readonly UserManager<ApplicationUser> _userManager; | |
public SupportController(UserManager<ApplicationUser> userManager) | |
{ | |
_userManager = userManager; | |
} | |
public async Task<IActionResult> Impersonate(string id, string returnUrl) | |
{ | |
var redirectAllowed = RedirectIsAllowed(returnUrl); | |
if (!redirectAllowed) | |
return NoContent(); | |
var dbUser = await _userManager.FindByIdAsync(id); | |
if (dbUser == null) | |
return NotFound(); | |
var userRoles = await _userManager.GetRolesAsync(dbUser); | |
if (userRoles.Where(x => x.Equals("admin")).Any()) | |
return Forbid(); | |
AuthenticationProperties authProps = new AuthenticationProperties | |
{ | |
IsPersistent = false, | |
ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(10)), | |
RedirectUri = returnUrl, | |
AllowRefresh = false, | |
IssuedUtc = DateTime.UtcNow | |
}; | |
var idServerUser = new IdentityServerUser(dbUser.Id) | |
{ | |
DisplayName = dbUser.UserName, | |
AuthenticationTime = DateTime.UtcNow | |
}; | |
await HttpContext.SignOutAsync(); | |
await HttpContext.SignInAsync(idServerUser, authProps); | |
return Redirect(returnUrl); | |
} | |
private bool RedirectIsAllowed(string returnUrl) | |
{ | |
//Verify that return url is from some whitelist | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment