【问题标题】:Jwt tokens authorization is not workingJwt 令牌授权不起作用
【发布时间】:2017-07-09 05:49:50
【问题描述】:

我正在尝试创建 Jwt 令牌授权。为此,我有发行者部分的代码如下:

public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] {"*"});
    Users user;
    using (var db = new UserStore())
    {
        user = Task.Run(()=> db.FindUser(context.UserName, context.Password, context.ClientId)).Result;
    }
    if (user == null)
    {
        context.SetError("invalid_grant", "The user name or password is incorrect");
        return Task.FromResult<object>(null);
    }
    var identity = new ClaimsIdentity("JWT");
    identity.AddClaim(new Claim(ClaimTypes.Name, user.Email));
    identity.AddClaim(new Claim("sub", context.UserName));
    identity.AddClaim(new Claim(ClaimTypes.Role, user.Roles.Name));

    var props = new AuthenticationProperties(new Dictionary<string, string>
    {
        {
            "audience", context.ClientId ?? string.Empty
        }
    });
    var ticket = new AuthenticationTicket(identity, props);
    context.Validated(ticket);
    return Task.FromResult<object>(null);
}

以及应该接受不记名令牌的“资源”部分:

public void ConfigureOAuth(IAppBuilder app)
{
    var issuer = SiteGlobal.Issuer;
    var audience = SiteGlobal.Audience;
    var secret = TextEncodings.Base64Url.Decode(SiteGlobal.Secret);
    app.UseJwtBearerAuthentication(
    new JwtBearerAuthenticationOptions
    {
        AuthenticationMode = AuthenticationMode.Active,
        AllowedAudiences = new[] { audience },
        IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
        {
            new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
        }
    });
}

据我所知,颁发的令牌是有效的(我在 jwt.io 上进行了验证),所以问题出在其他地方。当我在 Postman 中发送令牌并调用受 [Authorize] 属性保护的控制器时,它总是返回 401 代码。您能告诉我如何解决这个问题吗?

附:这就是我实现自定义 Jwt 格式的方式:

public string Protect(AuthenticationTicket data)
{
    if (data == null)
    {
        throw new ArgumentNullException("data");
    }
    string audienceId = data.Properties.Dictionary.ContainsKey(AudiencePropertyKey) ? data.Properties.Dictionary[AudiencePropertyKey] : null;
    if (string.IsNullOrWhiteSpace(audienceId)) throw new InvalidOperationException("AuthenticationTicket.Properties does not include audience");
    Audience audience;
    using (var store = new AudienceStore())
    {
        audience = Task.Run(()=> store.FindAudience(audienceId)).Result;
    }
    var symmetricKeyAsBase64 = audience.Base64Secret;
    var signingKey = new InMemorySymmetricSecurityKey(Encoding.UTF8.GetBytes(symmetricKeyAsBase64));
    var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest);
    var issued = data.Properties.IssuedUtc;
    var expires = data.Properties.ExpiresUtc;
    var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingCredentials);
    var handler = new JwtSecurityTokenHandler();
    var jwt = handler.WriteToken(token);
    return jwt;
}

附:伙计们,我很抱歉,但我忘了解释代码的“发行者”部分是独立应用程序,同时“受众”是受保护的 web api。这是两个独立运行的不同应用程序。

【问题讨论】:

  • 对此我不确定。标头有问题吗,我会收到类似错误的请求但不是未经授权的。
  • 我没有得到 jwt 的 exp,只有通过 URL 进行的 REST 查询,其中需要请求标头 Authorization : Basic &lt;encrypted user:pass&gt; 并且如果有问题(通过/名称/语法),它向我扔了 401。
  • @Tatranskymedved 这就是您将用于基本身份验证的方法,而不是 JWT。 JWT 需要 Authorization: Bearer &lt;jwt&gt; 格式。
  • 我在设置 JWT 并不断收到 401 时遇到了类似的问题。尝试更改启动类中的顺序,以便在其他任何事情之前完成 ConfigureOAuth。这为我解决了这个问题(Asp.Net Core WebAPI)。

标签: c# oauth-2.0 authorization owin jwt


【解决方案1】:

在 Postman 中确保您使用以下格式发送授权标头:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

确保将“授权”选项卡设置为 Type: No Auth

如果您仍然遇到问题,请在您的 GrantResourceOwnerCredentials 中设置一个断点并查看它是否到达该点。如果您想在事件链的早期进行调试,还可以考虑覆盖 OAuthAuthorizationServerProviderValidateClientAuthentication 方法,该方法应该在 GrantResourceOwnerCredentials 之前调用。

【讨论】:

  • 从邮差临屋的代码:授权:承载eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6ImFuZHJleS5zaGVka29AZ21haWwuY29tIiwic3ViIjoiYW5kcmV5LnNoZWRrb0BnbWFpbC5jb20iLCJyb2xlIjoiQWRtaW4iLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUyNzk5IiwiYXVkIjoiMDk5MTUzYzI2MjUxNDliYzhlY2IzZTg1ZTAzZjAwMjIiLCJleHAiOjE0ODc3NzIxOTEsIm5iZiI6MTQ4Nzc3MDM5MX0.5GFpvU08CjaS5LTH0vRVFIGuilenkEgVu_aJLma4lPo 跨度>
  • 这是个问题 - 在“资源” api 中我没有安装 Asp.Net 身份,如本教程中所述 - bitoftech.net/2014/10/27/…。方法 GrantResourceOwnerCredentials 我只有在“发行人”部分。
  • @andrey.shedko 您没有发布您试图通过邮递员运行的内容,但 401 表明某些内容未通过您的授权。设置断点应该允许您检查并找到特定的故障点。如果您删除 Authorized 属性并通过邮递员运行请求,它是否有效?
【解决方案2】:

我刚刚尝试运行SON Web Token in ASP.NET Web API 2 using Owin 中提到的demo project,一切都按预期运行。

我注意到您对Protect 方法的实现有很大不同。我建议您将您的实现与文章中给出的示例进行比较。试着先让它工作。

另外请确保两台服务器上的颁发者、受众和密码相同。

如果您提供完整的源代码,我可以尝试进行更多调查。

【讨论】:

    猜你喜欢
    • 2021-04-21
    • 2020-05-14
    • 2018-06-05
    • 2020-10-20
    • 2020-02-27
    • 2020-11-22
    • 2021-08-17
    • 2017-08-22
    • 2018-07-26
    相关资源
    最近更新 更多