Implementing API Key Authentication in ASP.NET Core

Sdílet
Vložit
  • čas přidán 8. 02. 2023
  • 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/nickworkshops
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: bit.ly/ChapsasGitHub
    Follow me on Twitter: bit.ly/ChapsasTwitter
    Connect on LinkedIn: bit.ly/ChapsasLinkedIn
    Keep coding merch: keepcoding.shop
    #csharp #dotnet

Komentáře • 134

  • @facephonesy
    @facephonesy Před rokem +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 Před rokem +68

    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  Před rokem +45

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

    • @ivcbusinesssystems6613
      @ivcbusinesssystems6613 Před rokem

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

    • @ArnoldNelisse
      @ArnoldNelisse Před rokem +10

      This also works with JetBrains Resharper in Visual Studio.

    • @victor_pogor
      @victor_pogor Před rokem

      Thanks, didn't know about this 😉

    • @michalkowalik89
      @michalkowalik89 Před rokem +3

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

  • @RonyFayyad
    @RonyFayyad Před 6 měsíci

    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.

  • @margosdesarian
    @margosdesarian Před rokem

    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!!

  • @carstenberggreen7509
    @carstenberggreen7509 Před rokem

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

  • @juliansegura5507
    @juliansegura5507 Před rokem +1

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

  • @ryanobray1
    @ryanobray1 Před rokem +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.

  • @MaiconLLoti
    @MaiconLLoti Před rokem

    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

  • @johnsitka
    @johnsitka Před 9 měsíci

    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 Před 3 měsíci

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

  • @stephenmiller1396
    @stephenmiller1396 Před rokem +4

    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 !

  • @voliansky
    @voliansky Před rokem +19

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

    • @rafekemmis3097
      @rafekemmis3097 Před rokem +5

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

    • @thibaudgallanddemanneville174
      @thibaudgallanddemanneville174 Před rokem +1

      There already is a video from Nick about it here czcams.com/video/M6AkbBaDGJE/video.html

    • @justingerber8077
      @justingerber8077 Před rokem

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

  • @ecitahpi385
    @ecitahpi385 Před rokem

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

  • @onmico
    @onmico Před rokem +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.

  • @aarongregory1806
    @aarongregory1806 Před rokem

    Awesome video as always Nick!

  • @kaymeister634
    @kaymeister634 Před rokem

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

  • @alejomunoz12
    @alejomunoz12 Před 2 měsíci

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

  • @Lazzerman42
    @Lazzerman42 Před rokem

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

  • @jeffnikelson5824
    @jeffnikelson5824 Před rokem +1

    one of your best videos so far 👌🏻

  • @mohdz8374
    @mohdz8374 Před 3 měsíci

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

  • @broadshare
    @broadshare Před měsícem

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

  • @TheJohndward01
    @TheJohndward01 Před rokem

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

  • @barry-deanmartin988
    @barry-deanmartin988 Před 4 měsíci

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

  • @Skillamu
    @Skillamu Před 10 měsíci

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

  • @OlleHellman
    @OlleHellman Před rokem +1

    Thank you for the simple to follow exampesl!

  • @SilasPeters
    @SilasPeters Před rokem

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

  • @nanvlad
    @nanvlad Před rokem +1

    This video is a gem!

  • @BK-19
    @BK-19 Před rokem

    Nick You are .Net Rockstar! Thank you!

  • @shehansamarasinghe3497
    @shehansamarasinghe3497 Před 8 měsíci

    Great video. Superb content. Thank you !!!

  • @cagrikolsuz7727
    @cagrikolsuz7727 Před rokem

    That's great explanation. Thanks.

  • @adR9990
    @adR9990 Před rokem

    Love your work!

  • @jerryjeremy4038
    @jerryjeremy4038 Před rokem

    Thanks Nick, i need this

  • @amandasanti8203
    @amandasanti8203 Před 9 měsíci +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 Před 8 měsíci +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

  • @takeshi_taro
    @takeshi_taro Před rokem +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  Před rokem +4

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

  • @salvcri
    @salvcri Před rokem

    Always great!!!!

  • @OgamerRato
    @OgamerRato Před 3 dny

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

  • @MatteoTrapani
    @MatteoTrapani Před rokem +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?

  • @miatribe
    @miatribe Před rokem

    Great video! thank you.

  • @19balazs86
    @19balazs86 Před rokem +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();

  • @AegirAexx
    @AegirAexx Před rokem

    Brilliant, thanks!

  • @sunilanthony17
    @sunilanthony17 Před rokem

    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.

  • @TheAproeX
    @TheAproeX Před rokem +2

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

    • @nickchapsas
      @nickchapsas  Před rokem

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

  • @oyedeoluwafunbi9635
    @oyedeoluwafunbi9635 Před rokem

    Great Video!!!!!!!!

  • @stripfood
    @stripfood Před rokem

    thank you we love you

  • @Any1SL
    @Any1SL Před rokem +1

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

  • @bogdanb904
    @bogdanb904 Před rokem

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

  • @jephrennaicker4584
    @jephrennaicker4584 Před 11 měsíci

    broooo,! so cool!

  • @rguere
    @rguere Před rokem

    excelente video

  • @antoniobuyukliev923
    @antoniobuyukliev923 Před 9 měsíci

    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?

  • @GachiMayhem
    @GachiMayhem Před rokem +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?

  • @alirezaarttam3344
    @alirezaarttam3344 Před 11 měsíci

    Thanks ❤

  • @florin84
    @florin84 Před rokem

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

  • @cdarrigo
    @cdarrigo Před rokem +2

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

  • @hueseyinguendogan8541

    Great!

  • @yoanashih761
    @yoanashih761 Před rokem

    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?

  • @mertboii3
    @mertboii3 Před rokem

    thanks

  • @veracsthedefiled
    @veracsthedefiled Před rokem

    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.

  • @thibaudgallanddemanneville174

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

    • @nickchapsas
      @nickchapsas  Před rokem +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 Před rokem

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

    • @benjaminboyle3295
      @benjaminboyle3295 Před rokem +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 Před rokem

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

    • @nickchapsas
      @nickchapsas  Před rokem +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

  • @MusicaX79
    @MusicaX79 Před rokem +1

    This breaks swagger documentation.

  • @blackpaw29
    @blackpaw29 Před 9 měsíci

    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 Před 9 měsíci

      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.

  • @yogeshkajala4170
    @yogeshkajala4170 Před rokem

    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?

  • @JacobDuenke
    @JacobDuenke Před rokem +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??

  • @adilbangush5014
    @adilbangush5014 Před rokem

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

  • @microtech2448
    @microtech2448 Před 9 měsíci

    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

  • @majmicky
    @majmicky Před rokem

    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

  • @daa82
    @daa82 Před rokem

    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?

  • @Rider0fBuffalo
    @Rider0fBuffalo Před rokem

    @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?

  • @feefifofum6383
    @feefifofum6383 Před rokem

    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  Před rokem +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.

  • @DemoBytom
    @DemoBytom Před rokem +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 Před rokem

      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 Před rokem

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

  • @tonykidv2
    @tonykidv2 Před rokem

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

  • @johnanderson350
    @johnanderson350 Před rokem

    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.

  • @alef.carlos
    @alef.carlos Před rokem +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  Před rokem

      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

  • @ArnonDanon
    @ArnonDanon Před rokem

    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 Před rokem

      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  Před rokem +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 Před rokem

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

  • @Livinghighandwise
    @Livinghighandwise Před rokem

    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?

  • @parcanapp1193
    @parcanapp1193 Před rokem

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

  • @diamondkingdiamond6289
    @diamondkingdiamond6289 Před 2 měsíci

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

  • @andrewholloway-breward213

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

  • @dasmaffin1633
    @dasmaffin1633 Před rokem

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

  • @bizneslupa3629
    @bizneslupa3629 Před rokem

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

  • @oM1naE
    @oM1naE Před rokem

    Is there a specific reason to not implement IMiddleware interface?

  • @funkykoval78
    @funkykoval78 Před rokem

    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

  • @doganyldrm5960
    @doganyldrm5960 Před měsícem

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

  • @alonsourena_
    @alonsourena_ Před 10 měsíci

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

  • @pbreslinltd
    @pbreslinltd Před rokem

    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  Před rokem

      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.

  • @hyipinvestorkhmer8226
    @hyipinvestorkhmer8226 Před 10 měsíci

    how to use AllowAnonymous?

    • @Tr00per0815
      @Tr00per0815 Před 3 měsíci

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

  • @TechySpeaking
    @TechySpeaking Před rokem +1

    First

  • @bastabro
    @bastabro Před rokem

    Not a fucking clue, but very interesting

  • @10Totti
    @10Totti Před rokem +2

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

  • @user-bz8gp2uv8d
    @user-bz8gp2uv8d Před 10 měsíci

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

  • @simplegameplay1469
    @simplegameplay1469 Před rokem

    OMG asp net core si solo cool 🥹🥹

  • @bolajibello8917
    @bolajibello8917 Před rokem

    Great job as always. Thanks dude