使用Identity Server 3,即使在成功的承载令牌认证之后,ClaimsPrinciple也为null

时间:2017-09-15 16:32:57

标签: asp.net ssl asp.net-web-api owin identityserver3

我有一个测试控制台应用程序,我指向Identity Server 3的本地实例来请求访问令牌。以下代码执行此操作并返回我的令牌(传递单个范围"scope.test.client")。

    static TokenResponse GetClientToken(string clientId, string clientSecret, string[] scopes)
    {
        var uri = new Uri(string.Concat(ID_BASE_URI, ID_URL_TOKEN));

        var client = new TokenClient(
            uri.AbsoluteUri,
            clientId,
            clientSecret);

        return client.RequestClientCredentialsAsync(string.Join(" ", scopes)).Result;

然后我使用此令牌调用也在本地运行的API。这将获取上面获得的TokenResponse并将其传递给此方法:

    static void CallApi(string url, TokenResponse response)
    {
        try
        {
            using (var client = new HttpClient())
            {
                client.SetBearerToken(response.AccessToken);
                Console.WriteLine(client.GetStringAsync(url).Result);
            }
        }
        catch (Exception x)
        {
            Console.WriteLine(string.Format("Exception: {0}", x.Message));
        }
    }

API(ASP.NET WebApi项目)使用Owin Startup类对所有请求强制执行承载令牌身份验证:

        appBuilder.Map(baseApiUrl, inner =>
        {
            inner.UseWebApi(GlobalConfiguration.Configuration);

            // Enforce bearer token authentication for all API requests
            inner.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = "https://identityserver/core",
                ValidationMode = ValidationMode.ValidationEndpoint,

                RequiredScopes = new[] { "scope.test.client" }
            });
        });

它还确保所有API请求都由自定义授权属性处理:

GlobalConfiguration.Configuration.Filters.Add(new DefaultApiAuthorizeAttribute());

调试此API,我覆盖的OnAuthorize方法(DefaultApiAuthorizeAttribute)中的第一行是:

var caller = actionContext.RequestContext.Principal as System.Security.Claims.ClaimsPrincipal;

如果我突破这一行,我可以看到actionContext.RequestContext.Principal始终为空。但是,我可以看到((System.Web.Http.Owin.OwinHttpRequestContext)actionContext.RequestContext).Request.Headers包含一个Authorization标头,其中包含从我的控制台应用程序传递的持有者令牌。

因此,似乎API项目未对承载令牌进行身份验证。当然,Identity Server日志表明在发出初始访问令牌后它根本没有被命中。所以我很感激你的专家建议,为什么这可能不会发生,或至少有一些关于在哪里看的指针。

我怀疑它可能与SSL有关。虽然Identity Server配置为不需要SSL并使用idsrv3test.pfx开发证书进行签名,但两个站点都在本地托管在自签名SSL证书下。我有另一个测试MVC Web应用程序,它将身份验证委托给在本地工作正常的同一个IS3实例,所以我相信我的IS3实例配置正确。

2 个答案:

答案 0 :(得分:1)

您需要在致电UseIdentityServerBearerTokenAuthentication 之前致电UseWebApi 。设置OWIN中间件管道时,顺序很重要。

在您的情况下,Web API将在将请求发送到Identity Server之前处理您的请求(如果它们被发送完毕)。

答案 1 :(得分:1)

我想一系列可能的问题可能会产生我所描述的影响,但在我的情况下,我能够通过向我的消费API添加诊断日志来找到原因。这让我发现问题是集会冲突。 Owin中间件正在寻找版本为8.0.0.0的Newtonsoft.JSON程序集,但我的消费API(实际上是在CMS上运行)使用的是7.0.0.0。

对于任何想要快速找到答案的人,而不是花费数小时调整配置,这里是描述如何添加此日志记录的文档:https://identityserver.github.io/Documentation/docsv2/consuming/diagnostics.html