使用 mvc dotnet core 访问 JWT 的有效负载

发布于 2025-01-19 05:44:57 字数 2029 浏览 0 评论 0原文

我在访问 dotnet 核心控制器中的 JWT(有效负载)时遇到问题。我不知道我错在哪里。我想我在下面的描述中涵盖了所有要点。如果我错过了一些可能有帮助的内容,请告诉我。 感谢您抽出时间。

将身份验证服务添加到 servicecollection

  services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = false,
                    ValidateIssuerSigningKey = false,
                    ValidIssuer = null,
                    ValidAudience = null,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("testify"))
                };
            });

我用于请求的令牌:

Used Token

邮递员调用: 邮递员呼叫

控制器动作的代码:

        [HttpPost]
        [ProducesResponseType(typeof(void), 201)]
        [ProducesResponseType(typeof(void), 400)]
        [ProducesResponseType(typeof(void), 401)]
        [ProducesResponseType(typeof(void), 403)]
        [ApiExplorerSettings(GroupName = "AuditLog")]
        [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
        public IActionResult Insert([Required] Dto.Log auditLog) => RunSafely(() =>
            {
                var log = _mapper.Map<Dto.Log, Log>(auditLog);
                log.CorrelationId = _headerReader.GetCorrelationId(Request?.Headers);

                _logRepository.AddLog(log);
                return this.StatusCode((int)HttpStatusCode.Created);
            });

控制器的状态: 结果是这样= 控制器

I have a problem with accessing the (payload of) JWT in a dotnet core controller. I don't know where I am wrong. I think I covered all the important points in the following description. If I have missed something, that could help, please let me know.
Thank you for your time.

Adding authentication service to the servicecollection

  services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = false,
                    ValidateIssuerSigningKey = false,
                    ValidIssuer = null,
                    ValidAudience = null,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("testify"))
                };
            });

The token I used for the request:

Used Token

The postman call:
Postman Call

The code of the controller action:

        [HttpPost]
        [ProducesResponseType(typeof(void), 201)]
        [ProducesResponseType(typeof(void), 400)]
        [ProducesResponseType(typeof(void), 401)]
        [ProducesResponseType(typeof(void), 403)]
        [ApiExplorerSettings(GroupName = "AuditLog")]
        [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
        public IActionResult Insert([Required] Dto.Log auditLog) => RunSafely(() =>
            {
                var log = _mapper.Map<Dto.Log, Log>(auditLog);
                log.CorrelationId = _headerReader.GetCorrelationId(Request?.Headers);

                _logRepository.AddLog(log);
                return this.StatusCode((int)HttpStatusCode.Created);
            });

The state of the controller:
Result this = Controller

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

假面具 2025-01-26 05:44:57

您可以通过使用 System.Security.Claims.ClaimsPrincipal 命名空间内的 User 对象来访问 jwt 的有效负载。例如:

var claims = User.Claims;

claims对象包含jwt的有效负载。此外,您还可以访问其他信息,例如:

if (User.Identity.IsAuthenticated)
{ ....

You can access payload of jwt by using User object inside of System.Security.Claims.ClaimsPrincipal namespace. For example:

var claims = User.Claims;

The claims object contains payload of jwt. Also, you can access other information like:

if (User.Identity.IsAuthenticated)
{ ....
神魇的王 2025-01-26 05:44:57

你的问题对我来说也有点不清楚,我不确定你的代币的创建过程。然而,我的一个项目中有确切的场景,效果很好。以下是不同谜题的代码:

创建令牌:

if (user != null)
{
    var result = await _signInManager.CheckPasswordSignInAsync(user, model.Password, false);

    if (result.Succeeded)
    {
    // Create the Token
    var claims = new[]
    {
                      new Claim(JwtRegisteredClaimNames.Sub, user.Email),
                      new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                      new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName)
                    };

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));

    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
      _config["Tokens:Issuer"],
      _config["Tokens:Audience"],
      claims,
      expires: DateTime.UtcNow.AddMinutes(120),
      signingCredentials: creds);

    var results = new
    {
        token = new JwtSecurityTokenHandler().WriteToken(token),
        expiration = token.ValidTo
    };

    return Created("", results);
    }
}

对于 IServiceCollection :

      services.AddAuthentication()
    .AddCookie()
    .AddJwtBearer(cfg =>
    {
      cfg.TokenValidationParameters = new TokenValidationParameters()
      {
        ValidIssuer = _config["Tokens:Issuer"],
        ValidAudience = _config["Tokens:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]))
      };
    });

和 config.json 文件:(请注意,由于安全原因,我更改了实际信息)

  "Tokens": {
"Key": "foo-foo-foo-foo-foo-foo-foo-foo",
"Issuer": "localhost",
"Audience": "localhost"
  }

这些设置与我在一个小项目中使用的设置完全相同,并且工作正常。检查您的项目中是否缺少某些内容。

Your question is a little unclear to me, too, and I am not sure about the creation process of your token. However, I have the exact scenario in one of my projects, which works fine. Here is the code for different puzzles:

Creating the Token:

if (user != null)
{
    var result = await _signInManager.CheckPasswordSignInAsync(user, model.Password, false);

    if (result.Succeeded)
    {
    // Create the Token
    var claims = new[]
    {
                      new Claim(JwtRegisteredClaimNames.Sub, user.Email),
                      new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                      new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName)
                    };

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));

    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
      _config["Tokens:Issuer"],
      _config["Tokens:Audience"],
      claims,
      expires: DateTime.UtcNow.AddMinutes(120),
      signingCredentials: creds);

    var results = new
    {
        token = new JwtSecurityTokenHandler().WriteToken(token),
        expiration = token.ValidTo
    };

    return Created("", results);
    }
}

For IServiceCollection :

      services.AddAuthentication()
    .AddCookie()
    .AddJwtBearer(cfg =>
    {
      cfg.TokenValidationParameters = new TokenValidationParameters()
      {
        ValidIssuer = _config["Tokens:Issuer"],
        ValidAudience = _config["Tokens:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]))
      };
    });

And config.json file: (Note that I changed real-world info due to security reasons)

  "Tokens": {
"Key": "foo-foo-foo-foo-foo-foo-foo-foo",
"Issuer": "localhost",
"Audience": "localhost"
  }

These settings are exact that I'm using in one of my small projects, and It's working fine. Check if something is missing in your project or not.

生生不灭 2025-01-26 05:44:57

在控制器中,您可以依赖ihttpContextAccessor,然后在httpcontext上,调用扩展方法gettokenAsynaC(getTokenAsync(string),它将将返回编码的字符串。

string encodedToken = _httpContextAccessor.HttpContext.GetTokenAsync("access_token");
JwtSecurityToken decodedToken = new JwtSecurityToken(encodedToken);
string email = decodedToken.Payload["email"].ToString();

jwtsecuritytokensystem.indesitymodel.tokens.jwt namespace和getTokenAsync httpcontext httpcontextMicrosoft.aspnetcore.authentication名称空间。

Within a controller, you can take a dependency on IHttpContextAccessor and then, on the HttpContext, call the extension method GetTokenAsync(string), which will return the encoded string.

string encodedToken = _httpContextAccessor.HttpContext.GetTokenAsync("access_token");
JwtSecurityToken decodedToken = new JwtSecurityToken(encodedToken);
string email = decodedToken.Payload["email"].ToString();

JwtSecurityToken is in the System.IdentityModel.Tokens.Jwt namespace, and GetTokenAsync extension method of HttpContext is in the Microsoft.AspNetCore.Authentication namespace.

愁以何悠 2025-01-26 05:44:57

原始有效载荷您可以访问RAW

访问令牌以使用.NET API控制器中的以下代码获取其JWTPAYLOAD

using System.IdentityModel.Tokens.Jwt;

[Route("api/contacts")]
public class ContactsController : Controller
{
    [HttpGet("")]
    public async Task<IEnumerable<Contact>> GetContactsAsync()
    {
        var authHeader = this.HttpContext.Request.Headers.Authorization.ToString();
        var parts = authHeader.Split(' ');
        var accessToken = parts[1];

        var handler = new JwtSecurityTokenHandler();
        var token = handler.ReadJwtToken(accessToken);
        var payload = token.Payload;
        System.Console.WriteLine($"Access token expiry time is {payload.Exp}");

        // Business code goes here
    }
}

JWT 提供更高级别的编程模型,默认情况下您永远无法访问JWT详细信息。这是一个值得关注的好模型 - 业务逻辑只能使用索赔

var expiry = this.User.Claims.First(c => c.Type == "exp");
System.Console.WriteLine($"Access token expiry time is {expiry.Value}");

自定义JWT处理

如果要实现与JWT相关的自定义行为,则是标准使用框架的可扩展性。然后,管道进入中间件类,因此控制器类保持着专注于业务。我的几个示例类别显示了如何扩展.NET框架:

  • ​CS“ rel =” nofollow noreferrer“> customJwtSecurityTokenHandler

有关更多信息,请参阅我的这些资源,这些资源专注于促进对API中重要标准的OAuth概念的理解:

  • ​-core-oauth-coding/“ rel =“ nofollow noreferrer”>博客文章

RAW PAYLOAD

You can access the raw JWT access token to get its JWTPayload using the following type of code in a .NET API controller:

using System.IdentityModel.Tokens.Jwt;

[Route("api/contacts")]
public class ContactsController : Controller
{
    [HttpGet("")]
    public async Task<IEnumerable<Contact>> GetContactsAsync()
    {
        var authHeader = this.HttpContext.Request.Headers.Authorization.ToString();
        var parts = authHeader.Split(' ');
        var accessToken = parts[1];

        var handler = new JwtSecurityTokenHandler();
        var token = handler.ReadJwtToken(accessToken);
        var payload = token.Payload;
        System.Console.WriteLine(
quot;Access token expiry time is {payload.Exp}");

        // Business code goes here
    }
}

CLAIMS

Microsoft provide a higher level programming model, where by default you never get access to the JWT details. This is a good model to follow - business logic should only ever use a ClaimsPrincipal:

var expiry = this.User.Claims.First(c => c.Type == "exp");
System.Console.WriteLine(
quot;Access token expiry time is {expiry.Value}");

CUSTOM JWT PROCESSING

If you want to implement custom behaviour related to JWTs then it is standard to use the extensibility features of the framework. The plumbing then goes into a middleware class, so that controller classes stay business focused. A couple of example classes of mine show how to extend the .NET framework:

For more info, see these resources of mine, which are focused on promoting understanding of the important standards based OAuth concepts in APIs:

拥有 2025-01-26 05:44:57

访问有效负载的最简单方法是使用注入到类中的 IHttpContextAccessor ,如下所示。

 public class MyClass: IEwocUser
    {
        private readonly IHeaderDictionary _headers;

        public MyClass(IHttpContextAccessor httpContextAccessor)
        {
            _headers = httpContextAccessor.HttpContext?.Request.Headers;
        }
}

您可以从标头中过滤身份验证令牌。

Easiest way to access payload is by using IHttpContextAccessor injected into your class like below.

 public class MyClass: IEwocUser
    {
        private readonly IHeaderDictionary _headers;

        public MyClass(IHttpContextAccessor httpContextAccessor)
        {
            _headers = httpContextAccessor.HttpContext?.Request.Headers;
        }
}

From the headers you can filter for Auth token.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文