Setting up an Authorization Server with OpenIddict - Part V - OpenID Connect
Tags: dotnet, oauth2, openiddict, aspnet
Published: 2020-12-11 13:14:04

> This article is part of a series called **Setting up an Authorization Server with OpenIddict**. The articles in this series will guide you through the process of setting up an OAuth2 + OpenID Connect authorization server on the the [ASPNET Core](https://dotnet.microsoft.com/apps/aspnet) platform using [OpenIddict](https://github.com/openiddict/openiddict-core).

- [Part I: Introduction](https://dev.to/robinvanderknaap/setting-up-an-authorization-server-with-openiddict-part-i-introduction-4jid)
- [Part II: Create ASPNET project](https://dev.to/robinvanderknaap/setting-up-an-authorization-server-with-openiddict-part-ii-create-aspnet-project-4949)
- [Part III: Client Credentials Flow](https://dev.to/robinvanderknaap/setting-up-an-authorization-server-with-openiddict-part-iii-client-credentials-flow-55lp)
- [Part IV: Authorization Code Flow](https://dev.to/robinvanderknaap/setting-up-an-authorization-server-with-openiddict-part-iv-authorization-code-flow-3eh8)
- **Part V: OpenID Connect**
- [Part VI: Refresh tokens](https://dev.to/robinvanderknaap/setting-up-an-authorization-server-with-openiddict-part-vi-refresh-tokens-5669)

{% github robinvanderknaap/authorization-server-openiddict no-readme %}

---
OpenIddict implements the OpenID Connect protocol, which is an identity layer on top of the OAuth2 protocol. 
The implementation of the OpenID Connect protocol issues an extra token to the client application, called the `identity token`. This token contains user profile information which can be used by client applications to identify the end-user.

[It's wise to keep your tokens small](https://leastprivilege.com/2016/12/14/optimizing-identity-tokens-for-size/). Therefore, the OpenID Connect protocol offers the possibility to expose an userinfo endpoint from which clients can retrieve extra information about the end-user which is not stored in the identity token.

In this part we will see how to leverage the OpenID Connect protocol and how to add an endpoint for querying extra user information.

## Enable OpenID Connect
As said, OpenIddict has implemented the OpenID Connect protocol. You can test this by requesting an extra scope called `openid` with Postman:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/j51cb90e7fft92k38xvh.png)

In the response you will find an identity token together with the access token.

To store extra profile information in the identity token, you can add claims in the `Authorize` method in the `AuthorizationController` when using the authorization code flow or add claims in the token endpoint if you are using the client credentials flow. Make sure to set the destination to `IdentityToken`. Here's an example using a default claim called `email`:

``` csharp
public async Task<IActionResult> Authorize()
{
    ...

    var claims = new List<Claim>
    {
        // 'subject' claim which is required
        new Claim(OpenIddictConstants.Claims.Subject, result.Principal.Identity.Name),
        new Claim("some claim", "some value").SetDestinations(OpenIddictConstants.Destinations.AccessToken),
        new Claim(OpenIddictConstants.Claims.Email, "some@email").SetDestinations(OpenIddictConstants.Destinations.IdentityToken)
    };
    
    ...
}
```

It is also possible for a claim to have multiple destinations, so we can add a claim to the access token and the identity token if we want.

You can view the content of the identity token on [jwt.io](https://jwt.io):

``` json
{
  "sub": "Robin van der Knaap",
  "email": "some@email",
  "oi_au_id": "e5e12b78-ddea-42df-8350-5b7bda36b07b",
  "azp": "postman",
  "at_hash": "iuzdujyas1p_1XjUuxtw9A",
  "oi_tkn_id": "7f0ae652-c997-4425-bda5-6d024ea3acb3",
  "aud": "postman",
  "exp": 1607684956,
  "iss": "https://localhost:5001/",
  "iat": 1607683756
}
```

## Userinfo endpoint
Besides the identity token, the OpenID Connect protocols also allows for an url to get information about the user. To leverage the userinfo endpoint, we need to enable the endpoint and set the url in `Startup.cs` first:

``` csharp
options
    .SetAuthorizationEndpointUris("/connect/authorize")
    .SetTokenEndpointUris("/connect/token")
    .SetUserinfoEndpointUris("/connect/userinfo");

options
    .UseAspNetCore()
    .EnableTokenEndpointPassthrough()
    .EnableAuthorizationEndpointPassthrough()
    .EnableUserinfoEndpointPassthrough();
```

Now if you restart the authorization server and navigate to [https://localhost:5001/.well-known/openid-configuration](https://localhost:5001/.well-known/openid-configuration). You will see that the userinfo endpoint is added to public configuration file:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/owh28639ry3i7mni27oj.png)

Next step is to implement the userinfo endpoint. We can decide for ourselves which user info we want to share with clients. We will add the method to the `AuthorizationController`:

``` csharp
[Authorize(AuthenticationSchemes = OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)]
[HttpGet("~/connect/userinfo")]
public async Task<IActionResult> Userinfo()
{
    var claimsPrincipal = (await HttpContext.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)).Principal;

    return Ok(new
    {
        Name = claimsPrincipal.GetClaim(OpenIddictConstants.Claims.Subject),
        Occupation = "Developer",
        Age = 43
    });
}
```

The user info endpoint can only be accessed when the client has a valid access token. This is why we added the `Authorize` attribute. For this to work, we have to enable authorization in `Startup.cs`:

``` csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    ...
    
    app.UseAuthentication();

    app.UseAuthorization();

    ...
}
```

Now if we do a GET request to `/connect/userinfo` and use a valid access token, the response looks something like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6w7e51in6s6ib8cozty3.png)

## Next
[Next up](https://dev.to/robinvanderknaap/setting-up-an-authorization-server-with-openiddict-part-vi-refresh-tokens-5669), we will enable the usage of refresh tokens.