2

我有使用 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与发行者不匹配,因此不会对请求进行身份验证。

我希望在这两种情况下都能够验证请求。

现在我看到根据jwt rfciss声明是可选的。

我的问题是我是否可以ValidateIssuer为此目的设置为 false,如果我这样做时会打开一个安全漏洞,是否有更推荐的替代方案?

services
    .AddAuthentication()
    .AddJwtBearer(options =>
    {
        options.Authority = "http://test/";
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = false,
            ...
        }
    });

使用哪个配置来解决.well-known/openid-configurationAuthority希望不是发行者,因为这意味着每个人都可以发行令牌并将其与我的 api 一起使用。

4

3 回答 3

2

我查看了生成访问令牌的代码,发现它仅在未设置配置值时才采用当前 uri。

https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/120a7ea9a14a33fad292cf4a11b4077118fab21f/src/AspNet.Security.OpenIdConnect.Server/OpenIdConnectServerHelpers.cs#L198

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

于 2018-04-17T07:42:18.580 回答
1

另一种选择是设置ValidateIssuerfalse.


正如JWT RFC所说,iss(颁发者)声明是可选的。

“iss”(颁发者)声明标识了颁发 JWT 的委托人。此声明的处理通常是特定于应用程序的。"iss" 值是包含 StringOrURI 值的区分大小写的字符串。 使用此声明是可选的。


OAuth 2.0 RFC根本没有提及颁发者或令牌的格式。


解析的 uri.well-known/openid-configurationMetadataAddress属性配置。如果未设置此属性,则该属性似乎Authority用于构建 uri。

https://github.com/aspnet/Security/blob/b3e4bf382c9676e2d912636b7ee0255cad244e11/src/Microsoft.AspNetCore.Authentication.JwtBearer/JwtBearerPostConfigureOptions.cs#L37

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/jwksMetadataAddress. 但我想不出这样的案例。

于 2018-04-17T21:13:37.470 回答
0

另一种解决方案是将所有已知别名包含ValidIssuersTokenValidationParameters. 但我认为这不是一个好主意,因为您可能会忘记一些别名。

例如,在不同的子网中,您可能可以使用不同的 ips 或不同的 dns 别名访问服务。

于 2018-04-17T21:23:34.003 回答