How To Implement API Key Authentication In ASP.NET Core

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
there are many ways to introduce authentication to an API one of the more popular approaches is using Json web tokens but today I'm going to show you how to implement API key Authentication in.net 7. so we're in the products module in our eShop application and I'm specifically looking at the post endpoint for creating a product let's say that we want to introduce authentication to this endpoint but we want to implement API key authentication so how will we go about implementing this web minimal apis you have an option to specify a filter that is going to execute around your minimal API endpoint the way that you specify that filter is by calling the add endpoint filter method you can either specify a strongly type filter by using this override or you can provide a delegate that's going to represent your filter that is going to wrap your minimal API route so let's use that approach to start out to implement this method we need to provide a delegate that takes in an endpoint filter invocation context and an endpoint filter delegate which is essentially your endpoint code and it returns an object that represents the endpoint result so let's start out by defining the delegate I'm going to say context and next and let's define the body so on the context I have access to the HTTP context of the current request and this is what we're going to use to implement API key Authentication how you actually execute the endpoint filter is you just await the next delegate execution and you pass it the end-to-end invocation context so this would be an endpoint filter that pretty much does nothing but we're going to add API key authentication logic into our endpoint filter let's actually Implement a separate class that is going to represent our endpoint filter so let's for example add a folder in the presentation project that is going to contain our authentication logic I'm going to give the folder the name of authentication and let's add a class inside that is going to represent our endpoint filter I'm going to call it API key authentication endpoint filter I'm going to implement the high endpoint filter interface and we're going to introduce Logic for authenticating our endpoint using an API key so we first have to start off by implementing the I endpoint filter interface so let's go ahead and do that and you'll notice that it only has one method inside which is the invoke async method which essentially represents a middleware around our endpoint so as I said the default implementation comes down to invoking the next delegate and returning the result of that delegate as the result of our filter so I'm going to say return await next and we're going to pass it the context so this will be creating an endpoint filter without any logic but we actually want to introduce API key authentication into this endpoint filter so I'm going to create a simple method that is going to return a Boolean value representing whether our specified API key is valid or not so I'm going to say is API key valid it's going to have an API key argument that can even be nullable for example and will take care of the null case and for the default implementation of if the API key is valid let's just return true if the API key is not empty so I'm going to say return not string is now white space and we're going to pass in the API key inside of our invokazing method I'm going to write a condition that's going to check if the API key is not valid then the authentication has failed and we're supposed to return an unauthenticated result the way you do that with minimal apis is very simple you're just going to say return results and we're going to return unauthorized and this is going to return a 401 unauthorized response to the API caller of course now we need to see how we're going to provide the API key for the validation there are many ways to provide the API key you can pass the API key as part of the query string in the request your API you can pass the API key in a cookie for example and the most common approach I've seen is passing the API key as part of a header in your request your API so that's the approach that we're going to implement inside of this endpoint filter so let's define a constant that is going going to represent the name of the header that is supposed to contain our API key so I'm going to say private cons string API key header name and we're going to give it a value of x API key so this is the name of the header which is supposed to contain our API key so now we need to figure out how we're going to get back the value for this header it's very easy to do that I'm going to create a variable that is going to contain the API key and what I'm going to do is access the context and you can see that we have access to the HTTP context value the HTTP context contains the request which is sent to our API and on the request we have access to the request headers and this is a dictionary we can access this dictionary by specifying the API key header name as the value that we want to get back and we have our API key which we can pass to the is API key valid method so this is a very simplistic approach where we are just validating that the API key exists so I'm going to make this method into an expression body and I can even make this method static for the time being because it's not accessing anything on our instance now that we have defined our API key authentication endpoint filter we need to apply it to the endpoint where we want to introduce API key authentication so I'm just going to take the name of this type and we can specify it here on the map post endpoint and we have to call the add endpoint filter method and we're going to specify our API key authentication and point filter so now when our endpoint is executed we are first going to run our endpoint filter which is going to apply our authentication logic and if that authentication logic succeeds it's going to proceed into our minimal API endpoint so let's see if this is actually working properly I prepared a post request in Postman that is going to hit our endpoint on our API to create a new product if I check out the headers that are sent to our API you can see that there are no custom headers and there are some Auto generated errors which are always sent by Postman so let's hide those and let's hit our endpoint without specifying our API key so if I hit send we're going to hit our API key authentication endpoint filter and let's see what's going on inside the first step is trying to get the value for our API key header and as you see the API key is null because we did not specify it this means that is API key valid method is going to return false and we're going to end up returning an unauthorized response from our API endpoint so I'm going to press continue and you can see in Postman that we get back our 401 unauthorized response so let's try specifying the X API key header value let's give it a value of one two three four five this is obviously just the dummy value and doesn't represent the proper API key we'll get to that in a moment so let's send this request to our API and see what's going on we again hit our API key authentication endpoint filter and this time when we try to extract the API key from the header you can see that we get back our value that we specified in Postman so now our is API key valid method is going to succeed and we're going to proceed into our endpoint as you can see here which is going to create a new product and return on 200 okay result so I'm going to press continue and let's see what we have to do next obviously checking if the API key is empty or not is not proper authentication logic so what we have to do is now check that the specified API key provided in the header of the request is actually a valid API key that we have defined in our application what we have to do is to Define our API key and store it somewhere securely this can be in some sort of secret manager this can even be in your configuration values in your application maybe in an environment variable or you can even store your API keys in the database and then validate if they exist or not I'm going to take a simple approach here and I'm going to specify the API key inside of our application settings you might be tempted to do something simple and place the API key inside of your app settings Json and I do not recommend doing this because you're going to be leaking your API key into your Source control and you don't want to do this so the way to do this is to avoid the application settings Json entirely and you're going to be using your user secrets so I'm going to say manage user secrets and this provides a way for us to safely specify secret values and development this is going to be a value that's going to be local to your machine and it won't go anywhere near Source control so there is no chance you're going to accidentally leak your secret keys so let's define a setting here that is going to represent our API key for the value of your API key you are supposed to set something that is very hard to guess a good option is maybe using a guide so I'm going to use this approach now I'm going to head back to our API key authentication endpoint filter and we need to validate our API key against the one that we defined in our secrets so I'm going to inject an instance of eye configuration and we're going to use this to read our API key so I'm going to say configuration let's inject this from The Constructor and now inside of the is API keyvalid method we're going to implement actual validation logic we can still implement the null or white space check so I'm going to say if string is now a white space API key we're going to return false and now I want to fetch the actual API key so I'm going to say actual API key to be able to access the configuration instant that I just injected we're going to have to remove static from our method and now I can say configuration get value we're going to get a string back and we're going to specify the name as API key so this is going to be the value that we get back from our configuration and I'm going to give it a null forgiving operator because our API key should never be null we can even validate this at runtime to make sure that we always specify our API key so now we just have to compare the API key provided here with our actual API key so the simplest approach would be doing something like this API key equals actual API key so now that we have implemented the sapi keyvalid method let's see how this is actually working so now if I try to specify the proper value for the X API key header and send the request again to our API we're going to hit our breakpoint extract the header value and now let's see what's going on with the validation so we extract the actual API key we compare the two values and we determined that they are equal and our validation succeeds and now we proceed to invoke our minimal API endpoint which is going to execute its own logic so this is a simple way to introduce API key authentication to your apis I mentioned that there are two more approaches to get the API key value the one I showed in this video was using a request header but you can also specify your API key inside of a cookie or inside of the query string so if you were using cookies you would say context HTTP context request and then you can access the cookies collection and try to find the one contained in your API key or if you were passing it as part of the query string you can access either the raw query string that was passed to the request or you can specify the query collection which contains key value pairs representing the query string values so this is another way to get the value for your API key passed into your request and then proceed to authenticate the user to determine if they can access your endpoint I also want to comment on the logic here that is comparing your actual API key to the one provided in the request here I was fetching the actual API key value from application settings and this would mean essentially that you only have one API key for your API now this is not typically the case usually you want to have multiple API keys for each of your clients that are accessing your apis so in that case you may want to store the API keys in a database perhaps this would also tell you which client is accessing your API allowing you to introduce some authorization logic determining if they can access a given set of data in the database the implementation would be very similar to what we have here we will just be comparing the API keys by maybe executing a database query the approach I showed you here applies to minimal apis but how would you use API key authentication if you were using controllers I'm going to show you a quick example I'm going to create a new class and I'm going to call it API key authorization filter we're going to implement the eye authorization filter interface so let's inherit from it and add the implementation and as you can see this interface has only one method which is the on authorization method so this is the simplified implementation I use the same approach where I specify the API key in request header and we just have one method here that is going to validate our API key the method accepts an HTTP context which comes from the authorization filter context we have a property to access the HTTP context and now using the HTTP context I can get the API key from the header I can also use the request services to resolve the eye configuration and get the value of our API key if we were using application settings and then we just compare the API key provided in the request to the actual API key if the authentication fails we set the context result to a new unauthorized result which is going to return for one unauthorized when somebody accesses an endpoint that is protected using the API key authorization filter now how do you actually apply this filter there are a few approaches and the simplest one would probably be to make this API key authorization filter into an attribute you would also have to decorate it with attribute usage and you probably want to rename it into an actual attribute so let's name it API key attribute to follow the convention and how we would use this is for example if we had a controller I'm going to use the products module as the example but imagine that this is a controller you can go ahead and specify the API key attribute on the controller level or if you had individual routes that you want to protect with the API key you would just specify the API key on the route level and runtime this is going to invoke the eye authorization filter which you implemented inside of the API key attribute class in this case and that's going to run the on authorization method which will execute your API key authentication logic so whether you're using this approach which uses eye authorization filter and applies more to controllers or this approach with high endpoint filters which applies more to minimal apis you can see that it's very simple to introduce API key authentication and secure your API I really hope that you enjoyed this video consider subscribing to myweekly.net newsletter the link to subscribe is going to be in the pinned comment under this video and until next time stay awesome
Info
Channel: Milan Jovanović
Views: 17,223
Rating: undefined out of 5
Keywords: api key authentication, api key authentication asp.net core, api key authentication web api c#, api key authentication postman, api key authentication vs oauth, api key authentication example, api key authentication c#, api key authentication vs jwt, api key authentication flow, api key authentication minimal apis, api key authentication controllers, api key authentication .net, api key auth, api key authentication security, api key authentication secret, user secrets, security
Id: CV6VdBR86co
Channel Id: undefined
Length: 17min 13sec (1033 seconds)
Published: Tue Feb 07 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.