I’ve made an impersonation function, returning a custom crafted JWT.
object Impersonate(IUserAuth impersonatedUserAuth)
{
var session = (CustomUserSession)GetSession();
if (session.ImpersonatedByUserName != null)
throw new MasterServiceException("Already impersonated.");
var realUsername = session.UserAuthName;
var realRoles = session.Roles;
if (impersonatedUserAuth.Roles.Contains("Admin") && !realRoles.Contains("Admin"))
throw new MasterServiceException("You are not allowed to impersonate this user");
var jwtProvider = (JwtAuthProvider)AuthenticateService.GetJwtAuthProvider();
var header = JwtAuthProvider.CreateJwtHeader(jwtProvider.HashAlgorithm);
var body = JwtAuthProvider.CreateJwtPayload(new AuthUserSession // only base class is JWT'ed
{
UserAuthId = impersonatedUserAuth.Id.ToString(),
UserName = impersonatedUserAuth.UserName,
DisplayName = impersonatedUserAuth.DisplayName,
Email = impersonatedUserAuth.Email,
IsAuthenticated = true,
},
issuer: jwtProvider.Issuer,
expireIn: TimeSpan.FromMinutes(1), // impersonation shouldn't last very long
audiences: new[] { jwtProvider.Audience },
roles: impersonatedUserAuth.Roles,
permissions: impersonatedUserAuth.Permissions
);
// manually add these to the JWT body, prefixed with http://mycompany.com, Auth0's best practice
body.Add("http://mycompany.com/ImpersonatedByUserName", realUsername);
body.Add("http://mycompany.com/ImpersonatedForTestOnly", realRoles.Contains("Admin") ? "false" : "true");
var jwtToken = JwtAuthProvider.CreateJwt(header, body, jwtProvider.GetHashAlgorithm());
return new HttpResult(new
{
userId = impersonatedUserAuth.Id,
UserName = impersonatedUserAuth.UserName,
DisplayName = impersonatedUserAuth.DisplayName,
Email = impersonatedUserAuth.Email,
roles = impersonatedUserAuth.Roles,
permissions = impersonatedUserAuth.Permissions,
BearerToken = jwtToken,
realUsername = realUsername
})
{ // put token in Cookie
Cookies = {
new System.Net.Cookie("ss-tok", jwtToken, "/") {
HttpOnly = true,
Secure = Request.IsSecureConnection,
Expires = DateTime.UtcNow.Add(jwtProvider.ExpireTokensIn),
}
}
};
This works beautifully, even in SS UI.
However, because of the short expiration (usually 30 min), after the token has expired (I’m using token as cookie), SS will somehow find back to a previous token. Probably this has something to do with the session.
I suspect I’ll need to do something with the session as well as just return the token cookie?
I’ve debugged and this happens:
- I impersonate and get back the new JWT in ss-tok
- After expiry, suddenly I get another JWT back (with my real user).