Search code examples
c#identityserver4

IdentityServer4: signin callback returns 404 status code - UserInfo endpoint not triggered


For some time now I've been trying to setup a project with IdentityServer4. I've come a long way, but now in the final stage I'm getting a 404 statuscode when IdentityServer takes me back to the web application (https://localhost:44384/signin-central?code=...&scope=...&state=...). First I was using the InMemoryClients etc, but now the data is sourced from the database and I had to do some refactoring.

I've been analysing the errors in the output window and updating my code accordingly. But with the code I have now, I'm not getting any errors anymore in my Output (with LogLevel set to Information).

Also I'm not keen on modifying the DefaultChallengeScheme, because this restricts you rightaway when you plan to have multiple OAuth providers in the future.

Code

This is The important code of the Client application

Application Startup
public class Startup {
    public Startup(IConfiguration configuration) {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services) {
        services.AddRazorPages();
        services
            .AddAuthentication(options => {
                //options.DefaultScheme = Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme;
                //options.DefaultAuthenticateScheme = Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme;
                //options.DefaultChallengeScheme = "oidc";
            }).AddCookie(Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme, options => {
                options.Cookie.HttpOnly = true;
                options.ExpireTimeSpan = TimeSpan.FromDays(30);
                options.AccessDeniedPath = new Microsoft.AspNetCore.Http.PathString("/AccessDenied");
            }).AddOAuth<CentralOptions, CentralHandler>("central", options => {
                options.ClaimsIssuer = "https://localhost:44359";
                options.SaveTokens = true;
                options.ClientId = "SsoApplicationClient";
                options.ClientSecret = "qsdfghjklm";

                //options.Scope.Add("openid");
                //options.Scope.Add("profile");
                //options.Scope.Add("email");
                options.Scope.Add("weatherforecasts.read");
                options.Scope.Add("weatherforecasts.write");

                options.UsePkce = true;

                //options.ClaimActions.MapJsonKey("email", )
            }).AddOpenIdConnect("oidc", options => {
                options.SignInScheme = "Cookies";

                options.Authority = "https://localhost:44359";
                options.RequireHttpsMetadata = false;

                options.ClientId = "SsoApplicationClient";
                options.ClientSecret = "qsdfghjklm";
                options.ResponseType = "code id_token";

                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                options.Scope.Add("weatherforecasts.read");
                options.Scope.Add("weatherforecasts.write");

                //options.ClaimActions.MapJsonKey("website", "website");

                options.Events.OnUserInformationReceived = async (info) => {
                    // This is never hit
                };
            });
        services
            .AddIdentity<Entities.User, Entities.Role>(options => {
            })
            .AddEntityFrameworkStores<SsoApplicationContext>()
            .AddDefaultTokenProviders();

        services
            .AddDbContext<SsoApplicationContext>()
            .AddScoped<Repositories.IAccountRepository, Repositories.AccountRepository>();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
        ...
    }
}
CentralOptions
public class CentralOptions : OAuthOptions {
    public CentralOptions() {
        CallbackPath = new Microsoft.AspNetCore.Http.PathString("/signin-central");
        AuthorizationEndpoint = "https://localhost:44359/connect/authorize";
        TokenEndpoint = "https://localhost:44359/connect/token";
        UserInformationEndpoint = "https://localhost:44359/connect/userinfo";
    }
}

Here I've overridden the methods to check what methods are being called, and what aren't. Everything below the comment line is never called.

CentralHandler
public class CentralHandler : OAuthHandler<CentralOptions> {
    public CentralHandler(IOptionsMonitor<CentralOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) {
    }
    protected override async Task InitializeEventsAsync() {
        await base.InitializeEventsAsync();
    }
    protected override async Task InitializeHandlerAsync() {
        await base.InitializeHandlerAsync();
    }
    protected override string ResolveTarget(string scheme) {
        var result = base.ResolveTarget(scheme);
        return result;
    }
    protected override async Task HandleChallengeAsync(AuthenticationProperties properties) {
        await base.HandleChallengeAsync(properties);
    }
    protected override void GenerateCorrelationId(AuthenticationProperties properties) {
        base.GenerateCorrelationId(properties);
    }
    protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri) {
        var challengeUrl = base.BuildChallengeUrl(properties, redirectUri);
        return challengeUrl;
    }
    protected override string FormatScope() {
        var scope = base.FormatScope();
        return scope;
    }
    protected override string FormatScope(IEnumerable<string> scopes) {
        var scope = base.FormatScope(scopes);
        return scope;
    }
    // Everything below this line is never called
    protected override async Task<object> CreateEventsAsync() {
        var events = await base.CreateEventsAsync();
        return events;
    }
    protected override async Task<HandleRequestResult> HandleAccessDeniedErrorAsync(AuthenticationProperties properties) {
        var result = await base.HandleAccessDeniedErrorAsync(properties);
        return result;
    }
    protected override async Task HandleForbiddenAsync(AuthenticationProperties properties) {
        await base.HandleForbiddenAsync(properties);
    }
    protected override async Task<HandleRequestResult> HandleRemoteAuthenticateAsync() {
        var result = await base.HandleRemoteAuthenticateAsync();
        return result;
    }
    public override async Task<bool> HandleRequestAsync() {
        var result = await base.HandleRequestAsync();
        return result;
    }
    public override async Task<bool> ShouldHandleRequestAsync() {
        var result = await base.ShouldHandleRequestAsync();
        return result;
    }
    protected override bool ValidateCorrelationId(AuthenticationProperties properties) {
        var result = base.ValidateCorrelationId(properties);
        return result;
    }
    protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) {
        var endpoint = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, "access_token", tokens.AccessToken);
        var response = await Backchannel.GetAsync(endpoint, Context.RequestAborted);
        if (!response.IsSuccessStatusCode)
        {
            throw new HttpRequestException($"An error occurred when retrieving Facebook user information ({response.StatusCode}). Please check if the authentication information is correct and the corresponding Facebook Graph API is enabled.");
        }

        var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());

        var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement);
        context.RunClaimActions();

        await Events.CreatingTicket(context);

        return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
    }
    protected override async Task<OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context) {
        var result = await base.ExchangeCodeAsync(context);
        return result;
    }
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync() {
        var result = await base.HandleAuthenticateAsync();
        return result;
    }
}

This is the important code of the IdentityServer application

Startup
public class Startup {
    public Startup(IConfiguration configuration) {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services) {
        services.AddRazorPages();
        services.AddAuthentication(options => { });
        services.AddAuthorization();
        services
            .AddDbContext<SsoCentralContext>()
            .AddScoped<Repositories.IAccountRepository, Repositories.AccountRepository>()
            .AddScoped<Services.IAccountService, Services.AccountService>();

        services.AddIdentity<Entities.User, Entities.Role>()
            .AddEntityFrameworkStores<SsoCentralContext>();

        var isBuilder = services.AddIdentityServer();
        isBuilder
            .AddDeveloperSigningCredential()
            .AddOperationalStore<SsoCentralContext>(identityServerOptions => {
                identityServerOptions.ConfigureDbContext = (builder) => builder
                    .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=SsoCentral;Trusted_Connection=True;ConnectRetryCount=0");
            }).AddConfigurationStore<SsoCentralContext>(identityServerOptions =>
                identityServerOptions.ConfigureDbContext = (builder) => builder
                    .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=SsoCentral;Trusted_Connection=True;ConnectRetryCount=0")
            ).AddAspNetIdentity<Entities.User>();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
        if (env.IsDevelopment()) {
            app.UseDeveloperExceptionPage();
        } else {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.Use(async (context, next) => {
            if (context.Request.Path.Value.Contains("connect/authorize")) {
                // Inspect the parameters of the Authorization request here
            }
            await next();
        });

        app.UseRouting();
        app.UseIdentityServer();
        app.UseAuthorization();
        app.UseEndpoints(endpoints => {
            endpoints.MapControllers();
            endpoints.MapRazorPages();
        });
    }
}
SsoCentralContext
internal class SsoCentralContext : IdentityDbContext<Entities.User, Entities.Role, string>, IPersistedGrantDbContext, IConfigurationDbContext {
    ...
}
AccountController
[Route("[controller]")]
public class AccountController : Controller {
    private readonly IIdentityServerInteractionService interaction;
    private readonly IHttpContextAccessor httpContextAccessor;
    private readonly IEventService events;
    public AccountController(...) { ... }

    [HttpGet("Login")]
    public async Task<IActionResult> Login([FromQuery] string returnUrl) {
        var context = await interaction.GetAuthorizationContextAsync(returnUrl);
        return View(new ViewModels.Account.LoginVM {
            ReturnUrl = returnUrl,
            User = new Dtos.Dtos.User {
                UserName = context?.LoginHint,
            }
        });
    }

    [HttpPost("Login")]
    public async Task<IActionResult> LoginPost([FromForm] ViewModels.Account.LoginVM model) {
        var request = await interaction.GetAuthorizationContextAsync(redirectUrl);
        try {
            var user = await accountRepository.Login(model.User.Email, model.Password);
            await events.RaiseAsync(new UserLoginSuccessEvent(model.User.UserName, model.User.Id, model.User.UserName, clientId: request?.Client.ClientId));
            var isUser = new IdentityServer4.IdentityServerUser(model.User.Id) {
                DisplayName = model.User.UserName,
                AdditionalClaims = new[] {
                    new System.Security.Claims.Claim("sub", model.User.Id),
                    new System.Security.Claims.Claim("email", model.User.Email),
                    new System.Security.Claims.Claim("name", model.User.UserName),
                }
            };
            await httpContextAccessor.HttpContext.SignInAsync(isUser);

            if (request != null) {
                return Redirect(model.ReturnUrl);
            } else if (Url.IsLocalUrl(model.ReturnUrl)) {
                return Redirect(model.ReturnUrl);
            } else if (string.IsNullOrEmpty(model.ReturnUrl)) {
                return Redirect("~/");
            } else {
                throw new System.Exception("Invalid return url");
            }
        } catch (System.Exception ex) {
            await events.RaiseAsync(new UserLoginFailureEvent(loginEx.Email, "invalid credentials", clientId: request?.Client.ClientId));
            return View(model);
        }
    }
}

Setup

To debug the code:

git clone https://github.com/PieterjanDeClippel/SSO.git
cd SSO/Application/Sso.Application.Data
dotnet ef database update --project ..\Sso.Application.Data --context SsoApplicationContext
cd ../../Central/Sso.Central.Data
dotnet ef database update --project ..\Sso.Central.Data --context SsoCentralContext

Run the SQL-script at SSO.Central.Data/Sql/CreateClient.sql

Or instead of all of the above, you can restore the dacpacs located at the /dacpac folder.

Set following startup projects:

  • Sso.Central
  • Sso.Application

Here is a demo of what's happening

Demo of the IdentityServer application

And here's the cutout of the Output window:

IdentityServer4.Startup: Information: Starting IdentityServer4 version 4.1.2+997a6cdd643e46cd5762b710c4ddc43574cbec2e
IdentityServer4.Startup: Information: Using the default authentication scheme Identity.Application for IdentityServer
IdentityServer4.Startup: Debug: Using Identity.Application as default ASP.NET Core scheme for authentication
IdentityServer4.Startup: Debug: Using Identity.External as default ASP.NET Core scheme for sign-in
IdentityServer4.Startup: Debug: Using Identity.External as default ASP.NET Core scheme for sign-out
IdentityServer4.Startup: Debug: Using Identity.Application as default ASP.NET Core scheme for challenge
IdentityServer4.Startup: Debug: Using Identity.Application as default ASP.NET Core scheme for forbid
Microsoft.Hosting.Lifetime: Information: Application started. Press Ctrl+C to shut down.
Microsoft.Hosting.Lifetime: Information: Hosting environment: Development
Microsoft.Hosting.Lifetime: Information: Content root path: C:\Users\Pieterjan De Clippel\source\repos\SSO\Central\Sso.Central
IdentityServer4.Startup: Debug: Login Url: /Account/Login
IdentityServer4.Startup: Debug: Login Return Url Parameter: ReturnUrl
IdentityServer4.Startup: Debug: Logout Url: /Account/Logout
IdentityServer4.Startup: Debug: ConsentUrl Url: /consent
IdentityServer4.Startup: Debug: Consent Return Url Parameter: returnUrl
IdentityServer4.Startup: Debug: Error Url: /home/error
IdentityServer4.Startup: Debug: Error Id Parameter: errorId
IdentityServer4.Hosting.EndpointRouter: Trace: No endpoint entry found for request path: /
Sso.Application.CentralHandler: Debug: HandleChallenge with Location: https://localhost:44359/connect/authorize?client_id=SsoApplicationClient&scope=weatherforecasts.read%20weatherforecasts.write&response_type=code&redirect_uri=https%3A%2F%2Flocalhost%3A44384%2Fsignin-central&code_challenge=HawX6uXjjANMQJQbhwsxi5zlsFrQKzGzOiyefqEbfnI&code_challenge_method=S256&state=CfDJ8PC7ZLg_v2RDsl0VaXUuuT9WNuyCeQha-k3ea6NLsX65PkYCYTKtf9EK-wHqKcvECq5o6zsSVViHYi3gw66FydCTo_YImAwSpM7ShCcajz-Otdo0V8btKv-PtRLPZ2xoy1WBK90ZqAYk-EvZl59PUWBAJRaiU7VVkD8kV2YdY6wkQzwJJYA8qYQSJFgz-cMTwrYsZOzVjMx1lkHTVpyCZ9Lg48p5wBqN0y6R49yWIuDfLu3_7vAivlTJdgcXz9NT9HVeu89V2afjFxJLTQa2igeympC7JO-HRhdK5Zr-GM538kMAjZz5OW8dRWzKo-dX6rHSy3DC4hgaNXLuPK4b5qgStG4Wi4U5PH0LE9flO4bP; and Set-Cookie: .AspNetCore.Correlation.central.vhEd_no3ibUFd7fiocNPiZ25zTfFWfbuuM8BVh6LUMo=N; expires=Mon, 15 Nov 2021 20:47:22 GMT; path=/signin-central; secure; samesite=none; httponly.
Sso.Application.CentralHandler: Information: AuthenticationScheme: central was challenged.
IdentityServer4.Hosting.EndpointRouter: Debug: Request path /connect/authorize matched to endpoint type Authorize
IdentityServer4.Hosting.EndpointRouter: Debug: Endpoint enabled: Authorize, successfully created handler: IdentityServer4.Endpoints.AuthorizeEndpoint
IdentityServer4.Hosting.IdentityServerMiddleware: Information: Invoking IdentityServer endpoint: IdentityServer4.Endpoints.AuthorizeEndpoint for /connect/authorize
IdentityServer4.Endpoints.AuthorizeEndpoint: Debug: Start authorize request
IdentityServer4.Endpoints.AuthorizeEndpoint: Debug: No user present in authorize request
IdentityServer4.Validation.AuthorizeRequestValidator: Debug: Start authorize request protocol validation
IdentityServer4.EntityFramework.Stores.ClientStore: Debug: SsoApplicationClient found in database: True
IdentityServer4.Stores.ValidatingClientStore: Trace: Calling into client configuration validator: IdentityServer4.Validation.DefaultClientConfigurationValidator
IdentityServer4.Stores.ValidatingClientStore: Debug: client configuration validation for client SsoApplicationClient succeeded.
IdentityServer4.Validation.AuthorizeRequestValidator: Debug: Checking for PKCE parameters
IdentityServer4.EntityFramework.Stores.ResourceStore: Debug: Found  identity scopes in database
IdentityServer4.EntityFramework.Stores.ResourceStore: Debug: Found weatherforecasts API resources in database
IdentityServer4.EntityFramework.Stores.ResourceStore: Debug: Found weatherforecasts.read, weatherforecasts.write scopes in database
IdentityServer4.Validation.AuthorizeRequestValidator: Debug: Calling into custom validator: IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator
IdentityServer4.Validation.AuthorizeRequestValidator: Trace: Authorize request protocol validation successful
IdentityServer4.Endpoints.AuthorizeEndpoint: Debug: ValidatedAuthorizeRequest
{
  "ClientId": "SsoApplicationClient",
  "ClientName": "SsoApplicationClient",
  "RedirectUri": "https://localhost:44384/signin-central",
  "AllowedRedirectUris": [
    "https://localhost:44384/signin-central"
  ],
  "SubjectId": "anonymous",
  "ResponseType": "code",
  "ResponseMode": "query",
  "GrantType": "authorization_code",
  "RequestedScopes": "weatherforecasts.read weatherforecasts.write",
  "State": "CfDJ8PC7ZLg_v2RDsl0VaXUuuT9WNuyCeQha-k3ea6NLsX65PkYCYTKtf9EK-wHqKcvECq5o6zsSVViHYi3gw66FydCTo_YImAwSpM7ShCcajz-Otdo0V8btKv-PtRLPZ2xoy1WBK90ZqAYk-EvZl59PUWBAJRaiU7VVkD8kV2YdY6wkQzwJJYA8qYQSJFgz-cMTwrYsZOzVjMx1lkHTVpyCZ9Lg48p5wBqN0y6R49yWIuDfLu3_7vAivlTJdgcXz9NT9HVeu89V2afjFxJLTQa2igeympC7JO-HRhdK5Zr-GM538kMAjZz5OW8dRWzKo-dX6rHSy3DC4hgaNXLuPK4b5qgStG4Wi4U5PH0LE9flO4bP",
  "PromptMode": "",
  "SessionId": "",
  "Raw": {
    "client_id": "SsoApplicationClient",
    "scope": "weatherforecasts.read weatherforecasts.write",
    "response_type": "code",
    "redirect_uri": "https://localhost:44384/signin-central",
    "code_challenge": "HawX6uXjjANMQJQbhwsxi5zlsFrQKzGzOiyefqEbfnI",
    "code_challenge_method": "S256",
    "state": "CfDJ8PC7ZLg_v2RDsl0VaXUuuT9WNuyCeQha-k3ea6NLsX65PkYCYTKtf9EK-wHqKcvECq5o6zsSVViHYi3gw66FydCTo_YImAwSpM7ShCcajz-Otdo0V8btKv-PtRLPZ2xoy1WBK90ZqAYk-EvZl59PUWBAJRaiU7VVkD8kV2YdY6wkQzwJJYA8qYQSJFgz-cMTwrYsZOzVjMx1lkHTVpyCZ9Lg48p5wBqN0y6R49yWIuDfLu3_7vAivlTJdgcXz9NT9HVeu89V2afjFxJLTQa2igeympC7JO-HRhdK5Zr-GM538kMAjZz5OW8dRWzKo-dX6rHSy3DC4hgaNXLuPK4b5qgStG4Wi4U5PH0LE9flO4bP"
  }
}
IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator: Trace: ProcessInteractionAsync
IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator: Information: Showing login: User is not authenticated
IdentityServer4.Endpoints.AuthorizeEndpoint: Trace: End authorize request. result type: IdentityServer4.Endpoints.Results.LoginPageResult
IdentityServer4.Hosting.IdentityServerMiddleware: Trace: Invoking result: IdentityServer4.Endpoints.Results.LoginPageResult
IdentityServer4.Hosting.EndpointRouter: Trace: No endpoint entry found for request path: /Account/Login
IdentityServer4.Services.OidcReturnUrlParser: Trace: returnUrl is valid
IdentityServer4.Validation.AuthorizeRequestValidator: Debug: Start authorize request protocol validation
IdentityServer4.EntityFramework.Stores.ClientStore: Debug: SsoApplicationClient found in database: True
IdentityServer4.Stores.ValidatingClientStore: Trace: Calling into client configuration validator: IdentityServer4.Validation.DefaultClientConfigurationValidator
IdentityServer4.Stores.ValidatingClientStore: Debug: client configuration validation for client SsoApplicationClient succeeded.
IdentityServer4.Validation.AuthorizeRequestValidator: Debug: Checking for PKCE parameters
IdentityServer4.EntityFramework.Stores.ResourceStore: Debug: Found  identity scopes in database
IdentityServer4.EntityFramework.Stores.ResourceStore: Debug: Found weatherforecasts API resources in database
IdentityServer4.EntityFramework.Stores.ResourceStore: Debug: Found weatherforecasts.read, weatherforecasts.write scopes in database
IdentityServer4.Validation.AuthorizeRequestValidator: Debug: Calling into custom validator: IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator
IdentityServer4.Validation.AuthorizeRequestValidator: Trace: Authorize request protocol validation successful
IdentityServer4.Services.OidcReturnUrlParser: Trace: AuthorizationRequest being returned
IdentityServer4.Services.DefaultIdentityServerInteractionService: Trace: AuthorizationRequest being returned
Sso.Application.CentralHandler: Debug: HandleChallenge with Location: https://localhost:44359/connect/authorize?client_id=SsoApplicationClient&scope=weatherforecasts.read%20weatherforecasts.write&response_type=code&redirect_uri=https%3A%2F%2Flocalhost%3A44384%2Fsignin-central&code_challenge=8Y5LgodB0uHMn0_GM9CmNYmqEYGfJz15EDSf2xaYfNg&code_challenge_method=S256&state=CfDJ8PC7ZLg_v2RDsl0VaXUuuT8NE8XSs1AYCpL2ZvWOHqXb3wfqoMRmAH4sn59F6H58d2TcUTPijfKCPrL9GlynS0MZJSfzQVchhFExl9Q9Qg_7J9qLr_TP-4z9tOeCcwFKDdl9O-_ecFuNc1SzWGb_DkgtPfFvVBwlIPahb4SChuHwhkHHynIVGxTUb8Xpdtmtpu2wXjq9vW-G_ShcEdRxWBQBCSqAtu3w2XDPEmtz1GwaGwhc68sZ38-PF2RW2WmrY_E1OK7mET9yfxK1Y0IAfH4I8KodEoK6sQohtOgVKrJKZLfu6H7ndhsON85jtELk1uEYZHHmHJq544ce1TkxQkN030XSHrDAIgIKZKEyb1Ft; and Set-Cookie: .AspNetCore.Correlation.central.ndfb5rjEd-gqaE4rKKeJb2DBQ2hTgf9U22nCZ6Day-U=N; expires=Mon, 15 Nov 2021 20:47:43 GMT; path=/signin-central; secure; samesite=none; httponly.
Sso.Application.CentralHandler: Information: AuthenticationScheme: central was challenged.
IdentityServer4.Hosting.EndpointRouter: Debug: Request path /connect/authorize matched to endpoint type Authorize
IdentityServer4.Hosting.EndpointRouter: Debug: Endpoint enabled: Authorize, successfully created handler: IdentityServer4.Endpoints.AuthorizeEndpoint
IdentityServer4.Hosting.IdentityServerMiddleware: Information: Invoking IdentityServer endpoint: IdentityServer4.Endpoints.AuthorizeEndpoint for /connect/authorize
IdentityServer4.Endpoints.AuthorizeEndpoint: Debug: Start authorize request
IdentityServer4.Endpoints.AuthorizeEndpoint: Debug: No user present in authorize request
IdentityServer4.Validation.AuthorizeRequestValidator: Debug: Start authorize request protocol validation
IdentityServer4.EntityFramework.Stores.ClientStore: Debug: SsoApplicationClient found in database: True
IdentityServer4.Stores.ValidatingClientStore: Trace: Calling into client configuration validator: IdentityServer4.Validation.DefaultClientConfigurationValidator
IdentityServer4.Stores.ValidatingClientStore: Debug: client configuration validation for client SsoApplicationClient succeeded.
IdentityServer4.Validation.AuthorizeRequestValidator: Debug: Checking for PKCE parameters
IdentityServer4.EntityFramework.Stores.ResourceStore: Debug: Found  identity scopes in database
IdentityServer4.EntityFramework.Stores.ResourceStore: Debug: Found weatherforecasts API resources in database
IdentityServer4.EntityFramework.Stores.ResourceStore: Debug: Found weatherforecasts.read, weatherforecasts.write scopes in database
IdentityServer4.Validation.AuthorizeRequestValidator: Debug: Calling into custom validator: IdentityServer4.Validation.DefaultCustomAuthorizeRequestValidator
IdentityServer4.Validation.AuthorizeRequestValidator: Trace: Authorize request protocol validation successful

Discodoc

{
  "issuer": "https://localhost:44359",
  "jwks_uri": "https://localhost:44359/.well-known/openid-configuration/jwks",
  "authorization_endpoint": "https://localhost:44359/connect/authorize",
  "token_endpoint": "https://localhost:44359/connect/token",
  "userinfo_endpoint": "https://localhost:44359/connect/userinfo",
  "end_session_endpoint": "https://localhost:44359/connect/endsession",
  "check_session_iframe": "https://localhost:44359/connect/checksession",
  "revocation_endpoint": "https://localhost:44359/connect/revocation",
  "introspection_endpoint": "https://localhost:44359/connect/introspect",
  "device_authorization_endpoint": "https://localhost:44359/connect/deviceauthorization",
  "frontchannel_logout_supported": true,
  "frontchannel_logout_session_supported": true,
  "backchannel_logout_supported": true,
  "backchannel_logout_session_supported": true,
  "scopes_supported": [
    "openid",
    "profile",
    "email",
    "role",
    "weatherforecasts.read",
    "weatherforecasts.write",
    "offline_access"
  ],
  "claims_supported": [
    "role"
  ],
  "grant_types_supported": [
    "authorization_code",
    "client_credentials",
    "refresh_token",
    "implicit",
    "password",
    "urn:ietf:params:oauth:grant-type:device_code"
  ],
  "response_types_supported": [
    "code",
    "token",
    "id_token",
    "id_token token",
    "code id_token",
    "code token",
    "code id_token token"
  ],
  "response_modes_supported": [
    "form_post",
    "query",
    "fragment"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic",
    "client_secret_post"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "subject_types_supported": [
    "public"
  ],
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ],
  "request_parameter_supported": true
}

Solution

  • Okay so apparently I was missing the UseAuthentication middleware, but now it seems that the token returned from the IdentityServer don't contain any information