Как вернуть пользовательскую схему ошибок json из asp.net WebApi при использовании JwtBearerAuthentication - PullRequest
0 голосов
/ 04 января 2019

У меня есть проект 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 я переопределил методы Protect и 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 и т. д.), но просто не могу понять, как это сделать.

Есть ли способ сделать это, иесли да, то как?

Заранее спасибо за любую помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...