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

时间:2016-08-08 07:04:15

标签: identityserver3

我正在使用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应用程序查询发现文档,它永远不会得到响应。

我错过了什么?

2 个答案:

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

希望它有所帮助。