Как проверить токен jwt от другого эмитента - PullRequest
3 голосов
/ 07 мая 2019

Я использую действенные сообщения (с веб-приложением Outlook) для вызова приложения логики. Поэтому я получаю токен на предъявителя в запросе:

«Действие-Авторизация»: «Несущий эйJ0eXAi ...»

CallStack: Outlook web app -> Logic App -> my endpoint hosted in azure

Теперь я попытался проверить токен с помощью jwt.io, но получил сообщение о том, что подпись недействительна. Поэтому я попытался проверить это в c # с JwtSecurityTokenHandler.

Я пытался добавить https://substrate.office.com/sts/ в список издателей, но похоже, что проверка даже не дошла.

Я использую следующий код для проверки токена jwt, выданного office.com:

bool IsAuthorized(HttpActionContext actionContext)
        {
            var valid = base.IsAuthorized(actionContext);

            // Custom handle for Bearer token, when invalid from base-class
            if (!valid && actionContext.Request.Headers.Authorization.Scheme == "Bearer")
            {
                var jwt = actionContext.Request.Headers.Authorization.Parameter;
                var th = new JwtSecurityTokenHandler();
                var sjwt = th.ReadToken(jwt) as JwtSecurityToken;                

                var validationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = false,
                    //IssuerSigningToken = sjwt,
                    ValidateActor = false,
                    ValidateAudience = false,
                    ValidateIssuer = true,
                    ValidateLifetime = true,
                    ValidIssuers = new[] { "https://substrate.office.com/sts/" },
                    ValidAudiences = new[] {"https://XXX.logic.azure.com"}
        };

                SecurityToken validatedToken;
                try
                {
                    th.ValidateToken(jwt, validationParameters, out validatedToken);
                }
                catch (Exception ex)
                {
                    return false;
                }
            }

            return valid;
        }

Вот мой токен JWT:

JWT Token

Я получаю исключение:

IDX10500: Signature validation failed. Unable to resolve SecurityKeyIdentifier: 'SecurityKeyIdentifier
    (
    IsReadOnly = False,
    Count = 2,
    Clause[0] = X509ThumbprintKeyIdentifierClause(Hash = 0x818...),
    Clause[1] = System.IdentityModel.Tokens.NamedKeySecurityKeyIdentifierClause
    )
', ...

Даже если я установил ValidateIssuerSigningKey = false.

Есть ли способ принять https://substrate.office.com/sts/ в качестве действующего эмитента?

1 Ответ

0 голосов
/ 07 мая 2019

Исключение говорит о том, что «Проверка подписи не удалась».Чтобы решить эту проблему, мы не можем просто добавить требуемого действующего эмитента к ValidIssuers, нам нужно убедиться, что токен выпущен от самого эмитента.

Специально для этого случая, когда office.com являетсяэмитент Я нашел ожидаемый ключ (JWK - JSON Web Key) здесь: https://substrate.office.com/sts/common/discovery/keys (также https://substrate.office.com/sts/common/.well-known/openid-configuration)

Вот рабочий код:

bool IsAuthorized(HttpActionContext actionContext)
        {
            var valid = base.IsAuthorized(actionContext);

            // Custom handle for Bearer token, when invalid from base-class
            if (!valid && actionContext.Request.Headers.Authorization.Scheme == "Bearer")
            {
                var jwt = actionContext.Request.Headers.Authorization.Parameter;
                var th = new JwtSecurityTokenHandler();

                var validationParameters = new TokenValidationParameters
                {
                    ValidateAudience = false,
                    ValidateLifetime = true,
                    ValidateIssuer = true,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new JsonWebKey(GetJWK()),
                    ValidIssuers = new[] { "https://substrate.office.com/sts/" }
                };

                Microsoft.IdentityModel.Tokens.SecurityToken validatedToken;
                try
                {
                    var claims = th.ValidateToken(jwt, validationParameters, out validatedToken);
                    valid = true;
                }
                catch (Exception ex)
                {
                    valid = false;
                }
            }

            return valid;
        }

        // Get the token from configuration
        private string GetJWK()
        {
            return ConfigurationManager.AppSettings["ida:jwks_json"];
        }

В настройках приложенияЯ положил ключ RSA с веб-сайта для проверки токена, он выглядит так:

{"kty":"RSA","use":"sig","kid":"gY...","x5t":"gY...","n":"2w...","e":"AQAB","x5c":["MII..."]}
...