IdentityServer4 IdentityServer3.AccessTokenValidation
Asked Answered
S

2

8

Happy new year to everyone...

I configured an IdentityServer4, and I can make successful ASP.net Core web api calls. But for asp.net framework 4.5.2 web apis, I got {"Response status code does not indicate success: 401 (Unauthorized)."} error from a .NET framework web api. I want to ask your help and opinion.

I seached the topic with IS4, and found some entries about IdentityServer3.AccessTokenValidation compatibility. And according to the replies, I loaded a signing cert and called AddSigningCredential instead of AddTemporarySigninCredential. x509certificate is a local created cert. and I updated IdentityServer3.AccessTokenValidation version to v2.13.0.

Still I got the error. Any help is appreciated.

Regards and thanks for your great effort.

IdentityServer 4 side: Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
                services
                .AddIdentityServer()                
                //.AddTemporarySigningCredential()
                .AddSigningCredential(x509Certificate)
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryClients(Config.GetClients())
                .AddAspNetIdentity<ApplicationUser>();
}

Config.cs

    public static IEnumerable<ApiResource> GetApiResources()
            {
                return new List<ApiResource>
                {
                    new ApiResource("AuthorizationWebApi","Authorization Web API .NET Core"),
                    new ApiResource("AuthorizationWebApiNetFramework","Authorization Web API NET Framework"),
                new ApiResource("api1", "Empty Test Api")
                };

            }

        public static IEnumerable<Client> GetClients()
        {
            return new List<Client> {
new Client {
                    ClientId = "silicon",
                    ClientName = "console app",
                    AllowedGrantTypes = GrantTypes.ClientCredentials,
                    ClientSecrets = { new Secret("abcdef".Sha256())},
                    AllowedScopes = new List<string>{
                    "AuthorizationWebApiNetFramework"
                    }

                },
                new Client
                {
                    ClientId = "MYUX",
                    ClientName = "MYUX MVC Client",
                    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
                    RequireConsent = false,
                    ClientSecrets= {new Secret("abcdef".Sha256()) },
                    RedirectUris = { "http://localhost:5002/signin-oidc" },
                    PostLogoutRedirectUris = {"http://localhost:5002"},

                    AllowedScopes = {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,                        
                        "custom.profile",
                        "AuthorizationWebApi",
                        "AuthorizationWebApiNetFramework"
                    },
                    AllowOfflineAccess = true
                }
            };
        }

.NET Framework APİ Side

public void Configuration(IAppBuilder app)
        {
            //ConfigureAuth(app);
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
            {
                Authority = "http://www.abcdefgh.com:5000",
                ValidationMode = ValidationMode.ValidationEndpoint,
                RequiredScopes = new[] { "AuthorizationWebApiNETFramework" }

            });
            //configure web api
            var config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();

            //require authentication for all controllers

            config.Filters.Add(new AuthorizeAttribute());

            app.UseWebApi(config);
        }

Calling side:

try
            {
                ViewData["Message"] = "Authorization Test.";
                var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");
                var authorizationApiClient = new HttpClient();
                authorizationApiClient.SetBearerToken(accessToken);
                var content = await authorizationApiClient.GetStringAsync("http://localhost:13243/values");
                return View();
            }
            catch (Exception ex)
            {
                throw;
            }

or by a console app...

try
{
    // discover endpoints from metadata
    var disco = await DiscoveryClient.GetAsync("http://www.abcdefgh.com:5000");

    var tokenClient = new TokenClient(disco.TokenEndpoint, "silicon", "abcdef");
    var tokenResponse = await tokenClient.RequestClientCredentialsAsync("AuthorizationWebApiNetFramework");

    if (tokenResponse.IsError)
    {
        Console.WriteLine(tokenResponse.Error);
        return;
    }

    Console.WriteLine(tokenResponse.Json);

    var client = new HttpClient();
    client.SetBearerToken(tokenResponse.AccessToken);

    var response = await client.GetAsync("http://localhost:13243/values");
    if (!response.IsSuccessStatusCode)
    {
        Console.WriteLine(response.StatusCode);
    }
    else
    {
        var content = await response.Content.ReadAsStringAsync();
        Console.WriteLine(JArray.Parse(content));
    }
}
catch (Exception)
{
   throw;
}     

EDIT: On 4.5.2 Api side: I commented out the line ValidationMode = ValidationMode.ValidationEndpoint. I added this line by following IS3 documentation. Thanks everyone.

Statfarad answered 2/1, 2017 at 10:36 Comment(6)
I'd suggest starting with the samples and confirm that they work. Then from the samples start to compare the differences in your custom projects.Salamanca
What does the idsrv4 log say on the time you recieve the 401 error.Ed
Thanks guys, @BrockAllen as i said I can authenticate ASP.Net Core MVC with open id connect, and authenticate ASP.Net Core WebApi with client credentials with my ASP.Net Core IS4. But I have problem with 4.5.2 ApiResource. Jonas Axelsson I see token being generated successfully, but as i remember nothing happens when I call GetAsync of WebApi. I'll check it today :). regardsStatfarad
@JonasAxelsson I created a new project, zipped and uploaded it to googledrive, I want to share it with you if u find it convenient. This time i keep it really simple :D. I dont know SO policy about it, so i did not copy here. Can we share drive link or email here? Btw, I see 4.5.2 web api accesstoken validation call on IS4 console.Statfarad
@JonasAxelsson I see 4.5.2 web api accesstoken validation call on IS4 console, But it is rejected by the api I think, I'll check extra logging on IS4 side.Statfarad
@JonasAxelsson I did it, thanks for your kind support. I commented out ValidationMode = ValidationMode.ValidationEndpoint row; it was taken from IS3 documentation tutorial btw. I noticed the error while checking the IS4 logs. Regards.Statfarad
E
6

Remove the following line in the WebAPI accesstoken validation middleware.

ValidationMode = ValidationMode.ValidationEndpoint

The result should look like this:

app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions 
{
     Authority = "http://www.abcdefgh.com:5000",
     RequiredScopes = new[] { "AuthorizationWebApiNETFramework" }
});
Ed answered 4/1, 2017 at 16:58 Comment(0)
G
4

In my case, I enabled the log following this: https://identityserver.github.io/Documentation/docsv2/consuming/diagnostics.html

By default Katana uses the TraceSource mechanism in .NET for logging. Add the following snippet to your config file to enable logging to a file:

<system.diagnostics>
  <trace autoflush="true" />

  <sources>
    <source name="Microsoft.Owin">
      <listeners>
        <add name="KatanaListener" />
      </listeners>
    </source>
  </sources>

  <sharedListeners>
    <add name="KatanaListener"
          type="System.Diagnostics.TextWriterTraceListener"
          initializeData="katana.trace.log"
          traceOutputOptions="ProcessId, DateTime" />
  </sharedListeners>

  <switches>
    <add name="Microsoft.Owin"
          value="Verbose" />
  </switches>
</system.diagnostics>

Then I saw the root cause in WebAPI folder log file "katana.trace.log":

    Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationMiddleware Error: 0 : Authentication failed
System.IO.FileLoadException: Could not load file or assembly 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'
   at IdentityServer3.AccessTokenValidation.ValidationEndpointTokenProvider.<ReceiveAsync>d__1.MoveNext()
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine& stateMachine)
   at IdentityServer3.AccessTokenValidation.ValidationEndpointTokenProvider.ReceiveAsync(AuthenticationTokenReceiveContext context)
   at Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationHandler.<AuthenticateCoreAsync>d__0.MoveNext()

After I upgraded the Newtonsoft.Json from 6.0 to 9.01, it worked.

Geometrize answered 30/10, 2018 at 6:22 Comment(1)
Adding the logging configuration to web.config made the error appear immediately after trying to get it to output for hours. Thank you!Tabard

© 2022 - 2024 — McMap. All rights reserved.