【问题标题】:JWT token not being validatedJWT 令牌未经过验证
【发布时间】:2017-08-18 08:21:23
【问题描述】:

我的 JWT 令牌验证不起作用。

以下前 3 个代码块是 JWT 生成服务器。最后是我的资源服务器。两者都是 ASP.NET 服务器应用程序。 JWT 生成器正在生成代码,当我使用 Postman 在 Header Authentication 中发送该代码以访问安全([Authorized])WebAPI 时,我收到了未经授权的消息。我想我在配置两个应用程序时都犯了一些错误

启动类是

   public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();
            // Web API routes
            config.MapHttpAttributeRoutes();
            ConfigureOAuth(app);
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            app.UseWebApi(config);
        }


        public void ConfigureOAuth(IAppBuilder app)
        {
            OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
            {
                //For Dev enviroment only (on production should be AllowInsecureHttp = false)
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/oauth2/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
                Provider = new CustomOAuthProvider(),
                AccessTokenFormat = new CustomJwtFormat()
            };

            // OAuth 2.0 Bearer Access Token Generation
            app.UseOAuthAuthorizationServer(OAuthServerOptions);

        }
    }

CustomOAuthProvider

using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;

namespace AuthorizationServer.Api.Providers
{
    public class CustomOAuthProvider : OAuthAuthorizationServerProvider
    {

        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated();
            return Task.FromResult<object>(null);
        }

        public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {

            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });


            if (context.UserName != context.Password)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect");
                //return;
                return Task.FromResult<object>(null);
            }

            var identity = new ClaimsIdentity("JWT");

            identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
            identity.AddClaim(new Claim("sub", context.UserName));
            identity.AddClaim(new Claim(ClaimTypes.Role, "Manager"));
            identity.AddClaim(new Claim(ClaimTypes.Role, "Supervisor"));

            var props = new AuthenticationProperties(new Dictionary<string, string>
                {
                    {
                         "audience", "099153c2625149bc8ecb3e85e03f0022"
                    }
                });

            var ticket = new AuthenticationTicket(identity, props);
            context.Validated(ticket);
            return Task.FromResult<object>(null);
        }
    }
}

自定义JWT格式

using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.DataHandler.Encoder;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Web;
using Thinktecture.IdentityModel.Tokens;

namespace AuthorizationServer.Api.Formats
{
    public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket>
    {
        private readonly string _issuer = "http://jwtauthzsrv.azurewebsites.net";

        public CustomJwtFormat()
        {
        }

        public string Protect(AuthenticationTicket data)
        {
            if (data == null)   {
                throw new ArgumentNullException("data");
            }

            string symmetricKeyAsBase64 = "IxrAjDoa2FqElO7IhrSrUJELhUckePEPVpaePlS_Xaw";
            var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
            var signingKey = new HmacSigningCredentials(keyByteArray);
            var issued = data.Properties.IssuedUtc;
            var expires = data.Properties.ExpiresUtc;
            var token = new JwtSecurityToken(_issuer, "099153c2625149bc8ecb3e85e03f0022", data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey);
            var handler = new JwtSecurityTokenHandler();
            var jwt = handler.WriteToken(token);
            return jwt;
        }

        public AuthenticationTicket Unprotect(string protectedText)
        {
            throw new NotImplementedException();
        }
    }
}

现在这是我的资源启动代码

namespace ResourceServer.Api
{
    public class Startup
    {

        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();
            ConfigureOAuth(app);
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            app.UseWebApi(config);
        }


        public void ConfigureOAuth(IAppBuilder app)
        {
            var issuer = "http://jwtauthzsrv.azurewebsites.net";
            var audience = "099153c2625149bc8ecb3e85e03f0022";
            var secret = TextEncodings.Base64Url.Decode("IxrAjDoa2FqElO7IhrSrUJELhUckePEPVpaePlS_Xaw");


            // Api controllers with an [Authorize] attribute will be validated with JWT
            app.UseJwtBearerAuthentication(
                new JwtBearerAuthenticationOptions
                {
                    AuthenticationMode = AuthenticationMode.Active,
                    AllowedAudiences = new[] { audience },
                    IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                    {
                        new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
                    },
                    Provider = new OAuthBearerAuthenticationProvider
                    {
                        OnValidateIdentity = context =>
                        {
                            context.Ticket.Identity.AddClaim(new System.Security.Claims.Claim("newCustomClaim", "newValue"));
                            return Task.FromResult<object>(null);
                        }
                    }
                });
        }
    }
}

【问题讨论】:

  • 您能否也显示您向 Postman 提出的请求?
  • 我选择后与URL localhost:18303/api/protected然后,在报头我把这个密钥值令牌从早期请求的授权承载eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmlxdWVfbmFtZSI6ImEiLCJzdWIiOiJhIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciJdLCJpc3MiOiJodHRwOi8vand0YXV0aHpzcnYuYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiIwOTkxNTNjMjYyNTE0OWJjOGVjYjNlODVlMDNmMDAyMiIsImV4cCI6MTQ5MDQ0MDc2MCwibmJmIjoxNDkwNDM4OTYwfQ.DnC4Pn0vf1D3mlMlbskM8MXd_8_4JepX0La4GSeJMu0 B> 跨度>生成
  • 如果你转到jwt.io,到调试器部分并尝试令牌,你会看到它标记它无效。所以,问题似乎出在生成令牌时。
  • 我去了jwt.io并在底部的VERIFY SIGNATURE文本框中输入了“IxrAjDoa2FqElO7IhrSrUJELhUckePEPVpaePlS_Xaw”,然后单击复选框“secret base64 encoded”消息转为已验证
  • 不知何故,jwt.io 上的前一个令牌没有提取“PAYLOAD:DATA”,但随后我生成了另一个令牌,然后有效负载开始显示在代码中发送的数据,该令牌是 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9。 eyJ1bmlxdWVfbmFtZSI6ImEiLCJzdWIiOiJhIiwicm9sZSI6WyJNYW5hZ2VyIiwiU3VwZXJ2aXNvciJdLCJpc3MiOiJodHRwOi8vd3d3Lm15d2Vic2l0ZS5jb20iLCJleHAiOjE0OTA0NDU4ODIsIm5iZiI6MTQ5MDQ0NDA4Mn0.WIv_B30y9o8bfLFnqotrGupoqHAGRNjnQzS47ZoBZxo 跨度>

标签: asp.net api web jwt


【解决方案1】:

JWT 无法在 jwt.io 中进行验证,因为他们需要一个公钥才能对其进行签名,而该页面没有。这是通过您的 Web api 应该具有的 AccessTokenValidation 扩展或中间件进行的过程。 我有一个类似的问题,我相信它与 timout 有关,因为我实现了 Katana 日志记录以查看更多细节(它是一个额外的中间件层,必须在 Startup.cs 类中构建)它开始为我工作,无需检查任何日志或实施任何进一步的解决方案。 我按照本教程删除了其中产生异常的示例。

https://www.tugberkugurlu.com/archive/logging-in-the-owin-world-with-microsoft-owin--introduction

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 2018-04-22
  • 2017-07-27
  • 2019-10-20
  • 2016-01-17
  • 2020-08-23
  • 1970-01-01
相关资源
最近更新 更多