调用 callapi/clientcredentials 时浏览器在 IdentityServer MVC 演练中挂起

Browser hangs in IdentityServer MVC walkthrough when calling callapi/clientcredentials

我正在通过 IdentityServer MVC walkthrough in the documentation 工作,这很棒,直到我进入第 2 部分,我从 MVC 应用程序调用另一个 api。在这里,浏览器在调用 /callApi/ClientCredentials 时挂起,直到最终因任务取消错误而超时,并且 VS 调试器在 api 启动 class 中抛出无效操作异常 app.UseIdentityServerBearerTokenAuthentication(...)内部例外: IDX10803: Unable to create to obtain configuration from: 'http://localhost:44300/identity/.well-known/openid-configuration'.

正如我所说,到目前为止,演练中的一切都运行良好。可以通过浏览器从该地址毫无问题地获取发现文档(没有 SSL 错误 - 站点证书是可信的)。

这看起来与 here 相似,但又有所不同,因为在此配置中,身份服务器和访问令牌验证中间件处于不同的进程中(都在 iis express 运行 我的帐户中)。我尝试设置 DelayLoadMetadata 无论如何,现在浏览器 returns 任务取消了异常并且 Visual Studio 没有抛出异常。

我添加了日志记录,但没有发现任何问题 - 它显示 MVC 客户端获取其访问令牌,仅此而已。

我还重新配置了所有应用程序和 SSL 端口以使用 "real" 主机名和证书,这样我就可以通过 Fiddler 观看所有内容。这对整个演练(以及上一个演练)都非常有效,但此时仍然卡住了。我看到 api 应用程序正在查询发现文档,但它从未得到响应。

我错过了什么?

如果您使用的是身份服务器 3,您应该在身份数据库服务器中获取 18 个表,用于客户端和用户。因此,如果您可以在数据库中看到这些表,那么一切都很好。

现在在您的资源服务器中,必须是一个 StartUp class,其配置用于设置令牌提供程序和验证:

   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 可以使用相同的端口并使你疯了。

希望对您有所帮助。

事实证明这只是我的一个简单错误。在 api 的启动 class 中,当我初始化 IdentityServerBearerTokenAuthenticationOptions 权限 属性 时,我错误地在 URL 前面加上了 http:// 而不是 https:/ /.因此,即使我的 SSL 证书和端口正常工作,api 还是使用 http 尝试访问身份服务器,而且我的计算机上显然没有绑定到 http://localhost:44300。当我将其固定为

Authority = "https://localhost:44300/identity",
// added the "s"-^

然后它就像冠军一样工作。我因为错过了这个而踢自己。故事的寓意:验证端口、路径、证书和协议都正确。