在jwt承载处理程序

时间:2018-04-16 09:21:51

标签: asp.net-core oauth-2.0 jwt openiddict asp.net-core-security

我有使用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 rfciss声明是可选的。

我的问题是,如果我为此目的设置ValidateIssuer为假,如果我在执行此操作时打开安全漏洞并且是否有更推荐的替代方法?

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

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

另一种方法是将ValidateIssuer设置为false

由于JWT RFC表示iss(发行人)声明是可选的。

  

“iss”(发行人)索赔确定了发行该证券的委托人      智威汤逊。该权利要求的处理通常是特定于应用的。      “iss”值是包含StringOrURI的区分大小写的字符串      值。 使用此声明是可选的。

OAuth 2.0 RFC未提及发行人或代币的格式。

解析.well-known/openid-configuration的uri由MetadataAddress属性配置。如果未设置此属性,则似乎使用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/jwks文件中,该文件以MetadataAddress为前缀,如果您不愿意,应该保存以忽略此声明排除所有共享相同配置文件的某些发行者。但我想不出这样的情况。

答案 2 :(得分:0)

另一种解决方案是将所有已知别名包含在ValidIssuers的{​​{1}}属性中。但我不认为这是一个好主意,因为你可能会忘记一些别名。

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