Identity Server 4中的WWW-Authenticate标头未经授权的响应

时间:2018-01-30 11:13:59

标签: authentication oauth-2.0 identityserver4 identityserver3

我正在使用Identity Server 4保护Web API。

如果外部应用尝试使用客户端凭据访问它但未传入访问令牌,我会按预期获得未经授权的响应。

这里的问题是响应不像我期望的那样包含WWW-Authenticate标头,如OAuth spec中所述。

我在Identity Server中缺少一些配置吗?或者Identity Server实现有问题吗?

相关的代码部分如下:

Identity Server上的客户端注册:

new Client()
{
    ClientId = "datalookup.clientcredentials",
    ClientName = "Data Lookup Client with Client Credentials",
    AlwaysIncludeUserClaimsInIdToken = true,
    AlwaysSendClientClaims = true,
    AllowOfflineAccess = false,
    ClientSecrets =
    {
        new Secret("XXX".Sha256())
    },
    AllowedGrantTypes = GrantTypes.ClientCredentials,
    AllowedScopes =
    {
        Scopes.DataLookup.Monitoring,
        Scopes.DataLookup.VatNumber
    },
    ClientClaimsPrefix = "client-",
    Claims =
    {
        new Claim("subs", "1000")
    }
}

在Identity Server上注册ApiResource:

new ApiResource()
{
    Name = "datalookup",
    DisplayName = "Data Lookup Web API",
    ApiSecrets =
    {
        new Secret("XXX".Sha256())
    },
    UserClaims =
    {
        JwtClaimTypes.Name,
        JwtClaimTypes.Email,
        JwtClaimTypes.Profile,
        "user-subs"
    },
    Scopes =
    {
        new Scope()
        {
            Name = Scopes.DataLookup.Monitoring,
            DisplayName = "Access to the monitoring endpoints",
        },
        new Scope()
        {
            Name = Scopes.DataLookup.VatNumber,
            DisplayName = "Access to the VAT Number lookup endpoints",
            Required = true
        }
    }
}

Web API中的身份验证配置:

public void ConfigureServices(IServiceCollection services)
{
    (...)
    services.AddMvc();
    services
        .AddAuthorization(
            (options) =>
            {
                options.AddPolicy(
                    Policies.Monitoring,
                    (policy) =>
                    {
                        policy.RequireScope(Policies.Scopes.Monitoring);
                    });
                options.AddPolicy(
                    Policies.VatNumber,
                    (policy) =>
                    {
                        policy.RequireScope(Policies.Scopes.VatNumber);
                        policy.RequireClientSubscription();
                    });
            });
    services.AddAuthorizationHandlers();
    services
        .AddAuthentication("Bearer")
        .AddIdentityServerAuthentication(
            (options) =>
            {
                options.Authority = "http://localhost:5000";
                options.RequireHttpsMetadata = false;
                options.ApiName = "datalookup";
            });
    (...)
}

访问Web API的客户端:

using (HttpClient client = new HttpClient())
{
    // client.SetBearerToken(accessToken);
    using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Constants.WebApiEndpoint))
    {
        using (HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false))
        {
            if (!response.IsSuccessStatusCode)
            {
                ConsoleHelper.WriteErrorLine(response);
                return;
            }
            string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            ConsoleHelper.WriteInformationLine(content);
        }
    }
}

请注意,client.SetBearerToken(accessToken)已被注释,因此我希望响应包含WWW-Authenticate标头。

这背后的全部想法是在客户端库上实现一个功能来处理Http Bearer挑战(例如,Azure KeyVault客户端库就可以了)。

0 个答案:

没有答案