【问题标题】:Unable to cast HttpContext to User无法将 HttpContext 强制转换为用户
【发布时间】:2021-06-09 08:36:13
【问题描述】:

我正在使用 Web API。我遵循了有关实施 JWT Auth 的教程。当我使用 Postman 并获得令牌并尝试进行身份验证时,它可以工作,但我无法将 HttpContext 转换为 User 类。

错误:

“无法转换类型的对象 'AsyncStateMachineBox1[TechStore.Api.Data.Enteties.User,TechStore.Api.Data.Repositories.GenericRepository1+d__5[TechStore.Api.Data.Enteties.User]]' 输入“TechStore.Api.Data.Enteties.User”。”

关于授权方法:

public void OnAuthorization(AuthorizationFilterContext context)
        {
            var user = (User)context.HttpContext.Items["User"]; //Here it throws error
 
            if (user == null)
            {
                context.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized };
            }
        }

httpcontext 中的数据是正确的,但我无法将其转换为用户对象。

用户类别:

public class User
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public string Username { get; set; }

        public string Email { get; set; }

        public string Password { get; set; }

        public string LastName { get; set; }

        public string Adress { get; set; }

        public string PhoneNumber { get; set; }

        public int Age { get; set; }

        public Cart Cart { get; set; }

        public int CartId { get; set; }
    }

JWTAuthntictor 类:

namespace TechStore.Api.Helpers
{
    public class JWTAuthenticator
    {
        private readonly RequestDelegate _next;

        public JWTAuthenticator
            (
                RequestDelegate next
            )
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context, IRepository<User> userService)
        {
            var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();

            if (token != null)
                attachUserToContext(context, userService, token);

            await _next(context);
        }

        private void attachUserToContext(HttpContext context, IRepository<User> userService, string token)
        {
            try
            {
                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.ASCII.GetBytes("acdc11434jjkk34311acdasdwjkdnovjfnbcacacasdadc11434jjkk314311acdc");
                tokenHandler.ValidateToken(token, new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    // set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later)
                    ClockSkew = TimeSpan.Zero
                }, out SecurityToken validatedToken);

                var jwtToken = (JwtSecurityToken)validatedToken;
                var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value);

                // attach user to context on successful jwt validation
                context.Items["User"] = userService.GetByProperty(u => u.Id == userId);
            }
            catch
            {
                // do nothing if jwt validation fails
                // user is not attached to context so request won't have access to secure routes
            }
        }

    }
}

Athorize 属性:

public class AuthorizeAttribute : Attribute, IAuthorizationFilter
    {
        public AuthorizeAttribute()
        {
        }

        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var user = (User)context.HttpContext.Items["User"];
 
            if (user == null)
            {
                context.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized };
            }
        }
    }

【问题讨论】:

  • 你是否得到了预期的对象而不进行强制转换?相同的属性?类型?价值观? var user = context.HttpContext.Items["User"];
  • JSON 响应是否正确解密以匹配 c# 类?

标签: c# asp.net api authentication jwt


【解决方案1】:

我也有同样的情况。 对我来说这一行:

var user = (User)context.HttpContext.Items["User"];

确实在 NET Core 3.1 项目上工作过, 但在另一个使用 NET Core 5 的项目中,我得到了这个确切的例外。

如果你只需要检查用户不为空,那么你不需要强制转换 User 对象的上下文项。

相反,您可以这样做,并且您的 if 检查将起作用:

        //var user = (User)context.HttpContext.Items["User"];
        var user = context.HttpContext.Items["User"];//remove casting
        if (user == null)
        {
            context.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized };
        }

我想不通的是如何访问附加图像中的结果(这是您可能想要的实际对象)。

也许其他人可以澄清这一点。

【讨论】:

    猜你喜欢
    • 2018-09-05
    • 2018-05-12
    • 2023-03-17
    • 2013-03-07
    • 2015-06-16
    • 2017-04-28
    • 1970-01-01
    • 2022-07-15
    • 1970-01-01
    相关资源
    最近更新 更多