Skip to content
This repository has been archived by the owner on Nov 19, 2024. It is now read-only.

Web Applications

Dominick Baier edited this page Jul 24, 2022 · 12 revisions

Overview

This library automates all the tasks around token lifetime management for user-centric web applications.

While many of the details can be customized, by default the following is assumed:

  • ASP.NET Core web application
  • cookie authentication handler for session management
  • OpenID Connect authentication handler for authentication and access token requests against an OpenID Connect compliant token service
  • the token service returns a refresh token

Setup

By default, the token management library will use the ASP.NET Core default authentication handler for token store (this is typically the cookie handler and its authentication session), and the default challenge scheme to deriving token client configuration for refreshing tokens or requesting client credential tokens (this is typically the OpenID Connect handler pointing to your trusted authority).

// setting up default schemes and handlers
builder.Services.AddAuthentication(options =>
    {
        options.DefaultScheme = "cookie";
        options.DefaultChallengeScheme = "oidc";
    })
    .AddCookie("cookie", options =>
    {
        options.Cookie.Name = "web";

        // automatically revoke refresh token at signout time
        options.Events.OnSigningOut = async e => { await e.HttpContext.RevokeRefreshTokenAsync(); };
    })
    .AddOpenIdConnect("oidc", options =>
    {
        options.Authority = "https://sts.company.com";

        options.ClientId = "webapp";
        options.ClientSecret = "secret";

        options.ResponseType = "code";
        options.ResponseMode = "query";

        options.Scope.Clear();

        // OIDC related scopes
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("email");

        // API scopes
        options.Scope.Add("invoice");
        options.Scope.Add("customer");

        // requests a refresh token
        options.Scope.Add("offline_access");
        
        options.GetClaimsFromUserInfoEndpoint = true;
        options.MapInboundClaims = false;

        // important! this store the access and refresh token in the authentication session
        // this is needed to the standard token store to manage the artefacts
        options.SaveTokens = true;
        
        options.TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = "name",
            RoleClaimType = "role"
        };
    });

// adds services for token management
builder.Services.AddOpenIdConnectAccessTokenManagement();

HTTP client factory

Similar to the worker service support, you can register HTTP clients that automatically send the access token of the current user when making API calls. The message handler plumbing associated with those HTTP clients will try to make sure, the access token is always valid and not expired.

// registers HTTP client that uses the managed user access token
builder.Services.AddUserAccessTokenHttpClient("user_client",
    configureClient: client => { client.BaseAddress = new Uri("https://api.company.com/invoices/"); });

This could be also a typed client:

// registers a typed HTTP client with token management support
builder.Services.AddHttpClient<InvoiceClient>(client =>
    {
        client.BaseAddress = new Uri("https://api.company.com/invoices/");
    })
    .AddUserAccessTokenHandler();

Of course, the ASP.NET Core web application host could also do machine to machine API calls that are independent of a user. In this case all the token client configuration can be inferred from the OpenID Connect handler configuration. The following registers an HTTP client that uses a client credentials token for outgoing calls:

// registers HTTP client that uses the managed client access token
builder.Services.AddClientAccessTokenHttpClient("masterdata.client",
    configureClient: client => { client.BaseAddress = new Uri("https://api.company.com/masterdata/"); });