我必须在 Thread.CurrentPrincipal 中保存一个令牌,然后才能将其传递给外部 API,以免在应用程序周围携带令牌。在此类中,我检查令牌是否正确有效:
public class MyAuthenticationFilter : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext filterContext)
{
var authorization = filterContext.Request.Headers.Authorization;
if (authorization == null || authorization.Scheme != "Bearer" || string.IsNullOrEmpty(authorization.Parameter))
{
filterContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
return;
}
var principal = ValidateToken(authorization.Parameter);
if (!principal.Identity.IsAuthenticated)
{
filterContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
Thread.CurrentPrincipal = principal;
if (filterContext.RequestContext != null)
{
filterContext.RequestContext.Principal = principal;
}
}
public ClaimsPrincipal ValidateToken(string token)
{
SecurityToken securityToken;
return new JwtSecurityTokenHandler().ValidateToken(token, GetTokenValidationParameters(), out securityToken);
}
#region Private Methods
private static TokenValidationParameters GetTokenValidationParameters()
{
var identityServerUrl = StatiConfigurationService.Instance.GetValue("url");
var client = new HttpClient();
var res = client.GetAsync(identityServerUrl + "/.well-known/openid-configuration/jwks").GetAwaiter().GetResult();
var keyList = new JsonWebKeySet(res.Content.ReadAsStringAsync().GetAwaiter().GetResult()).GetSigningKeys();
var validation = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
ValidateIssuer = false,
TokenDecryptionKeys = keyList,
IssuerSigningKeys = keyList,
RequireSignedTokens = true,
RequireExpirationTime = true,
ValidateLifetime = true,
ValidIssuer = identityServerUrl,
ValidAudience = "Vendor.Api",
ValidateAudience = true,
};
return validation;
}
#endregion
}
有什么办法可以保存我的令牌?
更新 最后我找到了解决方案:在行 var principal = ValidateToken(authorization.Parameter); 之后
var identity = (ClaimsIdentity)(principal.Identity);
identity.AddClaim(new Claim("Token", authorization.Parameter));
并检索令牌
var token = ((ClaimsPrincipal)Thread.CurrentPrincipal)
.Claims.Where(c => c.Type.Equals("Token"))
.Select(c => c.Value).SingleOrDefault();