Implementing API Key Authentication in ASP.NET Core

Поділитися
Вставка
  • Опубліковано 6 вер 2024
  • Check out my courses: dometrain.com
    Become a Patreon and get source code access: / nickchapsas
    Hello everybody I'm Nick and in this video I will show you all the approaches you can use to add API Key based authentication in you ASP.NET Core APIs. I will cover a generic approach and then Controller and Minimal API specific approaches and also show you how you can add Open API support for Swagger.
    Workshops: bit.ly/nickwor...
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: bit.ly/ChapsasG...
    Follow me on Twitter: bit.ly/ChapsasT...
    Connect on LinkedIn: bit.ly/ChapsasL...
    Keep coding merch: keepcoding.shop
    #csharp #dotnet

КОМЕНТАРІ • 136

  • @facephonesy
    @facephonesy Рік тому +65

    I love your videos, you are so professional, but i would really love and appreciate if you make a small app, that shows us how yo implement all the best practices you teach us, I mean I learn tbd concept from you, and I always go and implement it in my projects, but sometimes I get lost in the implementation. If you can just do a todo list api, with all the consepts, like rest API rules, versioning, SOLID, services, mapping, results, responses. Thank you very much for the great content 🙏

  • @NathanWienand
    @NathanWienand Рік тому +69

    Hi Nick I love your videos so very much!
    *Hint* You probably already know this, but rather than using the Generate Guid tool (which means moving hand to mouse etc.) you can just type "nguid [tab]" and Rider will allow you to insert a new guid and even select the version without dashes. :) Keep up the great work mate!

    • @nickchapsas
      @nickchapsas  Рік тому +45

      I DIDNT KNOW THAT OH MY GOD THATS SO COOL!!!

    • @ivcbusinesssystems6613
      @ivcbusinesssystems6613 Рік тому

      Wait... WHAT???
      I need to try Rider ASAP!

    • @ArnoldNelisse
      @ArnoldNelisse Рік тому +11

      This also works with JetBrains Resharper in Visual Studio.

    • @victor_pogor
      @victor_pogor Рік тому

      Thanks, didn't know about this 😉

    • @michalkowalik89
      @michalkowalik89 Рік тому +3

      @@nickchapsas `!apiKey.Equals(expectedApiKey)`. This is prone to timing-attack. Secrets should be compared in constant time.

  • @ryanobray1
    @ryanobray1 Рік тому +16

    I would love to see examples using OAuth 2 Client Credentials flow (using an IDP service like Okta or Auth0) where the APIs accept a valid bearer token.

  • @voliansky
    @voliansky Рік тому +19

    Thanks for the awesome video.
    Would be very interesting to see JWT Bearer auth with refresh tokens as well.

    • @rafekemmis3097
      @rafekemmis3097 Рік тому +5

      Agreed. Would be nice to see best approaches to implement OIDC or just oauth.

    • @thibaudgallanddemanneville174
      @thibaudgallanddemanneville174 Рік тому +1

      There already is a video from Nick about it here ua-cam.com/video/M6AkbBaDGJE/v-deo.html

    • @justingerber8077
      @justingerber8077 Рік тому

      Yeah! And how would you protect against a replay attack? Or is it even necessary to worry about this?

  • @takeshi_taro
    @takeshi_taro Рік тому +9

    To get rid of [ServiceFilter(typeof(...)] thing you can derive from ServiceFilterAttribute and provide default ctor with :base (typeof(ApiKeyAuthFilterImpl)). Then you can use your filter directly (ApiKeyAuthFilterImpl is actual implementation of filter, must be registered in DI container)

    • @nickchapsas
      @nickchapsas  Рік тому +4

      Good suggestion! For the longest time I thought the attribute was sealed, but you are right, it isn't!

  • @stephenmiller1396
    @stephenmiller1396 Рік тому +5

    Id love to see example of storing multiple API Keys in database and comparing the header key to those in the database. I have a scenario where I will have multiple clients using the API and would like to have a different API Key to give them access to their own data. Great video !

  • @amandasanti8203
    @amandasanti8203 11 місяців тому +3

    To get around the dependency injection problem you can create a custom attribute that extends from TypeFilterAttribute, which then passes typeof(MyFilter) to the base constructor. From there the system will allow you to use DI in your filter.

    • @stefano_schmidt
      @stefano_schmidt 10 місяців тому +1

      public class FooAttribute : TypeFilterAttribute
      {
      public FooAttribute() : base(typeof(FooFilter)) { }
      private class FooFilter : IActionFilter
      {
      private readonly IConfiguration _config;
      public FooFilter(IConfiguration config) // inject anything here
      {
      _config = config;
      }
      public void OnActionExecuting(ActionExecutingContext context) { ... }
      public void OnActionExecuted(ActionExecutedContext context) { ... }
      }
      }
      And now you can apply [FooAttribute] to anything and have, for example, IActionFilter with Dependency Injection

  • @MeerHussainAbrar
    @MeerHussainAbrar 2 місяці тому

    Thank you Nick! This video greatly helped me. You covered all aspects, including the Swagger which I was struggling with. Thank you 🙏

  • @MaiconLLoti
    @MaiconLLoti Рік тому

    i always copy/paste some example from the internet and i never stop to think how it works because the explanation is almost always just technical terms and blah blah hard to understand
    your explanation is without a doubt simple, objective and easy to understand, thank you very much

  • @onmico
    @onmico Рік тому +1

    Great video Nick, as always! A tip to others: the same principal can be used to enforce client certificate based auth, minus the Swagger UI integration. This way, you can easily enforce different types of auth on different scopes within the same API.

  • @johnsitka
    @johnsitka 11 місяців тому

    Great help, exactly what I needed. Thanks tons. Since adopting Blazor Server then finding Minimal API's I can now build Api's without MVC "and" secure them. I remember first hearing of WebSocket so many years ago, throw in Entra, Microsoft Graph, and Application Proxy we now have flying cars for the enterprise.

  • @linhvuquach
    @linhvuquach 5 місяців тому

    Extremely interested in the way you presented and covered different approaches. Thanks bro

  • @juliansegura5507
    @juliansegura5507 Рік тому +1

    I finally can understand this concept to it's fullest. Thanx for the great content

  • @RonyFayyad
    @RonyFayyad 8 місяців тому

    This is exactly what I was lookinf for to use in my current project. Well done on providing such great content; clean, concise and easy to follow.

  • @ecitahpi385
    @ecitahpi385 Рік тому

    the longest app. 18 minutes in my life :D thank you for the explanation!

  • @19balazs86
    @19balazs86 Рік тому +3

    Hi Nick, thanks for the video, good content as usual! You mentioned the attribute usage and DI issue. ApiKeyAuthFilter class can be as it is but creating a new attribute, makes it work.
    public class ApiKeyAuthFilterAttribute : ServiceFilterAttribute {
    public ApiKeyAuthFilterAttribute() : base(typeof(ApiKeyAuthFilter)) { }
    }
    services.AddScoped();

  • @thibaudgallanddemanneville174
    @thibaudgallanddemanneville174 Рік тому +6

    Thanks Nick for the video, awesome as usual !
    What is your thought about `AddScheme` and `AuthenticationHandler` ? or the `AddAuthorization` and `AddPolicy` ?

    • @nickchapsas
      @nickchapsas  Рік тому +2

      It's a bit of a more convoluted approach which is why I prefer the ones that I show in the video. They are way more straightfoward.

    • @thibaudgallanddemanneville174
      @thibaudgallanddemanneville174 Рік тому

      I agree with you, I had a hard time implementing them ^^

    • @benjaminboyle3295
      @benjaminboyle3295 Рік тому +3

      Hi Nick, I had to add mixed authorization: Bearer header as well as ApiKey header. I did it using the methods mentioned in the comment above. I have source code if you wanna see it. I was actually hoping this video would show us a better way of adding mixed authorization. Thank you as always, amazing work.

    • @benjaminboyle3295
      @benjaminboyle3295 Рік тому

      AND then I had to mix in jwt/bearer authorization for signalR in the query string instead of header :)

    • @nickchapsas
      @nickchapsas  Рік тому +3

      @@benjaminboyle3295 This video is exclusive to API Key authentication as the name implies. I've covered mixed auth in the past. It might be something I re-visit in the future

  • @broadshare
    @broadshare 3 місяці тому

    Thank you, very useful auth concept. Was just looking for something like it

  • @alejomunoz12
    @alejomunoz12 4 місяці тому

    This help me a lot, very well explained. Thank you !

  • @jeffnikelson5824
    @jeffnikelson5824 Рік тому +1

    one of your best videos so far 👌🏻

  • @mezoughmed
    @mezoughmed 6 місяців тому

    You saved me hours of training,
    Thank you very much for your hard work

  • @cdarrigo
    @cdarrigo Рік тому +2

    Please do a video on task ConfigureAwait(). It's so confusing

  • @Any1SL
    @Any1SL Рік тому +1

    Would love a video on building a throttle mechanism where its not waiting in memory but in a queue or database

  • @MatteoTrapani
    @MatteoTrapani Рік тому +1

    Hi Nick! First of all thank you very much for your videos! They are soooo interesting and you actually taught me a lot since when I started following you :D
    I have a question about this approach: why yoi didn't mention the AuthenticationHandler approach?

  • @carstenberggreen7509
    @carstenberggreen7509 Рік тому

    Tak! Brilliant video! Covers all my thoughts and questions about API Keys in one video!

  • @TheAproeX
    @TheAproeX Рік тому +2

    damn nice timing, Milan Jovanovixc released video on the same topic few days ago :D

    • @nickchapsas
      @nickchapsas  Рік тому

      Oh did he? Nice! I don't follow him so I wouldn't know, I plan my videos weeks in advance.

  • @OlleHellman
    @OlleHellman Рік тому +1

    Thank you for the simple to follow exampesl!

  • @lucasdiasfrota
    @lucasdiasfrota Місяць тому

    a lot of good tips =) Thanks Nick!

  • @margosdesarian
    @margosdesarian Рік тому

    Hi Nick, i love your videos - and this is one is especially great. In this short video you have explained so many things in a clear and concise way. Its great!!

  • @barry-deanmartin988
    @barry-deanmartin988 6 місяців тому

    Awesome video, thanks. very useful & just what I was looking for.

  • @JacobDuenke
    @JacobDuenke Рік тому +1

    Am I crazy? I’ve always found the swagger ui has the lock icons mixed up. Why would the lock be LOCKED when the api is unlocked and authorized for use??

  • @DemoBytom
    @DemoBytom Рік тому +2

    What is a good place to store secrets (like API keys etc) for on-premise services, hosted on IIS, that don't have access to any cloud solutions, like Azure/AWS key vaults?

    • @kirylkorzun3568
      @kirylkorzun3568 Рік тому

      Briefly: any separate server within your org network, data center, etc but you have to provide security, access control, physical security,etc
      Hope it will help! :)

    • @RusWatcher
      @RusWatcher Рік тому

      have you found somewhere the answer? can you share this?

  • @SilasPeters
    @SilasPeters Рік тому

    This was exactly what I needed. Now maze makes way more sense!

  • @nanvlad
    @nanvlad Рік тому +1

    This video is a gem!

  • @bogdanb904
    @bogdanb904 Рік тому

    You could also have a class extending ServiceFilterAttribute so you can have DI in you Authorization Filter.

  • @alef.carlos
    @alef.carlos Рік тому +1

    Thats awesome! But what about implemeting an AuthenticationHandler for ApiKey scheme and then register that in AuthenticationBuilder ? I think AuthenticationHandler is the best option.

    • @nickchapsas
      @nickchapsas  Рік тому

      It’s the most convoluted option for something that can be as simple as shown in the video. I don’t like that approach for this use case

  • @blackpaw29
    @blackpaw29 11 місяців тому

    Thank you, very interesting and easy to implement with your clear details. Looks appropriate for a use case I have.
    Couple of questions 😁
    - Can you safely mix auth schemes, i.e I have a multi-tenant minimal api that users authenticate to via Azure B2C oauth2, but I need to add a simple API key access for a few endpoints, for service apps to use. I could use client credentials flow or application api's, but there's the problem of distributing/revoking api keys and I want to issue them dynamically depending on the tenant the service apps belong to.
    - Can you restrict access to a SignalR server using these?
    - Swagger - can it handle multiple auth schemes?

    • @blackpaw29
      @blackpaw29 11 місяців тому

      To answer part of my own question - yup, Swagger UI can handle multiple auth types, you get the option to choose which one when Autherising. Works the best. And you can mix auth schemes.

  • @sunilanthony17
    @sunilanthony17 Рік тому

    Nick, at times I just think you're reading my mind. I was just building this out for work and needed a refresh because I haven't done it in a while.

  • @OgamerRato
    @OgamerRato 2 місяці тому

    Helped a loot, thank you. Gona subscribe to your channel. Nice work!

  • @Skillamu
    @Skillamu Рік тому

    Very good and detailed explination on this topic, great video!

  • @GachiMayhem
    @GachiMayhem Рік тому +1

    Great video! Thank you very much, Nick!
    Could you please tell us about cases where 2 authentication schemes are used at the same time, for example ApiKey together with JWT. For example a case where I have 2 clients for my API, a web app and a mobile app. How to properly design the api in such a case?

  • @BK-19
    @BK-19 Рік тому

    Nick You are .Net Rockstar! Thank you!

  • @Lazzerman42
    @Lazzerman42 Рік тому

    Fantastic! Thank you! Clear and precise! Very Good!

  • @kaymeister634
    @kaymeister634 Рік тому

    Great video! Thanks a lot for your efforts, Nick! You're great

  • @TheJohndward01
    @TheJohndward01 Рік тому

    Amazing video! I always learn so much from your content 😎👍

  • @stripfood
    @stripfood Рік тому

    thank you we love you

  • @aarongregory1806
    @aarongregory1806 Рік тому

    Awesome video as always Nick!

  • @microtech2448
    @microtech2448 Рік тому

    Hi, can you come up with a vidwo where you can demonstrate how to Authorize same endpoint using either inbuilt jwt bearer or api key at the same time? So,how we can add custom authentication along with inbuilt authentication schemes and regiater at startup. Thanks

  • @antoniobuyukliev923
    @antoniobuyukliev923 11 місяців тому

    Hi Nick, appreciate the work you do. One question about the filter of the minimal api. If we have another middleware the request stops first in it and then into the filter?

  • @shehansamarasinghe3497
    @shehansamarasinghe3497 10 місяців тому

    Great video. Superb content. Thank you !!!

  • @jerryjeremy4038
    @jerryjeremy4038 Рік тому

    Thanks Nick, i need this

  • @cagrikolsuz7727
    @cagrikolsuz7727 Рік тому

    That's great explanation. Thanks.

  • @bolajibello8917
    @bolajibello8917 Рік тому

    Great job as always. Thanks dude

  • @veracsthedefiled
    @veracsthedefiled Рік тому

    I was hoping to use api keys with Identity framework, I recall seeing your .NET core 2 & 3 playlist, and in comments section there you said we can look up the API key to find which user it belongs to, while that can work I think it will conflict with JWT auth since its configured as a filter, and [Authorize] attributes won't work with API keys, and as well as I think looking up the DB on every request is expensive.

  • @nebomusic2024
    @nebomusic2024 Рік тому

    This was awesome, thanks Nick!
    Just wondering, is there a reason for not using the IMiddleware interface when implementing the ApiKeyAuthMiddleware class?

  • @MusicaX79
    @MusicaX79 Рік тому +1

    This breaks swagger documentation.

  • @salvcri
    @salvcri Рік тому

    Always great!!!!

  • @adR9990
    @adR9990 Рік тому

    Love your work!

  • @daa82
    @daa82 Рік тому

    Can you make a video on best ways to do data authorization? i.e. how do I make sure user x has only access to New York weather?

  • @AegirAexx
    @AegirAexx Рік тому

    Brilliant, thanks!

  • @diamondkingdiamond6289
    @diamondkingdiamond6289 4 місяці тому

    But wouldn't that make a timing attack possible because you are just comparing the two strings without doing any hashing.

  • @alirezaarttam3344
    @alirezaarttam3344 Рік тому

    Thanks ❤

  • @mertboii3
    @mertboii3 Рік тому

    thanks

  • @majmicky
    @majmicky Рік тому

    Hi Nick
    Amazing video, I have a question about minimal api swagger authorize button option
    How to pass different keys with the same button
    I have bearer token some set of endpoint allowed with one token and other set of endpoints use another type of token.
    How can we address it so Authorise button worked
    Thank you

  • @yogeshkajala4170
    @yogeshkajala4170 Рік тому

    Hi Nick, that is very nice. Just a quick thought about how can I separate consumers(apps), like I want to have separate api key for each app trying to use api. Quick thought is to include app name along with key, I grab the app name and check the key. Any batter way?

  • @miatribe
    @miatribe Рік тому

    Great video! thank you.

  • @yoanashih761
    @yoanashih761 Рік тому

    Thanks Nick. Is JWT token a good choice if I want to use dynamic key approach or there are some other better ways to do so?

  • @feefifofum6383
    @feefifofum6383 Рік тому

    You mentioned at the start about extending this to handle dynamic keys and rate limiting. How and where would you handle rate limiting per key? Love your work.

    • @nickchapsas
      @nickchapsas  Рік тому +1

      There is actually a new rate limiting feature now built into ASP .NET Core. You can use the API key as the rate limit key and it's basically done.

  • @jephrennaicker4584
    @jephrennaicker4584 Рік тому

    broooo,! so cool!

  • @Livinghighandwise
    @Livinghighandwise Рік тому

    In your example, once the APIKeyMiddleware - public async Task method runs, and authentication is successful, it doesn't redirect to my Homecontroller in order to run the my Post method and continue with the request. How do I get it to direct to my post request in my Homecontroller?

  • @johnanderson350
    @johnanderson350 Рік тому

    I wonder is it possible the have the Authorization Filter attribute on the class level, but then override that with another Authorization Filter at the method level. That was by default the methods are safe, unless otherwise indicated.
    I know you can set Filter orders but they still both get fired.

  • @oyedeoluwafunbi9635
    @oyedeoluwafunbi9635 Рік тому

    Great Video!!!!!!!!

  • @hueseyinguendogan8541
    @hueseyinguendogan8541 Рік тому

    Great!

  • @adilbangush5014
    @adilbangush5014 Рік тому

    what is the best practice for custom error to display ( custom description , custom error-code ) in minimal API despite just use 401.

  • @dasmaffin1633
    @dasmaffin1633 Рік тому

    So if I have an app that connects to thousands of users authentication is something I dont need, did I get that right?

  • @tonykidv2
    @tonykidv2 Рік тому

    is it possible to use [AllowAnonymous] annotation to bypass the middleware?

  • @Rider0fBuffalo
    @Rider0fBuffalo Рік тому

    @11:20 can the Configuration not be injected here using the [FromServices] attribute on the IConfiguration contstuctor parameter? Or are Service Filters not built the same way Actions/Controllers are?

  • @rguere
    @rguere Рік тому

    excelente video

  • @ArnonDanon
    @ArnonDanon Рік тому

    Great video as usal, how would you go about rotating the key to thw customer, or even provide an new one securly, is there a solution already created for it?

    • @synysterdemon
      @synysterdemon Рік тому

      Personnally, I would turn that `ApiKey` setting to `ApiKeys` as an array, so when you want to rotate, you add the new API key, then you replace the old one in all the places it is used and at the end, you come back and remove the old API key from your service, invalidating it.

    • @nickchapsas
      @nickchapsas  Рік тому +1

      There is actually yeah. You can use something aws secrets manage which supports rotation and versioning so both keys are supported from a single variable. I talk about that in my free aws course

    • @ArnonDanon
      @ArnonDanon Рік тому

      @@nickchapsas guess i still havent got to this part at the course yet ... great courses both aws and the Integration tests by the way 👏🏽👏🏽👏🏽

  • @parcanapp1193
    @parcanapp1193 Рік тому

    Are you a factory that makes videos? I only now finished watching your previous one.

  • @bizneslupa3629
    @bizneslupa3629 Рік тому

    can you give us the book name or tutorial where did you learn this all?

  • @andrewholloway-breward213
    @andrewholloway-breward213 Рік тому

    Should these techniques work in the same way for Azure function triggered by HTTP or is this completely different?

  • @funkykoval78
    @funkykoval78 Рік тому

    does this solution intentionaly do not work?
    so you need to become patreon to see it works? or am I missing something.
    ''ApiKeyAuthMiddleware" is a type, which is not valid in the given context
    is what I get

  • @oM1naE
    @oM1naE Рік тому

    Is there a specific reason to not implement IMiddleware interface?

  • @pbreslinltd
    @pbreslinltd Рік тому

    Nick, I purchased your zero to hero minimal API course... the discord link is broken.... is that a mistake or did you shut it down?

    • @nickchapsas
      @nickchapsas  Рік тому

      The Discord server is being restructured so for now no new people can join. It will be relaunched and all course owners will be notified.

  • @doganyldrm5960
    @doganyldrm5960 4 місяці тому

    Hi sir. Firstly your videos are very helpfulll for us. By the way can you give me your source code pleace...

  • @hyipinvestorkhmer8226
    @hyipinvestorkhmer8226 Рік тому

    how to use AllowAnonymous?

    • @Tr00per0815
      @Tr00per0815 5 місяців тому

      var actionAttributes = context.ActionDescriptor.EndpointMetadata;
      if(actionAttributes.Any(x => x is AllowAnonymousAttribute))...

  • @alonsourena_
    @alonsourena_ Рік тому

    I was looking for the second approach, so sad 😂😂😂

  • @TechySpeaking
    @TechySpeaking Рік тому +1

    First

  • @bastabro
    @bastabro Рік тому

    Not a fucking clue, but very interesting

  • @user-bz8gp2uv8d
    @user-bz8gp2uv8d Рік тому

    This video is difficult to understand and video editing is inconsistent with the content..

  • @10Totti
    @10Totti Рік тому +2

    Your videos are great, but you speak too fast for non-native speakers :)

  • @simplegameplay1469
    @simplegameplay1469 Рік тому

    OMG asp net core si solo cool 🥹🥹