我正在使用IdentityServer MVC walkthrough in the documentation并且它很棒,直到我进入第2部分,我从MVC应用程序调用另一个api。这里,浏览器在调用/ callApi / ClientCredentials时挂起,直到最终超时,任务取消错误,并且VS调试器在app.UseIdentityServerBearerTokenAuthentication(...)
的api Startup类中抛出一个无效操作异常,内部异常:
IDX10803: Unable to create to obtain configuration from: 'http://localhost:44300/identity/.well-known/openid-configuration'.
正如我所说,直到现在,一切都在演练中运作良好。发现文档可以通过浏览器从该地址获得没问题(没有SSL错误 - 站点证书是可信的)。
这与here类似,但它有所不同,因为在此配置中,身份服务器和访问令牌验证中间件位于不同的进程中(在iis express中运行我的帐户)。我尝试设置DelayLoadMetadata
,现在浏览器返回任务取消异常,Visual Studio不会抛出异常。
我添加了日志记录并且没有看到任何问题 - 它显示MVC客户端获取其访问令牌然后就是它。
我还重新配置了所有应用程序和SSL端口,以使用" real"主持人姓名和证书所以我可以通过Fiddler观看所有内容。这对于整个演练(以及之前的演练)来说都很有用,但在这一点上仍然存在问题。我看到api应用程序查询发现文档,它永远不会得到响应。
我错过了什么?
答案 0 :(得分:1)
事实证明这是我的一个简单错误。在api的Startup类中,当我初始化IdentityServerBearerTokenAuthenticationOptions
Authority属性时,我错误地在URL前面加了http://而不是https://。因此,即使我有SSL证书和端口正常工作,api也会使用http来尝试访问身份服务器,并且我的计算机上没有任何东西明显绑定到http://localhost:44300。当我修复它
Authority = "https://localhost:44300/identity",
// added the "s"-^
然后它像冠军一样工作。我为了错过这个而踢我自己。故事的道德:验证端口,路径,证书和协议都是正确的。
答案 1 :(得分:0)
如果您使用的是Identity Server 3,则应为Identity客户端和用户访问Identity数据库服务器18表。因此,如果您可以在数据库中看到这些表,那么一切都很好。
现在在您的资源服务器中,必须是一个StartUp类,其配置用于设置令牌提供程序和验证:
public void Configuration(IAppBuilder app)
{
// Any connection or hub wire up and configuration should go here
var clientId = (string)ConfigurationManager.AppSettings["oauth2.clientid"];
var authority = (string)ConfigurationManager.AppSettings["oauth2.authority"];
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = authority,
ValidationMode = ValidationMode.ValidationEndpoint,
RequiredScopes = new[] { clientId },
});
app.UseResourceAuthorization(new AuthorizationManager());
var config = new HubConfiguration();
config.EnableJSONP = true;
app.MapSignalR(config);
}
private void ConfigureOAuth()
{
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
}
public class RequireHttpsAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
base.OnAuthorization(actionContext);
var request = actionContext.Request;
if (request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
actionContext.Response.Content = new StringContent("<p>https scheme required.</p>", Encoding.UTF8, "text/html");
if (string.Compare(request.Method.Method, "GET", true) == 0)
{
actionContext.Response = request.CreateResponse(HttpStatusCode.Found);
var builder = new UriBuilder(request.RequestUri);
builder.Scheme = Uri.UriSchemeHttps;
builder.Port = 443;
actionContext.Response.Headers.Location = builder.Uri;
}
else
{
actionContext.Response = request.CreateResponse(HttpStatusCode.NotFound);
}
}
}
}
我正在为此客户端使用ResourceOwner流程。我的最后一个推荐是下一个:Skype使用端口443,我知道这可能很奇怪,但如果仍然失败,请将您的IdentityServer端口更改为44305或与44300或443不同的东西.Skype可以使用相同的端口并制作你疯了。
希望它有所帮助。