我有一个测试控制台应用程序,我要指向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启动类来强制所有请求的携带者令牌身份验证:
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
总是为null。但是,我可以看到((System.Web.Http.Owin.OwinHttpRequestContext)actionContext.RequestContext).Request.Headers
包含一个授权标题,并带有从我的控制台应用程序传递的载体令牌。
因此,API项目似乎没有对承载令牌进行身份验证。当然,身份服务器日志表明它在发出初始访问令牌后根本没有被击中。因此,我感谢您关于为什么可能不会发生这种情况的专家建议,或者至少有一些有关在哪里看的建议。
我怀疑这可能与SSL有关。这两个站点均在自签名的SSL证书下本地托管,尽管身份服务器配置为不需要SSL并使用IDSRV3TEST.PFX开发证书进行签名。我确实有另一个测试MVC Web应用程序,该应用将身份验证委托给本地正常工作的同一IS3实例,因此我相信我的IS3实例已正确配置。
您需要在之前调用UseIdentityServerBearerTokenAuthentication
>您调用UseWebApi
。当您设置Owin中间件管道时,订单很重要。
在您的情况下,Web API将在发送到Identity服务器之前处理您的请求(如果它们完全发送)。
我想可能会产生我描述的一系列问题,但是就我而言,我能够通过将诊断日志添加到我的API中来找到原因。这使我发现问题是集会冲突。OWIN中间件正在寻找具有8.0.0.0版本的newtonsoft.json组件,但是我的消费API(实际上是在CMS Intance上运行)正在使用7.0.0.0.
对于任何想要快速找到答案而不是花费数小时的人来调整配置的人来说,这是描述如何添加此日志的文档:https://sidentityserver.github.github.io/documentation/docsv2/consuming/diargnostics。html