繁体   English   中英

如何从 asp.net web api 中的身份声明获取 JWT 身份验证的登录用户

[英]How to get JWT authenticated sign-in user from identity claims in asp.net web api

我实现了一个 JWT 令牌身份验证,其中注册和登录工作正常。

这就是我通常使用内置身份验证所做的事情

var currentUser = await _userManager.GetUserAsync(HttpContext.User); 
var category = _context.Categories.Where(m=>m.ApplicationUserId == currentUser.Id); 
return View(await category.ToListAsync());

我将从 httpContext 中获取当前登录的用户,然后将当前用户 ID(即当前用户的应用程序用户 ID)与应用程序用户 ID 匹配并返回匹配列表。

如果条件不匹配,则执行其他操作。

我似乎无法通过 JWT 身份验证获得此信息。 我正在使用 blazor 客户端

我尝试了不同的方法,但仍然没有得到它。 我以为我可以像这样获得当前用户,但我获得了应用程序用户 ID。 我正在获取当前用户的用户名。

        internal async Task<List<Staff>> GetAllStaffServices()
        {
            var currentUser = httpContextAccessor.HttpContext.User.Identity.Name.ToString();
            var another = userManager.FindByNameAsync(currentUser);

            //var userId = this.User.FindFirst(ClaimTypes.NameIdentifier).Value;
            var staff = applicationDbContext.Staffs.Where(m => m.ApplicationUserId == another.Id);

            return await staffs.ToListAsync();
        }

这是我的登录方法

    public async Task<IActionResult> Login([FromBody] LoginModel login)
        {
            var result = await _signInManager.PasswordSignInAsync(login.UserName, login.Password, false, false);

            if (!result.Succeeded) return BadRequest(new LoginResult { Successful = false, Error = "Username and password are invalid." });

            var user = await _signInManager.UserManager.FindByNameAsync(login.UserName);
            var roles = await _signInManager.UserManager.GetRolesAsync(user);

            var claims = new List<Claim>();


            claims.Add(new Claim(ClaimTypes.Name, login.UserName));
            claims.Add(new Claim(JwtRegisteredClaimNames.Jti, user.Id));
            claims.Add(new Claim(JwtRegisteredClaimNames.Email, user.Email));

            foreach (var role in roles)
            {
                claims.Add(new Claim(ClaimTypes.Role, role));
            }

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtSecurityKey"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expiry = DateTime.Now.AddDays(Convert.ToInt32(_configuration["JwtExpiryInDays"]));

            var token = new JwtSecurityToken(
                _configuration["JwtIssuer"],
                _configuration["JwtAudience"],
                claims,
                expires: expiry,
                signingCredentials: creds
            );

            return Ok(new LoginResult { Successful = true, Token = new JwtSecurityTokenHandler().WriteToken(token) });
        }
    }

配置服务

     public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddDefaultIdentity<RegisterInfoModel>().AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        options.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuer = true,
                            ValidateAudience = true,
                            ValidateLifetime = true,
                            ValidateIssuerSigningKey = true,
                            ValidIssuer = Configuration["JwtIssuer"],
                            ValidAudience = Configuration["JwtAudience"],
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSecurityKey"]))
                        };
                    });
            services.AddScoped<StaffServices>();
            services.AddMvc().AddNewtonsoftJson();
            services.AddResponseCompression(opts =>
            {
                opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
                    new[] { "application/octet-stream" });
            });
        }

  • 您不应将 user.Id 添加为声明。 做什么的 ?
  • 您不应将 user.Email 添加为声明。 做什么的 ? 用户名 == 电子邮件
  • 现在,您可以在由 Authorize 属性注释的 Web Api 端点中,编写如下代码:

     var userName = HttpContext.User.Identity.Name.ToString(); var user= userManager.FindByNameAsync(userName); var staff = applicationDbContext.Staffs.Where(m => m.ApplicationUser.Id == user.Id); return await staffs.ToListAsync();

注意:不需要使用 HttpContextAccessor... HttpContext 在控制器中可用

这里的代码与您的非常相似。 它从 HttpContext 中提取用户名,调用 FindByNameAsync 来检索用户,然后使用它。

请运行它并报告是否正常。 如果没有,请报告问题。

更新:如果您希望将用户 ID 添加到 Jwt 令牌,除了用户名之外,您还应该在 Login 方法中执行以下操作:

claims.Add(new Claim(ClaimTypes.Name, login.UserName));
 claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id));

并且要从 GetAllStaffServices 方法中获取用户 ID,您可以调用 UserManager.GetUserId,将一个从 HttpContext 中提取的声明主体对象传递给它:

var userId = UserManager.GetUserId (HttpContext.User);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM