Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IdentityServer4 IdentityServer3.AccessTokenValidation

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.

like image 258
ozgurozkanakdemirci Avatar asked Jan 02 '17 10:01

ozgurozkanakdemirci


People also ask

What is IdentityServer3?

IdentityServer3. IdentityServer is a framework and a hostable component that allows implementing single sign-on and access control for modern web applications and APIs using protocols like OpenID Connect and OAuth2.

Is Identity Server 4 still free?

About IdentityServer4IdentityServer is a free, open source OpenID Connect and OAuth 2.0 framework for ASP.NET Core.

How do I get the refresh token in IdentityServer4?

To get a new access token, you send the refresh token to the token endpoint. This will result in a new token response containing a new access token and its expiration and potentially also a new refresh token depending on the client configuration (see above).


2 Answers

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" }
});
like image 167
Jonas Avatar answered Nov 10 '22 21:11

Jonas


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.

like image 20
Sean Song Avatar answered Nov 10 '22 21:11

Sean Song