使用JwtBearerAuthentication时如何从asp.net WebApi返回自定义json错误模式

时间:2019-01-04 02:31:25

标签: asp.net-web-api oauth-2.0

我有一个asp.net WebAPI项目来提供REST服务,在这里我使用以下程序包来创建和使用JWT令牌来进行承载者身份验证/授权。

     <package id="Microsoft.Owin.Security" version="4.0.0" targetFramework="net47" />
     <package id="Microsoft.Owin.Security.Jwt" version="3.1.0" targetFramework="net47" />
     <package id="Microsoft.Owin.Security.OAuth" version="4.0.0" targetFramework="net47" />

我将其配置如下。

    OAuthAuthorizationServerOptions oauthServerOptions = new OAuthAuthorizationServerOptions()
      {
        AllowInsecureHttp = true,
        TokenEndpointPath = new PathString(TokenEndPoint),
        AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(config.SecuritySettings.AccessTokenExpiryMins ?? 1),
        Provider = new AuthorisationServerProvider(servicesFacade, securityDataRepository, resourceProvider, m_logger),
        AccessTokenFormat = new CustomJwtFormat(config, resourceProvider, m_logger),
        RefreshTokenProvider = new RefreshTokenProvider(securityDataRepository, config.SecuritySettings, m_logger),

      };

      app.UseOAuthAuthorizationServer(oauthServerOptions);

      OAuthBearerAuthenticationOptions bearerOptions = new OAuthBearerAuthenticationOptions
      {
        AccessTokenFormat = oauthServerOptions.AccessTokenFormat,
        AccessTokenProvider = oauthServerOptions.AccessTokenProvider,
        AuthenticationMode = oauthServerOptions.AuthenticationMode,
        AuthenticationType = oauthServerOptions.AuthenticationType,
        Description = oauthServerOptions.Description,
        SystemClock = oauthServerOptions.SystemClock
      };

      app.UseOAuthBearerAuthentication(bearerOptions);

     var issuer = config.SecuritySettings.AudienceId;
      byte[] audienceSecret = System.Text.Encoding.Unicode.GetBytes(config.SecuritySettings.AudienceSecret);

      // API controllers with an [Authorize] attribute will be validated with JWT

      app.UseJwtBearerAuthentication(
        new JwtBearerAuthenticationOptions
        {
          AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
          AllowedAudiences = new[] {config.SecuritySettings.AudienceId},
          IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
          {
            new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
          },

        });

CustomJwtFormat中,我重写了ProtectUnprotect方法。

Unprotect方法的实现如下。

        public AuthenticationTicket Unprotect(string protectedText)
        {
          var handler = new JwtSecurityTokenHandler();
          ClaimsPrincipal principal;

          try
          {
            SecurityToken validToken;
            principal = handler.ValidateToken(protectedText, m_tokenValidationParameters, out validToken);
            var validJwt = validToken as JwtSecurityToken;
            if (validJwt == null)        
              throw new ArgumentException(m_resourceProvider.GetInvalidJwtError().ToString());

            if (!validJwt.Header.Alg.Equals(SigningAlgorithm, StringComparison.Ordinal))
              throw new ArgumentException(m_resourceProvider.GetInvalidJwtAlgorithmError().ToString());

            // Additional custom validation of JWT claims here (if any)
          }
          catch (SecurityTokenValidationException ex)
          {
            m_logger.WriteInformation(ex.ToString());
            return null;
          }
          catch (ArgumentException aex)
          {
            m_logger.WriteError(aex.ToString());
            return null;
          }

          // Validation passed. Return a valid AuthenticationTicket:
          return new AuthenticationTicket(principal.Identities.FirstOrDefault(), new AuthenticationProperties());
        }  
      }

我想做的是,当Unprotect失败(例如令牌不再有效)时,我想为返回的错误提供自己的json模式,以匹配我的应用程序的其余部分,而不是其他内容图书馆用品。

我已经尝试了所有我能想到的东西(ExceptionFilters,Handlers等),但是看不到如何做到这一点。

有办法做到这一点吗?

在此先感谢您的帮助。

0 个答案:

没有答案