Secure APIs with FastAPI and the Microsoft Identity Platform Transcripts
Chapter: Web and headless clients
Lecture: Demo: ASP.NET Core web app consuming a FastAPI API
0:00 In this module will go through the steps necessary to build a web app against signing
0:06 users and securely call our fast API for the Web app we will use asp net core with .net7 .net is an open source cross platform framework by
0:17 Microsoft that allows you to write code that runs everywhere. asp.net is the web component of the web framework like Django and fast API
0:25 R for Python. However, the principles of this module should apply to any web app running on a server like java or
0:34 node.js. So here we have a browser that loads or calls a web application that can call one or multiple API.
0:41 And in our scenario, the web application will be calling our weather fast API as always. We will start with the Azure Active directory,
0:49 navigate to the Azure Active directory portal via aad.portal.azure.com And go to the app registration tab. This will be under Azure Active directory.
0:59 App registrations. And here we want to create a new App registration. We will name it FastAPI as web app and we'll leave everything else as
1:08 default and click register at this point we might want to copy client id and tenant id as we call them. So there will be somewhere handy client Id
1:17 tenant id. Always useful to have them lying around and now we want to navigate the authentication
1:24 because this is how we are going to configure our web app to receive incoming tokens
1:29 Once the user authenticate, we'll start with adding a platform and this time we're
1:33 using web and for the redirected URI this is where the tokens will be received once
1:38 the user signs in successfully. And the Azure Active directory redirect users back to
1:44 the application. So this needs to match the settings in our application as well. And since its web application running on a local host .net,
1:52 usually around 5001. If not, we can change it sign in OIDC. And I will show you exactly where this setting came from. Then we have access and
2:01 ID tokens. So we'll press configure here. The next step is to look at certificates and secrets here.
2:08 We need to configure a client's secrets if you're only planning on authenticating users in your application. This step is not necessary.
2:16 However, if your web needs to get access tokens on behalf of the user, it needs to be able to authenticate against Azure Active directory that stage
2:25 Why we need a client secret? Not however, that I like our console app.
2:29 Example from the previous module. The users here need to consent in order to receive access tokens to our FastAPI. So let's create a new one.
2:38 Let's name it web app and change it to three months and click add copy the value. Put it somewhere safe so we can use it later in case you're wondering
2:49 why we don't need to configure the api permissions for FastAPI it's because the Azure Active directory allows you to have dynamic consent,
2:57 which means that you can request the access token for the resources that you need to
3:02 access at the time that you need them and therefore you don't have to pre configure
3:05 them. That allows you to be more agile and more flexible with your app registrations
3:09 as well. Now we need to create a new application through our console. .net allows you to use the cli to do so first we'll create a new
3:16 directory and we will give it a meaningful name and that will change directory to the
3:21 Python web. Let's clear this and now we can run the .net commands of .net new web app and -- auth single
3:29 Org. What this command line will do is get a new web application and add the auth template on top of it to work with Azure Active Directory.
3:38 And because we're using Azure AD and we are in a single org environment it means that we're only using one tenant to authenticate,
3:46 only uses in that tenant will be able to authenticate. That's all we have to do.
3:50 And this will spin up everything including all the dependencies that we need. The next step is to actually open this in code and see what we have.
3:57 So here we are. The first thing that we want to do is obviously remove
4:01 comments from Json. I don't know why they're there and then bring over the information that we copied it earlier. One is the way to do that is to break
4:09 everything and then we'll fix it obviously but I don't want to cook, paste too many times and will add a buy in secret and add the appropriate value
4:17 Remember how we said that the directory URI, should have the sign in OIDC. This is the setting here. That corresponds to that.
4:23 We can always change it as long as it is the same between the Azure Active directory app registration and the settings in our code.
4:31 Make sure to save this and close down. We need to update the code a little bit here.
4:36 As you can see .net has made it significantly simple to add authentication and authorization in
4:43 our code. In fact, it only takes one line of code but we also need to extend this now to say that we want to enable token acquisition for downstream
4:51 Api's and that we also need to use a token cache. This is where the web app will store the tokens once it acquires them.
4:59 And again, the nice thing about using .net with Azure Active directory is that
5:04 a lot of the complexity is obstructed for us And with one line of code we can enable quite a few things.
5:10 The enable token acquisition injects a token acquisition object in our code that will later use in our pages to acquire tokens.
5:18 But for now this is all the code that we need to add to enable the application to sign in users and acquire access tokens.
5:24 The last step in the process is to add two new files. Under pages we want to add a weather.csHTML and I will explain shortly
5:33 what this means. And we also want to add one more file under pages called weather.csHTML.cs. The first file,
5:43 the cs HTML file is the presentation layer. The second file is the server side code that corresponds to the web page.
5:50 They're tied together. Any method and objects exposed in the code can also be accessed in the web page via the model object.
5:57 When the application runs the cs HTML page is rendered to HTML So you don't see all the fluff and the code behind the scenes,
6:04 we will not add too much HTML. Markup to the front end. Just a couple of lines of code that will render our weather, Json data in raw format.
6:11 Obviously this is not how we would present the data in a real application but the goal here is just to show you how a web app is different to a non
6:19 interactive application, like a console app. First thing that we have to do is open the weather.csHTML and add a
6:24 little bit of code. First we have to start with the page directive which informs the file that this is going to be a web page And then we want to
6:31 add the model. I will correspond to the code behind the CS file and then we also need to add a nice title here view data is a temporary structure that
6:43 holds some information that we can pass around and here I want to say weather it's
6:48 weather enough finally want to have an h3 here header or sub header that presents
6:54 the data that we just pulled from the api view data and then we'll call it
6:59 weather and once we populate the subject in the code behind it should be available in
7:04 our HTML. This is complaining because obviously the weather model doesn't exist yet.
7:09 Let's create it. We're going to be a little bit lazy here and copy a few things. So here I'm going to copy all that from the index page as
7:17 the homepage of the application and then we will do some editing in the naming. So we will do hit an index model.
7:27 Want to replace with weather model. Let's go very quickly through this page and see what
7:32 we have. We have a weather model which is a page model and affected tells code that it is attached to the front end via this model object and we have
7:43 a logger that can log some things for us every .net page gets that out of the box. We're injecting the weather model here from the middle where so can
7:53 substantiate the logger don't have to create a new one every time that object gets passed via dependency injection. Finally we have an on get method.
8:00 This on get method is where we implement most of the code. This function corresponds to an HTML get action when the page loads.
8:09 When the browser makes a get request to the server, the code in this particular method executes and in the end we return the view I
8:17 the HTML back to the user inside the on get method we need to implement two things. One is to acquire a token for API and the second is
8:26 to call the fast API with the right headers. Now one of the things that we didn't capture from the Azure active directory portal is
8:34 the permission to our API So we need to go back very quickly and grab it So from app registration the fast API we need the API permission for the
8:45 weather.read or weather.right we'll copy one of them. We need to authorize or scope. It does expect an array or strings here.
8:55 We need to add what we just copied the full thing and it is authorized for scopes and now we can add the missing name,
9:03 space this in effect willforce re authentication and user consent if it hasn't been provided yet. Next we need to add our token acquisition object.
9:13 I'm happy with that at this point we have the basic components of our authorization and now we need to add the token acquisition.
9:25 So let's let's grab a token var token because yes in .net we have to say that we need to do and async because this is an efficient method but we
9:36 can await it properly get access looking for user async and in here again we need to provide our scope which should be in the form of an array.
9:47 The token is successfully acquired. Then the next step is to create an http client to call our FastAPI default headers request headers.authorization.
10:01 I will remove that, resolve the missing name space here because I like to keep it nice and clean and we'll pass the token as a bearer token.
10:10 We also want to say http client.default headers to accept add and yes we expect the media type to be Json and with that we have our http object our
10:24 response and we want to call our local host 8000 because that's where our api is running. It's under API and weather type it correctly.
10:35 And then the city proper ui will probably request the user to pass the name of the city so that we would pass it here dynamically.
10:43 But for now we will hard code it to make sure that everything is working and now from the response we want to get a content so var content = once the
10:51 content read as string async view data this is where we populate our weather object
10:59 equals content. One last thing that we need to do is because I always like to run at 5000 instead of the random or that gets assigned by .net.
11:08 I come in here and I change these two ports. I love and I'm Houston now there's the application. Let's see if our API is running.
11:16 If not we can launch it again whether API here is not running. So let's run our fast API And I'm confident now that we can run and authenticate
11:25 and roll our api from our web first attempt, let's see we can run it from the command line as well if we desire to
11:32 do so. So here we can say .net watch, which also gives us nice recompilation. If we need to do any code changes.
11:41 Okay. The application has launched it prompt us for authentication which is a good sign It means that the authentication component is working.
11:48 So we're signing in the first time that we use the application and Azure Active
11:52 Directory provides a consent framework which means that we need to consent for the application to
11:57 access our basic profile and to get a refresh token notice also here that because I'm an admin to this azure active directory tenant.
12:06 I can also concerned for everybody else and if I do that, nobody else in my organization will see this consent form.
12:12 We are signed in obviously we're not seeing any weather data yet because we haven't called it. But if we navigate to the weather page,
12:22 that will be presented with another consent form based on our consent framework.
12:27 The first time that the application is trying to access data that we haven't consented to it will always ask for consent.
12:33 This only happens once and it might never happen if your admin has already consented on
12:38 behalf of your whole organization. But it notes now that we have a new one
12:41 that says allow users to read weather data in our fast API and that's exactly what we want to do. So I'll press accept and just like that we've got our
12:50 data from our fast Api not the prettiest, but it works. It's all down to you to make it presentable to summarize this
12:57 chapter. We saw how non interactive and interactive applications can be configured to call our
13:02 Fast Api there are small nuances between them that makes them so different yet so alike.