Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mekansime for å matche authentication scheme for token issuer #212

Closed
Tracked by #41
elsand opened this issue Oct 14, 2023 · 0 comments · Fixed by #287
Closed
Tracked by #41

Mekansime for å matche authentication scheme for token issuer #212

elsand opened this issue Oct 14, 2023 · 0 comments · Fixed by #287
Labels
auth Issue related to authentication / authorization enhancement New feature or request

Comments

@elsand
Copy link
Member

elsand commented Oct 14, 2023

Det er ingen smart matching mellom innkommed requests og hvilket authentication scheme som velges, så alle kjøres gjennom til én matcher. Det innebærer at hvis en f.eks. gjør en request med et Altinn-token, og konfigurasjonen WebApi:Authentication:JwtBearerTokenSchemas består av (i denne rekkefølgen) Maskinporten, MaskinportenAuxillary, Altinn vil det kastes to exceptions for de to Maskinporten-schemene som feiler, før det treffer Altinn-schemaet hvor tokenet aksepteres.

På min maskin med release-build og Serilog__MinimumLevel__Default satt til Error måles ca 15% økning i RPS på min PC hvis det treffer på første scheme vs treff på siste scheme. Målt med tests\k6\run.ps1 -ApiEnvironment localdev -ApiVersion v1 -TokenGeneratorUsername *** -TokenGeneratorPassword ** -FilePath tests\k6\tests\serviceowner\dialogSearch.js --vus 10 --duration 30s

Antagelsen er at overheaden kommer av at det kastes exceptions, som er forholdsvis dyrt. Dette vil også potensielt skape støy i application insights (som tracker alt av exceptions).

En potensiell optimalisering her er:

  1. Ved startup, eller i en singleton service, konstruerer en map mellom issuers og schemas, noe ala:
Dictionary<string, string> issuerToSchemeMap = new Dictionary<string, string>();

foreach (var schema in jwtTokenSchemas)
{
    var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(
        schema.WellKnown, new OpenIdConnectConfigurationRetriever());
    var config = await configManager.GetConfigurationAsync();
    issuerToSchemeMap[config.Issuer] = schema.Name;
}
  1. Introdusere en mellomvare som per request parser token, finner issuer, og lagrer matchet schema i context, noe ala:
public async Task Invoke(HttpContext context)
{
    if (context.Request.Headers.ContainsKey("Authorization"))
    {
        var authHeader = context.Request.Headers["Authorization"].ToString();
        var token = authHeader.Replace("Bearer ", string.Empty);
        var jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(token);
        var issuer = jwtToken.Issuer;

        if (issuerToSchemeMap.TryGetValue(issuer, out var scheme))
        {
            context.Items["CurrentScheme"] = scheme;
        }
    }

    await _next(context);
}
  1. Bruke en eventhandler per scheme som sjekker CurrentScheme matcher før den i det hele tatt prøver:
foreach (var schema in jwtTokenSchemas)
{
    authenticationBuilder.AddJwtBearer(schema.Name, options =>
    {
        options.MetadataAddress = schema.WellKnown;
        options.TokenValidationParameters = ....


        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                if ((string)context.HttpContext.Items["CurrentScheme"] != schema.Name)
                {
                    context.NoResult(); // Skip the current authentication scheme
                    return Task.CompletedTask;
                }

                // If the scheme matches, it will continue to validate the token for this scheme.
                return Task.CompletedTask;
            }
        };

    });
}

Antagelsen er at dette vil være raskere, siden det ikke vil kastes exceptions. Minuset er at ReadJwtToken alltid må gjøres to ganger, selv om det er treff på første scheme (en gang i mellomvaren og en gang i selve handleren).

@elsand elsand added the auth Issue related to authentication / authorization label Oct 14, 2023
@elsand elsand moved this from Nye issues to 📋 Backlog in Dialogporten / Arbeidsflate - GAMMEL Oct 26, 2023
@elsand elsand added the enhancement New feature or request label Nov 6, 2023
@github-project-automation github-project-automation bot moved this from 📋 Backlog to Ferdig in Dialogporten / Arbeidsflate - GAMMEL Dec 15, 2023
@elsand elsand moved this from Ferdig to 🔖 Klar for implementering in Dialogporten / Arbeidsflate - GAMMEL Dec 15, 2023
@elsand elsand moved this from 🔖 Klar for implementering to Ferdig in Dialogporten / Arbeidsflate - GAMMEL Dec 15, 2023
@elsand elsand added this to the Klar for ekstern testing milestone Mar 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth Issue related to authentication / authorization enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant