我有使用jwt承载认证的web api。创建jwt的实现(openiddict)使用当前url作为发布者。
services
.AddOpenIddict()
.UseJsonWebTokens();
我将jwt身份验证处理程序配置为使用有效的颁发者。
services
.AddAuthentication()
.AddJwtBearer(options =>
{
options.Authority = "http://test/";
...
});
当我到达http://test/
下的网站时,我获得了一个访问令牌,发行者设置为http://test/
。当Authority
与颁发者匹配时,请求将被验证。
当我到达http://125.124.35.21/
下的网站时,我获得了一个访问令牌,发行者设置为http://125.124.35.21/
。由于Authority
与发行者不匹配,因此请求将不会被验证。
我希望在这两种情况下都能够对请求进行身份验证。
现在我看到根据the jwt rfc,iss
声明是可选的。
我的问题是,如果我为此目的设置ValidateIssuer
为假,如果我在执行此操作时打开安全漏洞并且是否有更推荐的替代方法?
services
.AddAuthentication()
.AddJwtBearer(options =>
{
options.Authority = "http://test/";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
...
}
});
使用哪种配置来解析.well-known/openid-configuration
?Authority
?希望不是发行人,因为这意味着每个人都可以发出一个令牌并将其与我的api一起使用。
答案 0 :(得分:2)
我查看了生成访问令牌的代码,发现在没有设置配置值时它只需要当前的uri。
public static string GetIssuer(this HttpContext context, OpenIdConnectServerOptions options)
{
var issuer = options.Issuer;
if (issuer == null)
{
if (!Uri.TryCreate(context.Request.Scheme + "://" + context.Request.Host +
context.Request.PathBase, UriKind.Absolute, out issuer))
{
throw new InvalidOperationException("The issuer address cannot be inferred from the current request");
}
}
return issuer.AbsoluteUri;
}
因此,当我配置openiddict时,我可以设置Issuer
属性。
services.AddOpenIddict()
...
.Configure(options =>
{
options.Issuer = "http://test/";
...
});
当我添加身份验证服务时,我也可以设置Authority
属性。
services
.AddAuthentication()
.AddJwtBearer(options =>
{
options.Authority = "http://test/";
...
});
似乎没有配置有效的颁发者时,Authority
被用来验证发行者。但我没有找到支持这种说法的代码。
可能隐藏在Microsoft.IdentityModel.Protocols.OpenIdConnect.dll
答案 1 :(得分:0)
另一种方法是将ValidateIssuer
设置为false
。
由于JWT RFC表示iss
(发行人)声明是可选的。
“iss”(发行人)索赔确定了发行该证券的委托人 智威汤逊。该权利要求的处理通常是特定于应用的。 “iss”值是包含StringOrURI的区分大小写的字符串 值。 使用此声明是可选的。
OAuth 2.0 RFC未提及发行人或代币的格式。
解析.well-known/openid-configuration
的uri由MetadataAddress
属性配置。如果未设置此属性,则似乎使用Authority
属性来构建uri。
if (string.IsNullOrEmpty(options.MetadataAddress) && !string.IsNullOrEmpty(options.Authority))
{
options.MetadataAddress = options.Authority;
if (!options.MetadataAddress.EndsWith("/", StringComparison.Ordinal))
{
options.MetadataAddress += "/";
}
options.MetadataAddress += ".well-known/openid-configuration";
}
由于验证令牌的公钥存储在.well-known/jwks
文件中,该文件以MetadataAddress
为前缀,如果您不愿意,应该保存以忽略此声明排除所有共享相同配置文件的某些发行者。但我想不出这样的情况。
答案 2 :(得分:0)
另一种解决方案是将所有已知别名包含在ValidIssuers
的{{1}}属性中。但我不认为这是一个好主意,因为你可能会忘记一些别名。
例如,在不同的子网中,您可以使用不同的ips或不同的dns别名来访问服务。