在我正在构建的web api中,一些控制器具有从React接收jwttoken作为参数的动作,如下所示。
public async Task<IActionResult> post(string token)
{
if (!string.IsNullOrEmpty(token))
{
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
var jsonDecoded = decoder.Decode(token);
var jwtObject = JsonConvert.DeserializeObject<JwtToken>(jsonDecoded);
//do some business logic
}
很多方法都有相同的代码被复制以通过解码来检查令牌,然后继续进行自己的责任。
我创建了一个身份验证过滤器
public class AuthenticateFilter : Attribute,IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
throw new NotImplementedException();
}
public void OnActionExecuting(ActionExecutingContext context)
{
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
var token = context.HttpContext.Request.QueryString.HasValue ? context.HttpContext.Request.QueryString.Value.Substring(7):String.Empty;
var jsonDecoded = decoder.Decode(token);
var jwtObject = JsonConvert.DeserializeObject<JwtToken>(jsonDecoded);
}
}
我在startup.cs中注册了这个过滤器
services.AddMvc(
options =>
{
options.Filters.Add(new AuthenticateFilter());
options.Filters.Add(typeof(AuthenticateFilter));
}
).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
我正在使用库来解码令牌。 https://github.com/jwt-dotnet/jwt
在解码过滤器中的令牌之后,我将json字符串反序列化为.net类,如下所示。
public class JwtToken
{
[JsonProperty("sub")]
public Guid Sub { get; set; }
[JsonProperty("aud")]
public string Aud { get; set; }
}
我怎样才能访问该对象
var jwtObject = JsonConvert.DeserializeObject<JwtToken>(jsonDecoded);
在我装饰属性的所有控制器动作中。
在旁注有没有更好的方法来解决它,欢迎提出建议。
我认为你做得很好,但不明白为什么你需要访问该对象。
如果我是对的,你应该抓住异常来决定是否应该执行该动作。
public void OnActionExecuting(ActionExecutingContext context)
{
try
{
IJsonSerializer serializer = new JsonNetSerializer();
IDateTimeProvider provider = new UtcDateTimeProvider();
IJwtValidator validator = new JwtValidator(serializer, provider);
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
var token = context.HttpContext.Request.QueryString.HasValue ? context.HttpContext.Request.QueryString.Value.Substring(7) : String.Empty;
var jsonDecoded = decoder.Decode(token);
var jwtObject = JsonConvert.DeserializeObject<JwtToken>(jsonDecoded);
}
catch (TokenExpiredException)
{
Console.WriteLine("Token has expired");
//Do something here
}
catch (SignatureVerificationException)
{
Console.WriteLine("Token has invalid signature");
//Do something here
}
}
我希望能帮助你。
我找到了一个解决方法,即在字典中添加对象
context.HttpContext.Items.Add("jwt", jwtObject);
可以通过控制器访问
this.HttpContext.Items.ContainsKey("jwt")