冒充用户在 JWT 中嵌入了错误的详细信息
Impersonating user embeds wrong details inside JWT
我正在使用以下服务获取 JWT 令牌来模拟用户。
[Authenticate]
[RequiredRole(nameof(UserRoles.Admin))]
public class ImpersonateUserService : Service
{
private static ILog Log = LogManager.GetLogger(typeof(ImpersonateUserService));
public ImpersonateUserResponse Any(ImpersonateUserRequest request)
{
var user = Db.SingleById<UserAuthCustom>(request.UserId);
using (var service = base.ResolveService<AuthenticateService>()) //In Process
{
var resp = service.PostAsync(new Authenticate
{
provider = AuthenticateService.CredentialsProvider,
UserName = user.UserName ?? user.Email,
UseTokenCookie = true, // if using JWT
}).Result;
var token = ((AuthenticateResponse)resp).BearerToken;
return new ImpersonateUserResponse()
{
Success = true,
Token = token,
Email = user.Email,
DisplayName = user.DisplayName,
UserId = user.Id,
UserRole = (UserRoles)Enum.Parse(typeof(UserRoles), user.Roles[0]),
UserName = user.UserName ?? user.Email
};
}
}
}
public class ImpersonateUserRequest : IReturn<ImpersonateUserResponse>
{
public int UserId { get; set; }
}
public class ImpersonateUserResponse : ApiMessage
{
public string Token { get; set; }
public string Email { get; set; }
public string DisplayName { get; set; }
public string UserName { get; set; }
public int UserId { get; set; }
public UserRoles UserRole { get; set; }
}
问题是,当使用令牌时,它会激活管理员详细信息而不是模拟用户。如果我解码模拟令牌,我可以看到:
{
"sub": 1,
"iat": 1623677160,
"exp": 1624886760,
"email": "email@example.com",
"given_name": "admin name",
"name": "admin name",
"roles": [
"Admin"
],
"jti": 9
}
此令牌将允许我根据模拟用户角色访问端点(即根据“用户”角色而不是管理员身份验证的端点),但会在请求时带回管理员详细信息SessionAs<CustomUserSession>
。
获取包含正确详细信息的令牌的最佳方法是什么?
将回答我自己的问题,因为文档建议模拟用户不会模拟会话。
为了让它工作,我必须在模拟端点中完全创建 JWT
var user = Db.SingleById<UserAuthCustom>(request.UserId);
var customSession = new CustomUserSession()
{
UserAuthId = user.Id.ToString(),
UserName = user.UserName,
DisplayName = user.DisplayName,
Email = user.Email,
IsAuthenticated = true,
Roles = user.Roles
};
var jwtProvider = new JwtAuthProvider(Settings)
{
AuthKeyBase64 = Settings.GetString("auth:key")
};
var header = JwtAuthProvider.CreateJwtHeader(jwtProvider.HashAlgorithm);
var body = JwtAuthProvider.CreateJwtPayload(
customSession,
issuer: jwtProvider.Issuer,
expireIn: jwtProvider.ExpireTokensIn,
roles: user.Roles
);
var jwtToken = JwtAuthProvider.CreateJwt(header, body, jwtProvider.GetHashAlgorithm());
return new ImpersonateUserResponse()
{
Success = true,
Token = jwtToken,
Email = user.Email,
DisplayName = user.DisplayName,
UserId = user.Id,
UserRole = (UserRoles)Enum.Parse(typeof(UserRoles), user.Roles[0]),
UserName = user.UserName ?? user.Email
};
我正在使用以下服务获取 JWT 令牌来模拟用户。
[Authenticate]
[RequiredRole(nameof(UserRoles.Admin))]
public class ImpersonateUserService : Service
{
private static ILog Log = LogManager.GetLogger(typeof(ImpersonateUserService));
public ImpersonateUserResponse Any(ImpersonateUserRequest request)
{
var user = Db.SingleById<UserAuthCustom>(request.UserId);
using (var service = base.ResolveService<AuthenticateService>()) //In Process
{
var resp = service.PostAsync(new Authenticate
{
provider = AuthenticateService.CredentialsProvider,
UserName = user.UserName ?? user.Email,
UseTokenCookie = true, // if using JWT
}).Result;
var token = ((AuthenticateResponse)resp).BearerToken;
return new ImpersonateUserResponse()
{
Success = true,
Token = token,
Email = user.Email,
DisplayName = user.DisplayName,
UserId = user.Id,
UserRole = (UserRoles)Enum.Parse(typeof(UserRoles), user.Roles[0]),
UserName = user.UserName ?? user.Email
};
}
}
}
public class ImpersonateUserRequest : IReturn<ImpersonateUserResponse>
{
public int UserId { get; set; }
}
public class ImpersonateUserResponse : ApiMessage
{
public string Token { get; set; }
public string Email { get; set; }
public string DisplayName { get; set; }
public string UserName { get; set; }
public int UserId { get; set; }
public UserRoles UserRole { get; set; }
}
问题是,当使用令牌时,它会激活管理员详细信息而不是模拟用户。如果我解码模拟令牌,我可以看到:
{
"sub": 1,
"iat": 1623677160,
"exp": 1624886760,
"email": "email@example.com",
"given_name": "admin name",
"name": "admin name",
"roles": [
"Admin"
],
"jti": 9
}
此令牌将允许我根据模拟用户角色访问端点(即根据“用户”角色而不是管理员身份验证的端点),但会在请求时带回管理员详细信息SessionAs<CustomUserSession>
。
获取包含正确详细信息的令牌的最佳方法是什么?
将回答我自己的问题,因为文档建议模拟用户不会模拟会话。
为了让它工作,我必须在模拟端点中完全创建 JWT
var user = Db.SingleById<UserAuthCustom>(request.UserId);
var customSession = new CustomUserSession()
{
UserAuthId = user.Id.ToString(),
UserName = user.UserName,
DisplayName = user.DisplayName,
Email = user.Email,
IsAuthenticated = true,
Roles = user.Roles
};
var jwtProvider = new JwtAuthProvider(Settings)
{
AuthKeyBase64 = Settings.GetString("auth:key")
};
var header = JwtAuthProvider.CreateJwtHeader(jwtProvider.HashAlgorithm);
var body = JwtAuthProvider.CreateJwtPayload(
customSession,
issuer: jwtProvider.Issuer,
expireIn: jwtProvider.ExpireTokensIn,
roles: user.Roles
);
var jwtToken = JwtAuthProvider.CreateJwt(header, body, jwtProvider.GetHashAlgorithm());
return new ImpersonateUserResponse()
{
Success = true,
Token = jwtToken,
Email = user.Email,
DisplayName = user.DisplayName,
UserId = user.Id,
UserRole = (UserRoles)Enum.Parse(typeof(UserRoles), user.Roles[0]),
UserName = user.UserName ?? user.Email
};