如何从ASP.NET Web API中的身份声明获取JWT身份验证的登录用户 [英] How to get JWT authenticated sign-in user from identity claims in asp.net web api

查看:588
本文介绍了如何从ASP.NET Web API中的身份声明获取JWT身份验证的登录用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I implemented a JWT token authentication where the register and login are working fine.

这是我通常使用内置身份验证的方式

This is what I normally do with inbuilt authentication

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匹配,并返回匹配列表.

I will get the current logged in user from the httpContext, then match the current user id(that is the application user Id of the current user) with the application userid and return the matching list.

如果条件不匹配,请执行其他操作.

if the condition did not match then do something else.

我似乎无法通过JWT身份验证获得此权限.我正在使用blazor客户端

I cant seem to get this with JWT authentication. I am using blazor client

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

I have tried different approach but still not getting it. I thought I could get the current user like this but I the application user Id. I was getting the username of the current user.

        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端点中编写如下代码:

    • You shouldn't add user.Id as a claim. What for ?
    • You shouldn't add user.Email as a claim. What for ? UserName == Email
    • Now you can, in your Web Api end point annotated by Authorize attribute, code something like this:

      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在控制器中可用

      Note: No need to use HttpContextAccessor... HttpContext is available in the controller

      此处的代码与您的代码非常相似.它从HttpContext中解脱用户名,调用FindByNameAsync检索用户,然后使用它.

      The code here is very similar to yours. It extricates the user name from the HttpContext, call the FindByNameAsync to retrieve the user, and then use it.

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

      Please, run it and report if its OK. If not, report the issue.

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

      Update: If you wish to add the user Id to the Jwt token, in addition to the user name, you should do the following in your Login method:

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

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

      And to get the user id from the GetAllStaffServices method, you can call UserManager.GetUserId, passing it a claims principal object extracted from HttpContext:

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

      这篇关于如何从ASP.NET Web API中的身份声明获取JWT身份验证的登录用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆