IdentityServer / IdentityServer3.AccessTokenValidation

OWIN Middleware to validate access tokens from IdentityServer3
Apache License 2.0
91 stars 149 forks source link

Set AccessToken Validation on a .net wepapi 2 with Identity server 4 #164

Closed brunosantos closed 6 years ago

brunosantos commented 6 years ago

I know how to setup IdentityServer 4 Authentication in .Net core. That is: using the extensions defined in IdentityServer4.AccessTokenValidation. And I would set it up in my startup class like so:

    app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
    {
        Authority = "http://localhost:5000",
        RequireHttpsMetadata = false,

        ApiName = "webapi"
    });

The problem is that now I need to make authenticated requests to a .net 4.6 web api2 (not core). And the same package doesn't work for that.

According to this question all I have to do is to use the same package that was used for Identity server 3:IdentityServer3.AccessTokenValidation.

But After trying it out all I get is 401 when making requests to the web api. And I don't know how to wire authentication events to understand the reason behind it. Here is my configuration:

Api Startup.cs:

    app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
    {
        Authority = "http://localhost:5000",
        RequiredScopes = new[] { "webapi" },     
    });

Client Startup.cs:

            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                AuthenticationType = "oidc",
                SignInAsAuthenticationType = "Cookies",
                Authority = "http://localhost:5000",
                RedirectUri = "http://localhost:3954/signin-oidc",
                ClientId = "MvcClient",
                Scope = "openid profile webapi offline_access",
                ResponseType = "code id_token",
                ClientSecret = "secret",
                UseTokenLifetime = false,
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false,
                },
});

TestController in the Client project:

    var tokenClient = new TokenClient("http://localhost:5000/connect/token", "MvcClient", "secret");
    var tokenResponse = await tokenClient.RequestClientCredentialsAsync("webapi");

    var client = new HttpClient();
    client.SetBearerToken(tokenResponse.AccessToken);
    var content = await client.GetStringAsync("http://localhost:5004/api/identity");

I successfully get an access token here. But get a 401 when making the request to api/identity.

Here is the Config in the IDP:

new ApiResource("webapi", "My API")
[...]
                new Client
                {
                    ClientId = "MvcClient",
                    ClientName = "MVC Client",
                    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

                    RequireConsent = true,

                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },

                    RedirectUris = { "http://localhost:3954/signin-oidc" },
                    PostLogoutRedirectUris = { "http://localhost:3954/signout-callback-oidc" },

                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        "netcoremvcapi",
                        "webapi"
                    },
                    AllowOfflineAccess = true,
                }

Any idea why this might be failing? Am I making the wrong assumption that I can use IdentityServer3.AccessTokenValidation to validate the token?

brunosantos commented 6 years ago

The first issue was that my startup class wasn't being called. That was solved by adding the Microsoft.Owin.Host.SystemWeb package.

Then it got interesting. I started getting an exception while registering OpenIdConnectAuthenticationMiddleware into the OWIN runtime:

Could not load type 'System.IdentityModel.Tokens.TokenValidationParameters' from assembly
'System.IdentityModel.Tokens.Jwt, Version=5.0.0.127

And the reason is because my web api 2 project is using the Owin implementation Katana. And apparently Katana does not support v5.0 of that package. As described here and here.

So for that I had to remove that package first (downgrade didn't work due to dependency). That also failed because of the dependency on my version of the package Microsoft.Owin.Security.Jwt. And that, of course, led to another issue with a dependency of another package....after removing all the dependant packages and reinstalling System.IdentityModel.Tokens.Jwt v4.0.2 and then IdentityServer3.AccessTokenValidation. It all worked with the same setup described above...