如何从.net核心中的控制器操作中的动作过滤器访问对象?

问题描述 投票:0回答:2

在我正在构建的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);

在我装饰属性的所有控制器动作中。

在旁注有没有更好的方法来解决它,欢迎提出建议。

c# asp.net-web-api asp.net-core attributes
2个回答
1
投票

我认为你做得很好,但不明白为什么你需要访问该对象。

如果我是对的,你应该抓住异常来决定是否应该执行该动作。

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
        }
    }

我希望能帮助你。


0
投票

我找到了一个解决方法,即在字典中添加对象

context.HttpContext.Items.Add("jwt", jwtObject);

可以通过控制器访问

this.HttpContext.Items.ContainsKey("jwt")
© www.soinside.com 2019 - 2024. All rights reserved.