Token Authentication In ASP.NET Core 7 With JWT | Clean Architecture

Поделиться
HTML-код
  • Опубликовано: 4 ноя 2024

Комментарии • 294

  • @MilanJovanovicTech
    @MilanJovanovicTech  Год назад +39

    Get the source code for this video for FREE → the-dotnet-weekly.ck.page/jwt-auth
    Want to master Clean Architecture? Go here: bit.ly/3PupkOJ
    Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
    If you run into any issues while trying to implement this, I made two mistakes in the video:
    - At 16:00 it should be one call to `UseAuthentication` and one call to `UseAuthorization`
    - `JwtBearerOptionsSetup` should implement `IConfigureNamedOptions`

    • @zameer.vighio
      @zameer.vighio Год назад

      Milan!
      suppose we have this api having authentication & authorization as you did returning token on success login.
      now i want to consume this token in my front-end application developed using net core, which will use this token to authenticate and authorize user.
      question is how should we will implement setting for front-end application so it get logged/signin on token and authorize user accordingly and auto add token in api call header.

    • @mansaraicha8301
      @mansaraicha8301 10 месяцев назад +1

      Thank you for this great tutorial.
      could you please explain how JwtBearerOptionsSetup` should implement `IConfigureNamedOptions` ?

    • @shukhratmukhammadiev4994
      @shukhratmukhammadiev4994 10 месяцев назад

      Hey mate! Thanks for your videos!
      Would you be able to make the same video to .NET 8 version?
      Thanks in advance!

    • @YehorBachurinDev
      @YehorBachurinDev 9 месяцев назад

      Thanks for source code :)

    • @MilanJovanovicTech
      @MilanJovanovicTech  9 месяцев назад +1

      @@YehorBachurinDev You're welcome!

  • @tosunabi1664
    @tosunabi1664 Год назад +8

    Nice tutorial, especially the solution approach with options is quite pro.
    For those who try to use the example code with NET Core 7.0 will not have their JwtBearerOptions initialized thus token validation will fail.
    To solve the issue JwtBearerOptionsSetup must derive from IConfigureNamedOptions.
    JwtBearerOptionsSetup : IConfigureNamedOptions
    public void Configure(JwtBearerOptions options)
    {
    options.TokenValidationParameters = new TokenValidationParameters
    {
    ValidateIssuer = true,
    ValidIssuer = _options.Issuer,
    ...
    };
    }
    public void Configure(string? name, JwtBearerOptions options)
    => Configure(options);

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      I do believe it's noted in the pinned comment 😅

    • @tosunabi1664
      @tosunabi1664 Год назад

      @@MilanJovanovicTech I saw after posting.

    • @quanao6121
      @quanao6121 Год назад

      @tosunabi1664 thank you very much. I'm wondering I did the same in this video, I know it isn't wrong but it can't validate token. When I used IConfigureNameOptions and it worked

  • @kirwakelvinkering3122
    @kirwakelvinkering3122 Год назад +19

    What a tutorial !!!! Lacking words to describe this ,everything is professionally done !! I like the way you handle errors ,I liked the way you use DI and they way you did set up the JwtBearerOptions instance ,thanks buddy .

  • @TheBishalSaha
    @TheBishalSaha Год назад +3

    Thanks, Milan, This video helped me to integrate the JWT-based authentication in Clean Architecture. I searched a lot of articles and videos but this one is great 🚀

  • @itskills2579
    @itskills2579 Год назад +2

    One of the best tutorial I have watched so far in any topic, very clearly explain all you need , well done

  • @BSpangenberg
    @BSpangenberg 9 месяцев назад +1

    I never leave comments on videos, but this one absolutely deserves it. Great tutorial, not the average ‘just get it done’ attitude. So much effort into doing it cleanly and actually teaching proper techniques.
    Thank you.
    I’m interested in learning more on the command implementation done at 0:50 and your overall project structure and approach.
    Are the any further videos on this project?

    • @MilanJovanovicTech
      @MilanJovanovicTech  9 месяцев назад

      I talk about CQRS often:
      - ruclips.net/video/vdi-p9StmG0/видео.html
      - ruclips.net/video/85YbMEb1qkQ/видео.html
      You can search for "cqrs" on my channel, a bunch of videos will show up. Also many videos around project/solution structure.

  • @MXDMND_
    @MXDMND_ Год назад +8

    Thank you Milan! Another useful video and excellent quality of the content. Cannot wait to see the Authorization part :)

  • @newguycho
    @newguycho Год назад +3

    Kindly smashed the ring bell button too. What about token expiration? Should we use refresh token endpoint or there is sliding expiration if we use this method?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      We can (and should) also configure that through app settings also
      I would leave the refreshing to the frontend. The easiest is they can get a new token. Adding refresh token support requires more work.

    • @MartinoBordin
      @MartinoBordin Год назад +1

      @@MilanJovanovicTech Sorry to jump in :) requiring a new token in a real application would require us to send again username\password (so we would need to store them somewhere in the client application..not ideal)..better to use the refresh token flow

  • @hirbodkhatami9906
    @hirbodkhatami9906 Год назад +3

    Love that bright screen warning :)

  • @alexandernefedov7337
    @alexandernefedov7337 10 месяцев назад +1

    I came looking for copper but found gold. Amazing content, that helps a lot.
    I also have a question. What is in your opinion best way to tackle authentication in microservices environment and/or what are the best sources to look for?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад +1

      I would explore some existing platforms that can solve this problem, so I don't have to do it myself. Auth0, Identity, KeyCloak, etc.

  • @valterdebrito3990
    @valterdebrito3990 Год назад +2

    Thank you Milan! Excellent quality of the content.

  • @Re5pectful
    @Re5pectful Год назад +5

    Great vid as always!
    one small mistake at 16:00 you added the Authentication middleware twice and not the Authorisation middleware

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +5

      Sharp eyes! Yes, I missed that during recording, but fixed it later (otherwise it wouldn't have worked)

  • @ebrahim-s-ebrahim
    @ebrahim-s-ebrahim Год назад +1

    you're an artist, man! this is pure art.

  • @mattpsaltis7417
    @mattpsaltis7417 Год назад +4

    For people starting to move into this space, this is an excellent introduction to aspnet security. Well done Milan! With JWT bearer tokens, a word of caution - please consider your bearer token storage particularly in your browser based client side applications. Current recommendations is to move away from clients having any access to the JWT bearer tokens and instead use cookie based HTTPOnly cookies through patterns like BackEnd For FrontEnd (BFF). Again I want to take nothing away from this amazing video!

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      There are still so many applications storing JWTs client side. I'm not that good at frontend to see why this is a major issue. Care to explain?

    • @VastSolar
      @VastSolar Год назад

      I suppose this is because it allows tinkering with token (data stored in token). While cookie stores only ID by which you get all the data.

    • @mattpsaltis7417
      @mattpsaltis7417 Год назад +7

      @@MilanJovanovicTech In the limited amount of space we have in a chat to discuss a very deep problem sure! Firstly, completely agree that many applications are storing JWTs client side. I have built several systems in that way :D The generalized problem that client side storage introduces is how to protect the JWT which is a plain text password with a short lifespan. The general two options used to date are Local Storage and Cookie storage. In both approaches, malicious JavaScript can extract the JWT bearer token from the user's session storage and use it to attack the protected resource. The problem gets worse when the refresh token is also sent to the client side to support silent refresh which I still commonly see. This is even worse because it removes the short lifespan assurances provided by the JWT. As such, the current OWSAP recommendation is to never provide the client with the bearer or refresh token but instead use HTTPOnly cookies. This particular characteristic of the cookie means that JavaScript cannot access the cookie (with the exception of a browser level security vulnerability)

    • @mattpsaltis7417
      @mattpsaltis7417 Год назад

      The OWASP link is of particular importance because it talks through the specifics of proper session cookie storage and the additional requirements that go along with that. These are characteristics implemented in BFF frameworks such as Identity Server's implementation.

    • @mattpsaltis7417
      @mattpsaltis7417 Год назад +4

      @@VastSolar while jwts are text and are completely modifiable, they also have server side validation to prevent tampering using standard public key infrastructure signing techniques. This means a valid jwt can only be created by a system with access to the private key. Encryption of jwt data is also possible.

  • @ssudharsan5615
    @ssudharsan5615 5 месяцев назад +1

    You're the best tutor I ever had, Thanks a lot buddy!

  • @birukayalew3862
    @birukayalew3862 Год назад +2

    As always I learned a lot...can't wait for the next video.💯❤

  • @mahmoudalaskalany
    @mahmoudalaskalany Год назад +3

    This is great for anyone want to go into identity
    It will be very good if you continue it as a serie with openid dict 3 and extend it to oauth 2 and openid connect

  • @manofqwerty
    @manofqwerty Год назад +1

    Absolutley subscribed! Amazing content delivered so well. Thank you.

  • @MXDMND_
    @MXDMND_ Год назад +5

    Milan, I don't know why, but for some reason the JwtBearerOptionsSetup class Configure method was never called for me, if I followed your tutorial. The class had been instantiated, the constructor was called, but the not the Configure method. After I changed the interface from IConfigureOptions to IConfigureNamedOptions, then the Configure method called succesfully and works without any issue. :)

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Oh, replace it with IPostConfigureOptions! Forgot to mention that 😅

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      I made a mistake, and was too lazy to go back and re-record

    • @MXDMND_
      @MXDMND_ Год назад

      @@MilanJovanovicTech oh, okay no problem. :) thank you

    • @chesterapavliashvili1533
      @chesterapavliashvili1533 Год назад +3

      Oh, I have been trying to figure out for hours. I could configure authentication directly from startup but Milan's approach was not working. Now IPostConfigureOptions has worked, Thanks you both for this comments. Also Milan it would be nice to share your code from github or another source control website, it would be better for us to directly look into working version of it. Anyways thx for your awesome tutorials

    • @MXDMND_
      @MXDMND_ Год назад

      @@chesterapavliashvili1533 you are welcome :)

  • @MilanJovanovicTech
    @MilanJovanovicTech  Год назад +3

    Join more than *42,000+ .NET engineers* already reading my weekly newsletter.
    One actionable tip, every Saturday, less than a 5-minute read:
    www.milanjovanovic.tech/

  • @zaoralj
    @zaoralj Год назад +2

    Bright screen warning 👍

  • @Widra8710
    @Widra8710 Год назад +1

    The IOptions thing was new, thanks !

  • @elpe21
    @elpe21 Год назад +2

    Unless I missed you haven't showed on the video when you rigstered JwtProvider. Great video, I've done it myself as Infrastructure service without Mediator. I guess another small / quick video interesting to many people might be registering via Facebook or / and Gmail.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      I have a piece of code using Scrutor which registers it automatically

    • @elpe21
      @elpe21 Год назад +3

      @@MilanJovanovicTech Forgot about that . but for people that came here for the 1st time looking for JWT implementation this comment might be useful ;-)

  • @ratnadeepkadam1637
    @ratnadeepkadam1637 11 месяцев назад +1

    Hi Milan,
    Thanks for sharing your knowledge with us. It would be really great if you create one guide for handling refresh token

  • @AlannTom
    @AlannTom Год назад +1

    Thank you Milan, love your videos

  • @Real-Hindu-Us88
    @Real-Hindu-Us88 Год назад +1

    Good content i think one you miss about how to refresh token...

  • @justfair4181
    @justfair4181 10 месяцев назад +9

    I recommend creating a solution from scratch since it is too confuse to understand cause you have already lots of code in your solution.

  • @AlexLavrik
    @AlexLavrik Год назад +1

    02:07 - You're using ICommandHandler interface from the Application.Abstractions.Messaging namespace.
    Can you please provide us with the implementation of the interface?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Take a look at this video: ruclips.net/video/vdi-p9StmG0/видео.html

    • @AlexLavrik
      @AlexLavrik Год назад

      @@MilanJovanovicTech Thanks Milan, now I got it! Nice videos btw!

  • @georgeblazhev
    @georgeblazhev Год назад +1

    Hey Milan! Nice solution! Is this approach good for production? Are the signing credentials secure enough? I've heard that a signing certificate needs to be present, however, I don't know how this is implemented. Thanks!

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Why not use an external Identity provider and not have to think about it?

    • @georgeblazhev
      @georgeblazhev Год назад

      @@MilanJovanovicTech I'm asking for my bachelor thesis. My current implementation uses Auth0, but I want to build my own solution some day, just for the sake of it and understand the whole process. I'm still a junior dev and many of the solutions like Auth0 abstract much of the process and it itches me from the inside to learn it all haha.

    • @TheScriptPunk
      @TheScriptPunk Месяц назад

      Don't put sensitive info in the token.
      Token being short lived should be all you need, as it just needs to exist to perform api requests, not interface with the system to finagle auth implementation. The token is the auth, and shouldn't need to be used except for transactional requests.

  • @cyrildouglas9262
    @cyrildouglas9262 Год назад +1

    Great explanation for the generation of the token, kinda lost in the DDD because it was never my cup of tea but thanks in adance for the great tutorial.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Not much DDD here, but I needed this released before I could tackle Permissiom Authorization

  • @henokyoseph7120
    @henokyoseph7120 Год назад +1

    Where does this video continue from? Is there a video explaining how you got to this current outline (constructing gatherly)

  • @rogersab644
    @rogersab644 Год назад +1

    Thank you @MilanJovanovicTech
    But are there any previous videos describe this project (Gatherly) from zero

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      There isn't one

    • @rogersab644
      @rogersab644 Год назад

      @@MilanJovanovicTech I just need to know the content of the Result class, could you provide it for me please

  • @alexkanunnikov4908
    @alexkanunnikov4908 Год назад +1

    Thank you for video. I have a question, why you decide to make custom authentication (and authorization in future) instead of using something as Identity Server for example?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      I wanted to show the concept, and I also use some IDP on a real project. I'll make sure to cover that

    • @alexkanunnikov4908
      @alexkanunnikov4908 Год назад

      @@MilanJovanovicTech It would be great to know your plan and a summary of future videos)))))))

  • @danielegiovanetti9258
    @danielegiovanetti9258 Год назад +1

    Very interesting video. Waiting for next. Special thanks

  • @ahmadsabbagh1554
    @ahmadsabbagh1554 Год назад +2

    Thank you so much. Great topic🤩🌹

  • @diegodelafuente1739
    @diegodelafuente1739 Год назад +1

    Hi Milan. Nice video. I just like to ask if you have another one with the best practice to refresh the token before the original one expires. Regards from the land of Maradona and Messi

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      I didn't cover refresh tokens. Sending my regards from Serbia, to Argentina :)

  • @silvertek
    @silvertek Год назад +5

    Yet another great video, really breaks down simply what the JWT token is and all the options.
    Random question, how does your IDE show the values of your variables when debugging within the text editor? Seems very convenient compared to the separate windows.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      I'm not sure, it's either the latest VS version or ReSharper

    • @idkidk9204
      @idkidk9204 Год назад

      JetBrains Rider has this feature by default

  • @mariosamison3733
    @mariosamison3733 Год назад +1

    Is this a video in a series? I think I'm missing some basic setup to get this working. I'm trying to learn this, have an understanding of database migrations, controllers and REST api's but I don't understand how the interfaces you implement can execute the code of the class

    • @mariosamison3733
      @mariosamison3733 Год назад +1

      never mind my dumb question, I got it working, but I'm still getting unauthorized even though I use the token in the call

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Check out my pinned comment, and sorry for the inconvenience!

    • @mariosamison3733
      @mariosamison3733 Год назад

      @@MilanJovanovicTech no problem, I got everything working, fantastic video. Do you also have video's on how you set up a clean project from scratch?

  • @fieryscorpion
    @fieryscorpion Год назад +1

    Great video! Thank you so much!
    This would have been even better if you had ditched Clean Architecture in favor of simple architecture; dare I say Minimal APIs?
    Clean Arch forces you to create way too many files and abstractions to do a trivial task and I've got PTSD from it.

  • @rasimismatulin1400
    @rasimismatulin1400 Год назад +1

    Nice video add it to playlist for watch when i will be need to implement Authentication

  • @hedrickgodsons9011
    @hedrickgodsons9011 Год назад +1

    Do you have a video when you started this project from beginning ? I found you have already written a lot of codes. I am a newbie, and I found you have great contents.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Unfortunately, not. But the new series on eShop start more or less from scratch.

    • @hedrickgodsons9011
      @hedrickgodsons9011 Год назад

      @@MilanJovanovicTech Okay, if you have a paid courses on User Authentication and Authorization pls share a link. Good work Milan

  • @christiantricarico
    @christiantricarico Год назад +2

    Hi Milan, following your technique to setup JwtBearerOptions through ConfigureOptions gives me a www-authenticate: Bearer error="invalid_token",error_description="The signature key was not found" error. I still need to add the configuration as a AddJwtBearer method parameter in order to get it working. It's a .NET 7 web api project.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Did you take a look at the pinned comment?

    • @christiantricarico
      @christiantricarico Год назад

      @@MilanJovanovicTech I missed the pinned comment. IConfigureNamedOptions did the job. Thanks.

  • @joaquinarias3387
    @joaquinarias3387 Год назад +1

    Thank you, very useful. But, what should be changed to make it work on net core 6?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Just use the appropriate nuget package for .NET 6, everything else is the same

  • @sweeperq
    @sweeperq Год назад +1

    Great content! Is there a git repo for these videos?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Some of it I share on my GitHub, but if you want everything you can check out my Patreon page

  • @Tamer_Ali
    @Tamer_Ali Год назад +1

    Thanks Milan for your awesome video.
    I hope you talk about how to Refresh JWT?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      I'll consider it, didn't plan to. As I usually don't do any of this myself. I use an IDP

  • @siddharthgupta3313
    @siddharthgupta3313 Год назад +1

    Can you please share a video link in which you written code for Application/Abstraction folder?

  • @hiranochi
    @hiranochi Год назад +1

    Awesome video! Correct me if I'm wrong, wouldn't it be a good idea to create an extension method for the Services? ex: builder.Services.ConfigureJwtSetup(), then the said ConfigureOptions will just be invoked there (well if those two are tightly coupled).

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Of course, good idea. I didn't want to stress that topic here however

  • @iseraid1504
    @iseraid1504 3 месяца назад

    Hello! I encountered your videos on permission authorization and tried to return to the start of this 'series' link by link. This one seems to be the starting point, but, for example, throughout the video you use the Abstractions namespace from the solution. Am I right to assume that, for example, ICommand interface is your own written abstraction? Or is that some common logic that I'm just not familiar with? Being a little confused trying to follow along.

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 месяца назад +1

      Feel free to grab the source code from the link in the description

    • @iseraid1504
      @iseraid1504 3 месяца назад

      @@MilanJovanovicTech ah thanks, somehow overlooked the link!

  • @janhendrych1076
    @janhendrych1076 4 месяца назад

    Hi, great video. I would just like to have one question. Why do you separate the login request and command? why doesn't the controller just take a command as a parameter?

    • @MilanJovanovicTech
      @MilanJovanovicTech  4 месяца назад

      Separating the public API from internal API

    • @janhendrych1076
      @janhendrych1076 4 месяца назад

      @MilanJovanovicTech thank you, are there some major security issues if you don't do so?

  • @TheScriptPunk
    @TheScriptPunk Месяц назад

    Correct me if im wrong...
    The web tokens are stamped into http secure cookies, correct?
    So the browser context which has the proper cookies has authorization, but the frontend doesnt have any way to indicate that it has auth cookies...right?

  • @webdevelopment6679
    @webdevelopment6679 Год назад +1

    Great tutorial. Can you also do one to explain refresh tokens.

  • @pureevil379
    @pureevil379 Год назад +2

    Fantastic video! I'd love to see the using of the JWT expanded a little. For example yes they are a member and have successfully authenticated through the login endpoint. But they do not have permission to access GetMember endpoint based on claims (think it would be here that this differentiation would be set?). Would [Authorize] be un changed and the blocking of endpoint usage be within the endpoint method perhaps..
    Anyway once again fantastic video had me captivated.

  • @chadjefferson8203
    @chadjefferson8203 Год назад +1

    Hi Milan, great video. I am having a small issue implementing this though. I did not see in your video the adding of the service IJwtProvider to the program.cs. When I add these steps to my application I get a service issue on the JwtProvider. Any quick suggestions would be appreciated.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Add it as a Scoped service

    • @chadjefferson8203
      @chadjefferson8203 Год назад

      Don't worry there were 2 issues. 1 was the IConfigureNamedOptions Implementation on the JwtBearerOptions and the service issue i resoled by just making the jwt token generation happen inside the authorisation controller and removed the JwtTokenProvider Class. All works now so thanks for the video. If you have a quick idea as to why the generate method works in the JwtTokenProvider class for you and not in my case it would be great to learn why.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      @@chadjefferson8203 Did you check the pinned comment?

    • @chadjefferson8203
      @chadjefferson8203 Год назад

      @@MilanJovanovicTech Yes thank that is how I figured out an error I was having with failed JWT signature. I did try the scoped service but was getting a life cycle determination error. Token Generation is cruelty working as part of the Auth Api so will leave it there for now. Thankyou

  • @backfield7785
    @backfield7785 Год назад

    Thanks milan... Great video...

  • @ayedabboushi7221
    @ayedabboushi7221 Год назад +1

    Many thanks Milan, Can you extend it with OAuth 2 and OpenId-Connect.

  • @mylesdavies9476
    @mylesdavies9476 Год назад +1

    Another great video, thanks 👍

  • @onionware1
    @onionware1 Год назад +1

    Thank you very much for that! Can you say when should we use symmetric and when asymmetric keys to create JWTs? Currently we use symmetric, the server creates the JWT and sends it encrypted to the user. When the user sends it back, the server decrypts and checks it. The symmetric key is securely stored on the server. Do asymmetric keys have any advantages here?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Ideally, you won't implement any of this on your own. There are excellent third-party authentication services that implement this much more securely than what I showed in the video.

  • @mohammadsowrav2308
    @mohammadsowrav2308 Год назад +1

    how to show data tip ( that looks same as browser JS debugger data tip ) like you without hovering mouse over variable?

  • @ahsanmehmoodgaming
    @ahsanmehmoodgaming Год назад +1

    Can you give me a video where you attach db first approch with db in clean artitecture?

  • @joaovitorbarbosa4669
    @joaovitorbarbosa4669 Год назад +1

    Why is JwtProvider's interface in the application layer and not in the infrastructure layer along with its implementation class?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Because you need it in the command handler

    • @joaovitorbarbosa4669
      @joaovitorbarbosa4669 Год назад

      @@MilanJovanovicTech Because the application layer cannot depend on the infrastructure, so calling the interface directly from the infrastructure would break the rule, right?

  • @kodindoyannick5328
    @kodindoyannick5328 9 месяцев назад

    Excellent content! Thank again Milan.

  • @manouser11
    @manouser11 7 месяцев назад

    Hey! What extension are you using for the keyboard shortcuts (replacing words, autocomplete etc.)? It looks a lot like vim.
    Thanks!

  • @dmoth1610
    @dmoth1610 Год назад +1

    This video is so useful!

  • @manofqwerty
    @manofqwerty Год назад +1

    Do you have a video on the ICommand pattern being used here?

  • @maidulislam2057
    @maidulislam2057 Год назад +1

    hi @milan i liked ur way to do , but it not working at all . so i feel this is not full video or Code, do u mind share git repo for this.

  • @rajaramdeivanayagame
    @rajaramdeivanayagame Год назад +1

    Hi, Great content, i have this issue=> : Bearer error="invalid_token", error_description="The signature key was not found". How can i solve it ?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Please take a look at the pinned comment

    • @rajaramdeivanayagame
      @rajaramdeivanayagame Год назад

      @@MilanJovanovicTech Thank, you, i found my problems, issue with postman, after resolving my problems with postman, now works perfectly. Thank you for this content and for your answer.

  • @sonnyskold5634
    @sonnyskold5634 Год назад +1

    What are your thoughts of storing refresh and access tokens in localstorage? I have implemented refresh token rotation, and I do store the tokens in localstorage. So if the request is 401 etc I send to token/refresh and get new token pair and continue with the original request. But I am reading a lot of mixed information, some say its considerably more safe to store it in httponly cookies.
    I would appreciate your input on the implementation. Its a system where users login with a personal id. So its a bit sensitive, maybe httponly cookies is better then?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      I'm not a UI expert 🤷‍♂️ But I did in the past, don't tell though...
      So I'd refer to someone who does Frontend work for a living 😁

    • @sonnyskold5634
      @sonnyskold5634 Год назад

      @@MilanJovanovicTech Okay, thank you :D I will go for the implementation I have right now but will consider switching before deploying.
      Appreciate the answer :)

    • @committedcoder3352
      @committedcoder3352 Год назад

      @@sonnyskold5634 Hi! Since the refresh request will inherently always need the refresh token (and the refresh token will need to be sent to the UI in the first place), there really isn't a way to keep it safe from bad actors; as is generally the case with anything on the frontend. If you want it safe, keep it server side. The safety in these tokens comes from the hashing. It's actually pretty neat if you look up how it works, basically all the parts of everything that's encoded get meshed together and most stay on the server so the client knows very little about from what the token is generated.
      In terms of how to handle it, it depends on the concerns of the application.
      You'll often see websites have a "User inactive, you will be signed out in 'x' seconds, click to refresh" popup. I'm not certain but I assume that's just doing the refresh haha. Regardless if you're doing automatic token refresh, you should really do something to have either your users opt in or let them know that's what is going on for ethical considerations.
      You do want to make sure you're rotating your refresh tokens. You don't want any to be long-lasting.
      That said, what you listed works fine haha. I've done that in plenty of personal projects. For something more professional you should really do the pop-up.

  • @grumpydeveloper69
    @grumpydeveloper69 Год назад +1

    I just looked at Jwt authentication and was wondering: I wanted to use this for authentication API users where I supply an 'apikey' in the form of a Jwt. But then I want users to be able to use this token a long time (it will be configured in some backend services), but still have the ability to revoke it when needed. Am I correct in thinking the only way a Jwt can be revoked is by changing the Secret that is used to validate tokens, or I should store the token in the Api to have a revocationlist of tokens that I don't want to be used anymore.
    Maybe this is not what Jwt was intended for but with an API service you would like to give users access, be able to change what access they have (which endpoints they can call) and also either extend or revoke their access. This is not something a Jwt does out of the box unless you program around this.
    I tend to see a Jwt as something you can use to give shortlived access (hence the expiration) and during that time give access to a fixed set of resources, the claims (roles/policies) in the Jwt. It's handy that any endpoint can validate the token and give access to resources based on the claims inside this token without the need to go to some backend database.
    In my case we have an API that has several endpoints, let's say Company, Contact, Order and some users might not have access to Order so the Claims could quikly block users there. But then a user might have access to Company A, and **not** Company B, thats access information that cannot be stored in the Jwt and has to live elsewhere...right?
    But then when I have to store data elsewhere anyway, why not store as much of it elsewhere instead of in the Jwt...**I'm thinking of the Expire date here ** why store that in the token when I could also put in in the database, and even have the ability to extend it without having to give the user a new token.
    @Milan Do you have some place to discuss this with others outside of the RUclips comments?

  • @BillMoman
    @BillMoman Год назад

    @16:10 - you added app.UseAuthentication(); twice even though use said one should be app.UseAuthorization(); (lines 99 and 101) With that mistake, why did it work anyway?

  • @andresbeltran5779
    @andresbeltran5779 Год назад +1

    Hi, where can i find the source code? there is another series to develop this structure?

  • @Engineer2261
    @Engineer2261 6 месяцев назад

    Why did you create 2 separate records, referring to LoginCommand and LoginRequest?

    • @MilanJovanovicTech
      @MilanJovanovicTech  6 месяцев назад

      Splitting public contract from internal one

    • @Engineer2261
      @Engineer2261 6 месяцев назад

      ​@@MilanJovanovicTech Thanks.
      By the way, your source code is slightly different than the codes in the video. Did you make some improvements to it? For example, JwtBearerOptionsSetup is implemented IPostConfigureOptions instead of IConfigureOptions in the source code.

  • @ayedabboushi7221
    @ayedabboushi7221 Год назад +1

    You should add a dependency injection for IJwtProvider
    services.AddTransient();

  • @JuniorKidsProgramming
    @JuniorKidsProgramming 10 месяцев назад +1

    Hello! is there any chance to get the Source code?

  • @TolgaKoseoglu
    @TolgaKoseoglu Год назад +1

    Greate video, thank you. Do you have a video on how to configure a dotnet core webapi with EXTERNAL login providers, like Google, Facebook?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      No, I don't and I'm not sure I'll make one with Google/Facebook soon

  • @alisriti3002
    @alisriti3002 Год назад +1

    pretty good. bravo

  • @Hallo503
    @Hallo503 Год назад

    Great Video as always very informative! Q: Is there a way to invalidate a valid token, for example when the user changed password, or logs out?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +2

      That's a tough one, the short answer is no. But you can somehow store the token and check it on every authentication request, which is stupid and degrades performance. One option is to give tokens a short lifetime. Another option is to code your client side code to request a new token when a user does an action like that.

  • @Tamer_Ali
    @Tamer_Ali Год назад +1

    Hi Milan,
    Is it ok if I added Authentication and JwtBearer in the Infrastructure project instead of UI?

  • @kyreehenry9202
    @kyreehenry9202 28 дней назад

    A lot these videos and post of generating jwt tokens are out there but interestingly none on how to use the refresh token on a web client especially SSR client

    • @MilanJovanovicTech
      @MilanJovanovicTech  28 дней назад

      Nothing magic about a refresh token. Create a token, store it in the DB. Client sends it to get an access token back.

  • @SiyawashZahedi
    @SiyawashZahedi 11 месяцев назад

    hi,
    If authorization fails and you get this error :
    bearer error="invalid_token", error_description="the signature key was not found";
    In JwtBearerOptionSetup class implement IPostConfigureOptions

  • @VSinsights
    @VSinsights Год назад +1

    30/07/2023 I tried it again and again but always get UnAuthorized! Are there any recent changes in .Net Core that affect it? Please help!

  • @subhrajitmazumder7122
    @subhrajitmazumder7122 Год назад +1

    Thank you. How can I download this source code ?

  • @pritompaul4249
    @pritompaul4249 Год назад +1

    Please make a series with Identity Server

  • @johncerpa3782
    @johncerpa3782 Год назад +1

    Great video

  • @alexalexander3252
    @alexalexander3252 7 месяцев назад

    Milan, I get this exception whe try to create SymmetricSecurityKey: IDX10720: Unable to create KeyedHashAlgorithm for algorithm 'HS256', the key size must be greater than: '256' bits, key has '128' bits. (Parameter 'keyBytes'))
    I believe the problem is somewhere in UTF8. Could you advise how to fix this?:

  • @SerafimMakris
    @SerafimMakris Год назад +5

    BRIGHT SCREEN WARNING i LOVE IT

  • @subhrajitmazumder7122
    @subhrajitmazumder7122 3 месяца назад

    How we download this Gatherly application? Please give any suggestions.

  • @Anubis10110
    @Anubis10110 Год назад +1

    Straight to the point Thanks Milan

  • @lopezjesutoba4423
    @lopezjesutoba4423 Год назад +1

    The video isn't complete, I can seems to get the issuer, Audience and the secret key values

  • @DENDYTWOO
    @DENDYTWOO Год назад +1

    Please, do video with refresh tokens.. Thank you!

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Lets leave that to the IDP?

    • @DENDYTWOO
      @DENDYTWOO Год назад

      @@MilanJovanovicTech I'm a little uncomfortable, but I do not know what IDP is

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      @@DENDYTWOO No reason to be, I never discriminate on knowledge. 😁
      IDP = IDentity Provider
      What would that be?
      - Identity Server
      - Active Directory
      - Auth0
      - KeyCloak
      - Firebase Authentication

    • @DENDYTWOO
      @DENDYTWOO Год назад

      @@MilanJovanovicTech I really appreciate you answering my question. I do not know what I should answer your question about IDP, but now I know what it means. You are smart and kind, thank you for the answer and for your videos

  • @YuviYatham
    @YuviYatham Год назад +1

    Thanks its very helpfull

  • @manofqwerty
    @manofqwerty Год назад +1

    Hello, I believe I have followed this tutorial perfectly a number of times and have created a solution just for testing it, though I am always hitting the same issue. When testing in Postman, I am getting the following error in the `WWW-Authenticate` header: `Bearer error="invalid_token", error_description="The signature key was not found"` - do you have any ideas why this may be happening?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Yes, I do believe I mistakenly configured JwtBearerOptionsSetup to implement IConfigurOptions, and it should be IConfigureNamedOptions or IPostConfigureOptions.
      Also, at around line 105 in Program.cs, I have UseAuthentication two times. Where one of those should be UseAuthorization

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Can you confirm those fixes solved the problem? And I'll add a pinned comment with the resolution, for anyone else that runs into the issue

    • @manofqwerty
      @manofqwerty Год назад

      @@MilanJovanovicTech I just want to say how much I really appreciate you getting back to me and helping me!

    • @manofqwerty
      @manofqwerty Год назад +1

      @@MilanJovanovicTech Just to confirm, using the IConfigureNamedOptions did fix my issue. RUclips seems to be deleting a lot of my comments.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      @@manofqwerty RUclips is weird like that sometimes. Thanks for letting me know, I'll pin the explanation for anyone else that runs into the same issue.

  • @stebberg
    @stebberg Год назад +1

    Very nice!

  • @carrucancarrucan
    @carrucancarrucan 10 месяцев назад

    Using the options pattern within your startup configuration is an overuse of the pattern. This will get refactored into an extensions method where you simply pass configuration into a static method where the JwtBearer options can be configured. Also the OptionsSetup folder is not very useful or extensible for scaling the app. Instead I would add a Middleware folder in the Api project (Gatherly.App) then add folders as you create more startup extensions (Auth, HealthChecks, OpenApi, Telemetry, Validation, Etc.)

  • @new.clasic5512
    @new.clasic5512 Год назад +1

    thanks ,
    where is the code ? can you send the link

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      The source code is shared on Patreon

    • @new.clasic5512
      @new.clasic5512 Год назад

      tnx for answer , but i can't access to patreon in my country ,tnx for sharing your information @@MilanJovanovicTech

  • @winstochurgle9133
    @winstochurgle9133 Год назад +1

    May i somehow implement this to the .NET MVC project?

  • @wael8312
    @wael8312 8 месяцев назад

    You are implementing examples of a project. Where is the code for this project or any operating list in which the project was built

  • @ramysamir1987
    @ramysamir1987 Год назад +1

    Hi Milan,
    what about if i take this token and called specefic function with parameter not allowed to me ? how i can prevent it to happen specially from postman interface.
    Thanks

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      I didn't quite follow what you asked. Could you rephrase?

    • @ramysamir1987
      @ramysamir1987 Год назад

      @@MilanJovanovicTech if you take the jwt token and make request from postman if will be accepted even if this api is acepefic for 1 user, what shall i can do to prevent this to happen?
      i hope you can get what i means

    • @ramysamir1987
      @ramysamir1987 Год назад +1

      in another way lets supposed there is api with email id to get all email info. anyone can use this api through postman with valid jwt token with random email id to get email info without he has the access to this email itself.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      @@ramysamir1987 You need to add the concept of resource authorization to that. Based on the JWT you can know WHO the user is, and determine if they can access that specific email

  • @mustafahaider9115
    @mustafahaider9115 8 месяцев назад

    can I watch this without having to watch the clean architecture and ddd series?

  • @pseudocoffee4829
    @pseudocoffee4829 Год назад +1

    Doesn't work for me, I keep getting:
    Bearer error="invalid_token", error_description="The signature key was not found"

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Try using IPostConfiguteOptiond for the JwtOptionsSetup

    • @pseudocoffee4829
      @pseudocoffee4829 Год назад

      @@MilanJovanovicTech i tried it out but it does not seem to work, after some debugging it looks like the JwtBearerOptionsSetup class does not run at all, seems that if i extend IConfigureNamedOptions instead of IConfigureOptions it works.

    • @tonycaesar7934
      @tonycaesar7934 Год назад +1

      @@pseudocoffee4829 , Thanks for posting this. I was seeing a similar problem and hardcoded the config as a work around. I kept both interfaces and simply called the original Configure(options) from Configure(name, options).

  • @omidkianifar5144
    @omidkianifar5144 Год назад +1

    Hi milan ❤
    What is issuer and audience usage?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      I think this sums it up nicely: www.quora.com/How-can-I-understand-audience-and-issuer-in-JWT-authentication