【问题标题】:How can I Use JWT Token to Manage User Identity?如何使用 JWT Token 管理用户身份?
【发布时间】:2020-10-28 09:09:09
【问题描述】:

我有一个使用 JWT 身份验证并在登录时发出令牌的 API 项目。

我正在使用 ASP.NET 核心 MVC 项目作为客户端

在客户端应用程序中成功登录后,将返回一个 JWT 令牌, 现在我有了 JWT 令牌,

如何在我的客户端应用程序中访问 User.Identity?

我需要做什么才能在整个应用程序中获取和使用用户身份?

如何在客户端应用程序中管理授权?

API 项目

  // configure strongly typed settings objects
            var appSettingsSection = Configuration.GetSection("JwtSettings");
            services.Configure<JwtSettings>(appSettingsSection);


            // configure jwt authentication
            var appSettings = appSettingsSection.Get<JwtSettings>();
            var key = Encoding.ASCII.GetBytes(appSettings.Secret);

            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
          .AddJwtBearer(x =>
          {
              x.RequireHttpsMetadata = false;
              x.SaveToken = true;
              x.TokenValidationParameters = new TokenValidationParameters
              {
                  ValidateIssuerSigningKey = true,
                  IssuerSigningKey = new SymmetricSecurityKey(key),
                  ValidateIssuer = true,
                  ValidateAudience = true,
                  ValidateLifetime = true,
                  ValidIssuer = appSettings.Issuer,
                  ValidAudience = appSettings.Audience,
                  ClockSkew = TimeSpan.Zero

              };
              x.Events = new JwtBearerEvents
              {
                  OnAuthenticationFailed = context =>
                  {
                      if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                      {
                          context.Response.Headers.Add("Token-Expired", "true");
                      }
                      return Task.CompletedTask;
                  }
              };
          });

登录端点

  [HttpPost]
        public ActionResult Login([FromBody] LoginViewModel user)
        {
            if (user == null)
            {
                return BadRequest("Invalid client request");
            }


            if (user.Email == "user@example.com")
            {
                var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(appSettings.Secret));
                var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);

                var tokeOptions = new JwtSecurityToken(
                    issuer: appSettings.Issuer,
                    audience: appSettings.Audience,
                    claims: new List<Claim>(),
                    notBefore: DateTime.UtcNow,
                    expires: DateTime.UtcNow.AddMinutes(30),
                    signingCredentials: signinCredentials
                );

                var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);

                return Ok(new GenericResponse<string> { Data = tokenString, Message = null, Success = true });
            }
            else
            {
                return Unauthorized(new GenericResponse<string> { Data = null, Message = "Unauthorized", Success = false });
            }

        }

【问题讨论】:

  • 有什么更新吗?我的回复对你有帮助吗?
  • @BrandoZhang 是的,有帮助,谢谢,发布了修改。
  • 如果我的回复对您有帮助,请标记为回答。以便其他面临相同问题的人,您可以更轻松地找到答案。

标签: c# asp.net-mvc asp.net-core asp.net-web-api jwt


【解决方案1】:

为了让白兰度的回答奏效,我最终这样做了。

            app.Use(async (context, next) =>
            {
                string token = context.Session.GetString(config.AccessTokenName);

                if (!string.IsNullOrEmpty(token))
                {
                    var jwttoken = new JwtSecurityTokenHandler().ReadJwtToken(token);            
                    var userIdentity = new ClaimsIdentity(jwttoken.Claims);
                    context.User = new ClaimsPrincipal(userIdentity);
                }

                await next();

            });

【讨论】:

    【解决方案2】:

    据我所知,如果您想创建自定义 ClaimsPrincipal,我建议您可以尝试在客户端 asp.net 核心应用程序中使用自定义中间件。

    您可以从 Request.Headers 或 Session 中获取令牌(根据您自己的逻辑)。

    然后你可以使用 JwtSecurityTokenHandler().ReadJwtToken 来读取令牌。

    更多细节,您可以参考以下代码:

    将app.use代码添加到startup.cs配置方法中。注意:你应该把它放在use.endpoint之前。

            app.UseRouting();
            app.UseGrpcWeb(); // Must be added between UseRouting and UseEndpoints
            app.UseCookiePolicy();
            app.UseSession();
    
            app.Use(async (context, next) =>
            {
                // you could get from token or get from session. 
                string token = context.Request.Headers["Authorization"];
                if (!string.IsNullOrEmpty(token))
                {
                    var tok = token.Replace("Bearer ", "");
                    var jwttoken = new JwtSecurityTokenHandler().ReadJwtToken(tok);
                    var claims = new List<Claim> { /* add claims */ };
                    var userIdentity = new ClaimsIdentity(claims, ClaimTypes.Name);
                    context.User = new ClaimsPrincipal(userIdentity);
                }
    
                await next();
    
            });
    

    那么就可以在客户端操作中直接获取token用户名了:

            var user = User.Identity.Name;
    

    结果:

    【讨论】:

    • 谢谢,我试试看。
    猜你喜欢
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多