Join Alexander Zanfir for an in-depth discussion in this video Auth token middleware in ASP.NET, part of Building Applications with Angular, ASP.NET Core, and Entity Framework Core.
- [Instructor] So we're sending an authorization header with the token to our backend. Let's now modify our backend to make use of that token to identify and authorize the user. So let's stop our server. And then in our startup, we'll have to do a bit of setup to get ASP.NET Core to check for an authorization header and then eventually decode it so that we can get the user from it. Below our services.AddIdentity call, let's add a new line.
We'll use services.AddAuthentication and we'll pass in some options. We'll use options.DefaultAuthenticationScheme and we'll set that to JwtBearerDefaults. And we'll use the name space aspnetcore.authentication.JwtBearer. Then we can access .AuthenticationScheme.
Next let's do the same for options.DefaultChallengeScheme. And once again, we'll set it to JwtBearerDefaults.AuthenticationScheme. Then let's chain onto the end of AddAuthentication .addJwtBearer, and we'll take in a configuration object, and we'll set cfg.RequireHttpsMetadata to false.
We'll also set cfg.SaveToken to true. And we'll set cfg.TokenValidationParameters to new TokenValidationParameters, and we'll add the name space IdentityModelTokens, and let's initialize it. We'll set issuerSigningKey the signingKey.
And we don't have that yet, so we'll need to create it above. Then we'll set ValidateAudience to false. We'll set ValidateIssuer to false, ValidateLifetime to false, as well, and ValidateIssuerSigningKey to true. I've set the audience, issuer and lifetime validation to false just so I can demonstrate the entire process of Jwt authentication working quickly.
But in a production environment, you would need to check the audience, issuer and lifetime, as those are important security features. Next, the signing key is what will allow us to encrypt the token, and so I've set the validation of the IssuerSigningKey to true. And finally, we need to then supply a signingKey. So let's go above line 43 where we call services.AddAuthentication and create that signingKey variable. And I'll set it to new SymetricSecurityKey.
And we'll pass in Encoding. And first we'll need to add the name space, system.txt. And then we can continue with .UTF8 for the format, .GetBytes, and then we'll need to pass in our signingKey phrase. This will typically need to be stored in a secured configuration document, but for the purposes of this course, I'll just hard code it to keep it simple. This is the secret phrase.
Let's save that. And then let's finish off with semi-colons on line 61 and 62. So we've added all of this configuration and setup. What does it do for us? If we go over to our quizzes controller, and we scroll down to the function that allows us to post the quiz, on line 87, we have an HttpPost decorator. Above that, let's add a new decorator called Authorize.
And let's add the name space we need for it, ASP.NET Core .authorization. And before we try this out, let's run our server. Once it loads, let's go back to our app at the home view and try to post a new quiz. We should get back a 401 Unauthorized. And if we dig deeper in the www Authenticate, we can see our error, invalid token, and that the signature is invalid.
So even though we do have a token in our local storage that's being added to the authorization header, when we created the token we never signed it. So let's go back to the backend, stop the server and take a look at what I mean. In our startup, in our configure services function, we're telling it that we want to try to decode the token using this SigningKey, but in our AccountController, when we created the token, we never signed it with the same SigningKey, or at all.
So the next step we need to do is sign it with the same key. So let's go back to startup, and copy line 44 and paste it right above where we create our jwt. Then we'll need to bring in the name space, IdentityModel tokens, and system.txt. Next we'll need to pass in signing credentials into Jwt Security Token.
So we can't pass our signingKey directly, but we'll first need to create signingCredentials. So let's create a signingCredentials variable. And we'll set it to new, signingCredentials, and we'll pass in the signingKey, and we'll specify the security algorithm as .Hmac256. And now we can pass our signingCredentials.
And the last change that we need to do in our startup is to scroll down to our configure function on line 68, and at the top we'll add app.useAuthentication. Now let's try it out. Once the server starts, let's go back to our web app, go under Application, clear the token and then we'll have to register again so that we get a new token that has the signingKey this time. Then we'll register.
We can see our token has been added. Now let's go back to the home view and add a new quiz. I'll go over to the console, so if there's any errors, we'll see them. And we'll hit Post. And instead we're seeing the response with the new quiz. So it was created. Now let's double-check this by deleting our token, going back to console and once again trying to post the quiz. We can see since we don't have the token any longer, we're getting the 401 Unauthorized.
And so our ASP.NET Core authorization middleware is working, and we're able to protect those secure resources, such as posting a quiz. We don't want anybody being able to post a quiz, just the users that have registered and have user accounts. The next thing we need to do is identify the user from their token. Let's take a look at that next.
- Creating and configuring the Angular project
- Creating forms with Angular
- Creating get and post routes in an ASP.NET Core controller
- Updating Angular service to post to API
- Persistence with Entity Framework
- Displaying and editing data in Angular with ASP.NET Core
- Navigating to different views in Angular
- Associations between entities with Angular and Entity Framework
- Setting up Identity Framework