Architecture



The AuthServer framework has been built as a single NuGet package.


Endpoints have been designed as a minimum HTTP handler, with an accessor to parse the request, and a handler to validate and process the request.


endpoint architecture
Image 1: Class diagram of request handling

IRequestAccessor is responsible for parsing the request into a single request. It can for example contain parsed headers, query parameters and body parameters.

RequestHandler is responsible for accepting a request, then validate it through its IRequestValidator and if valid, then process it through IRequestProcessor.

IEndpointHandler is the HTTP request entrypoint and is responsible for handling the request by using IRequestHandler and IRequestAccessor.


The AuthServer framework consists of a single csharp project, containing feature folders, and core functionality shared across features.

For example, the authorize endpoint is a single feature, but some functionality is shared with the pushed authorization feature.

Consumers of the framework might not use all features that AuthServer has to offer, and therefore each feature can be enabled or disabled.
Some features, like Dynamic Client Registration offers fine grained feature control, grouped by action.
Therefore, getting a client is one feature, whereas creating a client is another feature.

Managing features is implemented through the Microsoft.FeatureManagement library.


module architecture
Image 2: State machine diagram of module handling

The feature flag filter is responsible for checking all incoming HTTP requests, whether the endpoint it reaches has been enabled through FeatureManagement. If it has been enabled, the execution flow continues normally, if it has not, then the request is cancelled immediately and the HTTP status code 404 is returned.
The feature flag check is also handled in the Discovery endpoint, to make sure metadata about disabled features is not exposed.


The Client and related data is accessed in almost every request, and that is by far mostly reading the client, as updating the client should rarely be done. Therefore, to alleviate the data store, all clients are cached in a distributed cache, for faster retrieval of data.