如何验证来自不同发行人的 jwt 令牌
How to validate jwt token from different issuer
我正在使用可操作消息(通过 Outlook 网络应用程序)来调用逻辑应用程序。因此,我在请求中获得了一个 Bearer 令牌:
"Action-Authorization": "Bearer eyJ0eXAi..."
调用堆栈:
Outlook web app -> Logic App -> my endpoint hosted in azure
现在我尝试使用 jwt.io 验证令牌,但遇到签名无效的问题。
所以我尝试用 JwtSecurityTokenHandler
.
在 c# 中验证它
我试图将 https://substrate.office.com/sts/
添加到发行者列表,但似乎验证甚至没有到达那里。
我正在使用以下代码来验证 office.com 颁发的 jwt 令牌:
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 令牌:
我遇到异常:
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/
作为有效发行人?
异常表示 "Signature validation failed"。
要解决这个问题,我们不能只将想要的有效发行者添加到 ValidIssuers
,我们需要验证令牌是由发行者本身发行的。
特别是对于 office.com 作为发行者的这种情况,我在这里找到了预期的密钥(JWK - JSON Web 密钥):
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"];
}
在 appsettings 中,我将来自网站的 RSA 密钥用于验证令牌,它看起来像:
{"kty":"RSA","use":"sig","kid":"gY...","x5t":"gY...","n":"2w...","e":"AQAB","x5c":["MII..."]}
我正在使用可操作消息(通过 Outlook 网络应用程序)来调用逻辑应用程序。因此,我在请求中获得了一个 Bearer 令牌:
"Action-Authorization": "Bearer eyJ0eXAi..."
调用堆栈:
Outlook web app -> Logic App -> my endpoint hosted in azure
现在我尝试使用 jwt.io 验证令牌,但遇到签名无效的问题。
所以我尝试用 JwtSecurityTokenHandler
.
我试图将 https://substrate.office.com/sts/
添加到发行者列表,但似乎验证甚至没有到达那里。
我正在使用以下代码来验证 office.com 颁发的 jwt 令牌:
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 令牌:
我遇到异常:
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/
作为有效发行人?
异常表示 "Signature validation failed"。
要解决这个问题,我们不能只将想要的有效发行者添加到 ValidIssuers
,我们需要验证令牌是由发行者本身发行的。
特别是对于 office.com 作为发行者的这种情况,我在这里找到了预期的密钥(JWK - JSON Web 密钥): 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"];
}
在 appsettings 中,我将来自网站的 RSA 密钥用于验证令牌,它看起来像:
{"kty":"RSA","use":"sig","kid":"gY...","x5t":"gY...","n":"2w...","e":"AQAB","x5c":["MII..."]}