Authorize with JWT in ASP.NET Core 3.0 Web API

Harry Hathorn
The Startup
Published in
3 min readNov 6, 2019

--

ASP.NET Core 3.0 provides native support that allows you to authorize endpoints using JSON web Tokens (JWT) i.e. without any dependency on third party packages.

After creating a new ASP.NET Core 3.0 Web API project add the following .NET core dependency:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer --version 3.0.0

i.e.

.NET Core middleware that enables an application to receive an OpenID Connect bearer token. — Microsoft

I would suggest adding some new config to your appsettings.json file

...
"Jwt": {
"Key": "12b6fb24-adb8-4ce5-aa49-79b265ebf256"
}

You may need additional config such as Issuer and Audience addresses if you wish to validate those.

Now to ‘‘start up’’ with we will need to make some changes to our Startup.cs file 😎

The DefaultAuthenticationScheme in AddAuthentication enables claims from the JWT to be assigned to the HTTPContext.User

The AddJwtBearer sets all the options that will be used for authorizing the JWT. A valid JWT will need to be created according to these options.

Next we need to use authentication and use authorization in the Configure block of the Startup.cs

With that done all that’s needed is to add an Authorize attribute to secure your controller endpoints

I have added an Authorize attribute to the whole controller to secure all the actions.

For more granular authorization to the example GetRobot() allows anonymous access while GetSmile() only allows Grandpa’s to access it.

The Grandpa role will need to be signed to the JWT role claims portion. Invalid requests to the GetSmile() or GetBurger() endpoints will respond with a 401 unauthorized.

Now let’s create a JWT that will be authorized by our API.

A JWT is composed of 3 dot delimited base64 encoded JSON parts- a Header, Payload and Signature. Here are the parts that our API will authorize:

Header

{
"alg": "HS256",
"typ": "JWT"
}

Payload
exp
is the expiration timestamp of the JWT , iat is timestamp of when the jwt was issued and nbf is a not valid before timestamp. It includes names, user info and role claims which will be grafted into the HttpContext.User Identity in our C# app.

{
"unique_name": "Harry Hathorn",
"email": "harry@domain.com",
"birthdate": "1923-12-12",
"nameid": "b006a7b8-04e3-43a7-8df5-276f5fe1e742",
"role": [
"Grandpa",
],
"nbf": 1573035014,
"exp": 1575627014,
"iat": 1573035014
}

Signature
the signature is a hash of the base 64 encoded header and payload using the secret, 🙊shhh don’t tell anyone. By default asp.net uses the HS256 hashing algorithm.

HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
"12b6fb24-adb8-4ce5-aa49-79b265ebf256"
)

I used powershell to create the token with base64 encode and HMACSHA256 hash. This can be done on http://jwt.io/ or unix commands or any other way

With that the $token is outputted as follows:

$token
>> eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IkhhcnJ5IEhhdGhvcm4iLCJlbWFpbCI6ImhhcnJ5QGRvbWFpbi5jb20iLCJiaXJ0aGRhdGUiOiIxOTIzLTEyLTEyIiwibmFtZWlkIjoiYjAwNmE3YjgtMDRlMy00M2E3LThkZjUtMjc2ZjVmZTFlNzQyIiwicm9sZSI6WyJHcmFuZHBhIl0sIm5iZiI6MTU3MzAzNTAxNCwiZXhwIjoxNTc1NjI3MDE0LCJpYXQiOjE1NzMwMzUwMTR9.ffgCAWvYs5lzDyyVsUrVI-FvOYKz80CvNk826er-jaI

We then can add the token as an Authorization header to our web request

Authorization: Bearer eyJhbGciOiJIUzI1NiIsI.....

Here is a postman example of the authorized request:

vualá

Job done. Remember that JWTS are used to authorize protected resources so be careful where you share your JWT credentials 😊

--

--