我有一个测试控制台应用程序,我指向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实例配置正确。
答案 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