首页 > 解决方案 > 如何从 .net 核心的控制器操作中的操作过滤器访问对象?

问题描述

在我正在构建的 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-apiasp.net-coreattributes

解决方案


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

如果我是正确的,你应该捕获异常来决定是否应该执行动作。

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

我希望能帮助你。


推荐阅读