c# - Jwt token 授权不起作用

标签 c# oauth-2.0 authorization owin jwt

我正在尝试创建 Jwt token 授权。为此,我让发行人部分使用这样的代码:

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);
}

和应该接受不记名 token 的“资源”部分:

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)
        }
    });
}

据我所知,颁发的 token 是有效的(我在 jwt.io 上进行了验证),所以问题出在其他地方。当我在 Postman 中发送 token 并调用受 [Authorize] 属性保护的 Controller 时,它总是返回 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;
}

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

最佳答案

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

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Postman Authorization Header

确保将“授权”选项卡设置为类型:无授权

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

关于c# - Jwt token 授权不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42336271/

相关文章:

c# - 捕获 PropertyInfo.setvalue 抛出的 setter 异常

android - 使用 AccountManager、Retrofit 和 Dagger 实现 OAuth2

c# - 我可以针对未授权或未验证抛出的 .NET 异常

azure - 如何在 Azure 中向 Microsoft Teams Bot 添加授权

c# - 在路由匹配发生之前拦截所有 WebApi 调用

c# - ASP.NET Web API破坏存储库/服务模式

c# - 检查是否安装了任何类型的 PDF 阅读器

google-apps-script - 每次调用gapi.auth.authorize的替代方法

node.js - Gmail API 是否支持 JWT?

php - 未经授权访问网页