Greg Fiske
Greg Fiske

Reputation: 51

Browser hangs in IdentityServer MVC walkthrough when calling callapi/clientcredentials

I'm working through the IdentityServer MVC walkthrough in the documentation and it's great until I get to Part 2 where I'm calling another api from the MVC app. Here, the browser hangs at the call to /callApi/ClientCredentials until eventually timing out with task cancelled error and the VS debugger throws an Invalid Operation Exception in the api Startup class at app.UseIdentityServerBearerTokenAuthentication(...) with the inner exception: IDX10803: Unable to create to obtain configuration from: 'http://localhost:44300/identity/.well-known/openid-configuration'.

As I said, everything was working great in the walkthrough until now. The discovery document can be obtained via the browser from that address no problem (no SSL error - the site cert is trusted).

This looks similar to here but yet it is different because in this configuration identityserver and the access token validation middleware are in separate processes (both in iis express running with my account). I tried setting DelayLoadMetadata anyway and now the browser returns the task cancelled exception and Visual Studio doesn't throw an exception.

I added logging and didn't see any issues - it shows the MVC client getting its access token and then that's it.

I also reconfigured all the apps and SSL ports to use a "real" host name and cert so I could watch everything via Fiddler. That worked great for the whole walkthrough (and the previous one, too) but still gets stuck at this point. I see the api app querying for the discovery document and it never gets a response.

What am I missing?

Upvotes: 1

Views: 552

Answers (2)

Greg Fiske
Greg Fiske

Reputation: 51

It turned out to be a simple mistake on my part. In the api's Startup class when I initialized the IdentityServerBearerTokenAuthenticationOptions Authority property, I incorrectly prefaced the URL with http:// instead of https://. So, even though I had the SSL cert and ports working, the api instead used http to try to reach the identity server and nothing apparently is bound on my computer to http://localhost:44300. When I fixed it to be

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

then it worked like a champ. I'm kicking myself for missing this. Moral of the story: verify the port, path, certificate AND the protocol are all correct.

Upvotes: 1

AbelMorgan
AbelMorgan

Reputation: 411

If you are using Identity Server 3, you should get in the Identity data Base server 18 tables, for clients and for Users. So if you can see those tables in your data base everything is fine.

Now in your Resource server, must be an StartUp class with the configuration to set the Token provider and validation:

   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);

                }
            }
        }
    }

I am using ResourceOwner flow for this client. And my last recomendation is the next one: Skype use the port 443, I know this can be strange, but if still failing, change your IdentityServer port to 44305 or something different from 44300 or 443. Skype can be using the same port and make you crazy.

Hope it helps.

Upvotes: 0

Related Questions