0

I wanted to write acceptance tests for my WebApi and IdentityServer. To keep things as simple as possible I copied the whole sample project from here but added another project, that essentially makes the same as the console client would but as a acceptance test.

The only scenario I got right now is this:

namespace SpecTesting
{
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using FluentAssertions;
using IdentityModel.Client;
using Xbehave;

public class JustLikeConsole
{
    private static readonly string ServerUrl = "http://localhost:11111";
    private static readonly string IdentityServerUrl = "http://localhost:5000";

    private IDisposable webApp;
    private IDisposable identityServer;
    private HttpClient appClient;
    private HttpClient identityServerClient;

    [Background]
    public void Background()
    {
        "establish server"._(() =>
        {
            this.identityServer = Microsoft.Owin.Hosting.WebApp.Start<IdSrv.Startup>(IdentityServerUrl);
            this.webApp = Microsoft.Owin.Hosting.WebApp.Start<Apis.Startup>(ServerUrl);
            this.appClient = new HttpClient { BaseAddress = new Uri(ServerUrl) };
            this.identityServerClient = new HttpClient { BaseAddress = new Uri(IdentityServerUrl) };
        }).Teardown(() =>
        {
            this.identityServerClient.Dispose();
            this.appClient.Dispose();
            this.webApp.Dispose();
            this.identityServer.Dispose();
        });
    }

    [Scenario]
    public void SimplestScenario(HttpResponseMessage response)
    {
        var clientId = "silicon";
        var clientSecret = "F621F470-9731-4A25-80EF-67A6F7C5F4B8";
        var expectedJson = $"{{ client: '{clientId}' }}";

        "get token"._(() =>
        {
            var client = new TokenClient(
                $"{IdentityServerUrl}/connect/token",
                clientId,
                clientSecret);

            var token = client.RequestClientCredentialsAsync("api1").Result;
            this.appClient.SetBearerToken(token.AccessToken);
        });

        "when calling the service"._(()
            => response = this.appClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, "/test"), CancellationToken.None).Result);

        "it should return status code 'OK'"._(()
            => response.StatusCode.Should().Be(HttpStatusCode.OK));

        "it should equal expected json"._(()
            => response.Content.ReadAsStringAsync().Result.Should().Be(expectedJson));
    }
}
}

I now always get the status code 'unauthorized' instead of 'ok'. When I call the two servers via the console client, it works as expected. Very frustrating.

Update I replaced the "when calling a service" step with the following lines just to enhance the simplicity:

var client = new HttpClient();
client.SetBearerToken(token.AccessToken);
var result = client.GetStringAsync($"{ServerUrl}/test").Result;

The problem is still the same: Now an HttpRequestException gets thrown (401 unauthorized).

Domenic
  • 708
  • 1
  • 9
  • 23
  • This question is a follow-up of: http://stackoverflow.com/questions/40425587/identityserver3-principals-always-null – Domenic Nov 07 '16 at 10:23
  • It's not as easy as that the tokens are not set on the appClient in the scenarios below "get token"? cp-paste the token fetching into each scenario, and just verify it's not that – John Korsnes Nov 07 '16 at 11:29
  • Didn't work. I've updated the question – Domenic Nov 07 '16 at 11:45

1 Answers1

0

In the meantime I found the reason why it wasn't working:

Turned out I have to use version 2.6.0 of IdentityServer3.AccessTokenValidation or earlier on the WebApi. As soon as I update to 2.7.0 or later it stops working. I didn't have time to find out what exactly has changed between the two releases and therefore what causes the problem. But I could isolate it to IdentityServer3.AccessTokenValidation

Domenic
  • 708
  • 1
  • 9
  • 23
  • What version of IdentityModel did you have installed in your project? – John Korsnes Nov 09 '16 at 12:22
  • I've installed version 2.0.0 of IdentityModel – Domenic Nov 09 '16 at 12:24
  • Seems there were some versions of IdentityModel that did not work for a while with the latest IdentityServer.AccessTokenValidatoin. I see Dominic pushed a new version yesterday fixing that: https://www.nuget.org/packages/IdentityServer3.AccessTokenValidation/2.12.0 Maybe 2.12 works? Probably would need to downgrade IdentityModel. – John Korsnes Nov 09 '16 at 12:27
  • See https://github.com/IdentityServer/IdentityServer3.AccessTokenValidation/pull/117 – John Korsnes Nov 09 '16 at 12:28