Creating your own OpenID Connect server with ASOS: registering the middleware in the ASP.NET Core pipeline

In the previous post (Choosing the right flow(s)), we saw the differences between the various OAuth 2.0/OpenID Connect flows. In this one, we'll see how to reference the ASOS package and how to register it in the ASP.NET Core pipeline.


Referencing the OpenID Connect server middleware package

This post was updated to reflect the latest changes introduced in the 1.0.0 RTM version of ASOS.

To reference ASOS, simply add "AspNet.Security.OpenIdConnect.Server": "1.0.0" under the dependencies node of your .csproj file:

1
2
3
4
5
6
7
<Project Sdk="Microsoft.NET.Sdk.Web">

<ItemGroup>
<PackageReference Include="AspNet.Security.OpenIdConnect.Server" Version="1.0.0" />
</ItemGroup>

</Project>

Referencing the OAuth 2.0 validation middleware

You'll also need to add the validation middleware, in charge of verifying/decrypting the tokens produced by ASOS and protecting your API endpoints:

1
2
3
4
5
6
7
<Project Sdk="Microsoft.NET.Sdk.Web">

<ItemGroup>
<PackageReference Include="AspNet.Security.OAuth.Validation" Version="1.0.0" />
</ItemGroup>

</Project>

The validation middleware is similar to the JWT bearer middleware developed by the ASP.NET team but was specifically designed to use the encrypted tokens issued by ASOS and to offer a much easier experience (it doesn't require any explicit configuration by default).

Starting with ASOS beta5, JWT is no longer the default format for access tokens, but is still supported natively. To use JWT tokens instead of opaque/encrypted tokens, follow the steps below:

  • Remove the reference to AspNet.Security.OAuth.Validation in project.json.
  • Remove the validation middleware registration (app.UseOAuthValidation()),
  • Reference the Microsoft.AspNetCore.Authentication.JwtBearer package.
  • Register the JWT middleware using app.UseJwtBearerAuthentication().
  • Assign options.AccessTokenHandler = new JwtSecurityTokenHandler() to override the default format.

Registering the services required by the OpenID Connect server middleware

For ASOS to work properly, you need to register the authentication services in the DI container:

1
2
3
4
5
6
7
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication();
}
}

Register the OpenID Connect server and the validation middleware in the ASP.NET Core pipeline

Make sure to always put the validation middleware at the top of your pipeline: if the validation middleware is not at the right place, requests won't be correctly authenticated when reaching the next middleware (e.g MVC).

The same remark applies to the OpenID Connect server middleware, that must be inserted before ASP.NET Core MVC to handle authorization and logout requests correctly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// Calling app.UseOAuthValidation() will register the middleware
// in charge of validating the bearer tokens issued by ASOS.
app.UseOAuthValidation();

// Alternatively, you can also register the JWT middleware
// if you don't want to use opaque tokens (the default format).
// In this case, comment or remove the previous line.
// app.UseJwtBearerAuthentication(new JwtBearerOptions
// {
// Audience = "http://localhost:58292/",
// Authority = "http://localhost:58292/",
// RequireHttpsMetadata = false,
// });

app.UseOpenIdConnectServer(options =>
{
// Create your own authorization provider by subclassing
// the OpenIdConnectServerProvider base class.
options.Provider = new AuthorizationProvider();

// Enable the authorization and token endpoints.
options.AuthorizationEndpointPath = "/connect/authorize";
options.TokenEndpointPath = "/connect/token";

// During development, you can set AllowInsecureHttp
// to true to disable the HTTPS requirement.
options.AllowInsecureHttp = true;

// Note: uncomment this line to issue JWT tokens.
// options.AccessTokenHandler = new JwtSecurityTokenHandler();
});
}
}

Next part: Creating your own authorization provider.