我們的商店已經使用 ServiceStack 庫好幾年了,沒有出現很多問題。最近,從 5.12 版本升級到 6.0 版本后,我們看到一個基于憑證的身份驗證請求沒有回傳 BearerToken。
我已經閱讀了關于 JWT 更改的發行說明部分,這里,我理解“重大”更改,以及這里,它描述了如何恢復為在回應中回傳不記名令牌。但是,建議的更改是針對 JwtAuthProvider,而不是 CredentialsAuthProvider。CredentialsAuthProvider 沒有 UseTokenCookie 屬性。
當身份驗證提供程式是 CredentialsAuthProvider 時,是否有辦法恢復在身份驗證回應中回傳不記名令牌?
對于它的價值,這里是相關的服務器代碼:
public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
private readonly IDbContext _dbContext;
private const string AuthProviderType = "credentials";
public CustomCredentialsAuthProvider(IDbContext dbContext)
{
_dbContext = dbContext;
}
public override async Task<bool> TryAuthenticateAsync(IServiceBase authService,
string userName, string password, CancellationToken token=default)
{
var userAuthentication = _dbContext.GetUserAuthenticationData(userName);
return (userAuthentication != null && HashHelper.VerifyHash(password, userAuthentication.PasswordSalt, userAuthentication.PasswordHash));
}
public override async Task<IHttpResult> OnAuthenticatedAsync(IServiceBase authService,
IAuthSession session, IAuthTokens tokens,
Dictionary<string, string> authInfo, CancellationToken token=default)
{
var customUserSession = (CustomUserSession)session;
var userId = _dbContext.GetUserId(string.Empty, customUserSession.UserAuthName);
if (!userId.HasValue) throw new AuthenticationException("Unable to locate UserId");
var claims = _dbContext.GetClaims(userId.Value);
var postalCode = _dbContext.GetPostalCode(userId.Value);
HydrateCustomUserSession(claims.ToList(), customUserSession, postalCode);
//Call base method to Save Session and fire Auth/Session callbacks:
return result = await base.OnAuthenticatedAsync(authService, customUserSession, tokens, authInfo, token);
}
private void HydrateCustomUserSession(IReadOnlyCollection<Claims> claims, CustomUserSession customUserSession, string postalCode)
{
customUserSession.AuthProvider = AuthProviderType;
customUserSession.CreatedAt = DateTime.UtcNow;
customUserSession.UserId = Convert.ToInt32(claims.First(item => item.ClaimName == "sub").ClaimValue);
customUserSession.UserStatusId = Convert.ToInt32(claims.First(item => item.ClaimName == "user_status_id").ClaimValue);
customUserSession.UserAuthId = claims.First(item => item.ClaimName == "sub").ClaimValue;
customUserSession.FirstName = claims.First(item => item.ClaimName == "given_name").ClaimValue;
customUserSession.LastName = claims.First(item => item.ClaimName == "family_name").ClaimValue;
customUserSession.Email = claims.First(item => item.ClaimName == "email").ClaimValue;
customUserSession.Company = claims.First(item => item.ClaimName == "company_name").ClaimValue;
customUserSession.CompanyId = Convert.ToInt32(claims.First(item => item.ClaimName == "company_id").ClaimValue);
customUserSession.CompanyTypeId = Convert.ToInt32(claims.First(item => item.ClaimName == "company_type_id").ClaimValue);
customUserSession.PostalCode = postalCode;
var productIds = claims.First(item => item.ClaimName == "product_ids").ClaimValue;
if (!string.IsNullOrEmpty(productIds))
{
customUserSession.ProductIds = productIds.Split(",").Select(int.Parse).ToList();
}
else
{
customUserSession.ProductIds = new List<int>();
}
var productFeatureIds = claims.First(item => item.ClaimName == "product_feature_ids").ClaimValue;
if (!string.IsNullOrEmpty(productFeatureIds))
{
customUserSession.ProductFeatureIds = productFeatureIds.Split(",").Select(int.Parse).ToList();
}
else
{
customUserSession.ProductFeatureIds = new List<int>();
}
var userRoles = claims.First(item => item.ClaimName == "user_roles").ClaimValue;
if (!string.IsNullOrEmpty(userRoles))
{
customUserSession.UserRoles = userRoles.Split(",").Select(x => new UserRole(x)).ToList();
}
else
{
customUserSession.UserRoles = new List<UserRole>();
}
}
}
在客戶端,這是一個批處理驅動的處理器,而不是 Web 應用程式。身份驗證部分在這里:
private static void GetBearerToken()
{
var authRequest = new Authenticate()
{
UserName = ConfigHelper.ServiceUserName,
Password = ConfigHelper.ServicePassword,
provider = "credentials",
RememberMe = true
};
var authResponse = _authServiceClient.Post(authRequest);
// BearerToken was returned until the auth service was updated to using ServiceStack 6.0
// After using 6.0, BearerToken is empty.
_myOtherServiceClient.BearerToken = authResponse.BearerToken;
}
填充后,不記名令牌用于驗證對其他服務的呼叫。謝謝你的幫助!
uj5u.com熱心網友回復:
如果您使用的是 JWT,您將JwtAuthProvider在AuthFeature插件中進行配置,這是需要配置的UseTokenCookie=false,以便在回應 DTO 上填充 JWT 令牌(即,而不是使用令牌 Cookie),如鏈接檔案。
new JwtAuthProvider(AppSettings) {
UseTokenCookie = false
}
盡管您應該考慮使用推薦的 JWT 令牌 cookie,因為成功的身份驗證仍然會產生經過身份驗證的_authServiceClient:
var authResponse = _authServiceClient.Post(authRequest);
// manual JWT handling is unnecessary when using Token Cookies
//_myOtherServiceClient.BearerToken = authResponse.BearerToken;
由于 JWT 令牌在 HTTP Cookie 中回傳,這將節省手動處理/填充承載令牌所需的額外作業,包括服務器自動重繪 v6 中過期的 JWT 承載令牌。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/450889.html
上一篇:通過OAuth2(OpenIDConnect)獲得的令牌存盤在哪里
下一篇:laravel護照可選認證
