skip to Main Content

I’m trying to implement an authorization code flow using Identity Server 4 but when I attempt to generate my authorization code all I get is a generic error page with nothing but the message ‘Sorry, there was an error’. (Title is ‘Error’).

I get this whether I’m using Postman or programmatically submitting a GET request with the required parameters.

To run my test, in Visual studio I start the Identity server and my API server. I start my MVC site to log in as the test user if needed and to make the callback url available. I then press the ‘Get New Access Token’ button in Postman. The result is that generic error.

I understand that when I programmatically submit the GET request the response should be the Auth Code which would be ideal but at this point I just want to successfully authenticate the client.

Can anyone see anything I might be missing?

In Postman my parameters are as follows in this image:

Settings I use for Postman testing

My Client is set up as follows:

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

                AllowedGrantTypes = GrantTypes.Code ,

                // where to redirect to after login
                RedirectUris = { "https://localhost:5002/signin-oidc" },

                // where to redirect to after logout
                PostLogoutRedirectUris = { "https://localhost:5002/signout-callback-oidc" },

                AllowOfflineAccess = true,
                AllowAccessTokensViaBrowser = true,

                AllowedScopes = new List<string>
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "api1",
                    IdentityServerConstants.StandardScopes.Email
                }
            }

My test user is this one that comes with the Identity Server Github code:

                new TestUser
                {
                    SubjectId = "88421113",
                    Username = "bob",
                    Password = "bob",
                    Claims =
                    {
                        new Claim(JwtClaimTypes.Name, "Bob Smith"),
                        new Claim(JwtClaimTypes.GivenName, "Bob"),
                        new Claim(JwtClaimTypes.FamilyName, "Smith"),
                        new Claim(JwtClaimTypes.Email, "[email protected]"),
                        new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
                        new Claim(JwtClaimTypes.WebSite, "http://bob.com"),
                        new Claim(JwtClaimTypes.Address, JsonSerializer.Serialize(address), IdentityServerConstants.ClaimValueTypes.Json)
                    }
                }

My Startup for Identity Server:

public class Startup
{
    public IWebHostEnvironment Environment { get; }

    public Startup(IWebHostEnvironment environment)
    {
        Environment = environment;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        // uncomment, if you want to add an MVC-based UI
        services.AddControllersWithViews();

        services.AddAuthentication()
            .AddGoogle("Google", options =>
            {
                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;

                options.ClientId = "<insert here>";
                options.ClientSecret = "<insert here>";
            });

        services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication (options =>
            {
                options.Authority = "https://localhost:5001";
                options.ApiName = "testapis";
            });


        var builder = services.AddIdentityServer(options =>
        {
            // see https://identityserver4.readthedocs.io/en/latest/topics/resources.html
            options.EmitStaticAudienceClaim = true;
        })
        .AddDeveloperSigningCredential()        //This is for dev only scenarios when you don’t have a certificate to use.
        .AddInMemoryIdentityResources(Config.IdentityResources)
        .AddInMemoryApiScopes(Config.ApiScopes)
        .AddInMemoryClients(Config.Clients)
        .AddTestUsers(TestUsers.Users)
        .AddCustomTokenRequestValidator<CustomTokenRequestValidator>();

        // not recommended for production - you need to store your key material somewhere secure
        builder.AddDeveloperSigningCredential();
    }

    public void Configure(IApplicationBuilder app)
    {
        if (Environment.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseHttpsRedirection();
        //// uncomment if you want to add MVC
        app.UseStaticFiles();
        app.UseRouting();
        
        app.UseIdentityServer();
        app.UseAuthentication();

        //// uncomment, if you want to add MVC
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute();
        });
    }
}

2

Answers


  1. Chosen as BEST ANSWER

    I've finally been able to get my access tokens and from what I can tell, when the AllowedGrantType on the target client is 'ClientCredentials', you cannot request the openid or profile scopes. For my test client I had added those two scopes to the AllowedScopes list but always failed to get my auth code. If I only request an ApiScope it's fine. If the scope is an IdentityResource it will not work.

    This is fine as my project requires that I implement the Code grantType which I've got working to a degree.


  2. One problem is that you should always ask for the openid scope, not just ap1.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search