Cookie based authentication with Spring Security | Spring Boot Backend #3.2

Ғылым және технология

In this video I will show the cookie based authentication with Spring Security. I will authenticate a stateless application with the cookies. And I will show the differences with the JWT authentication.
This is the second part of the third video of a playlist where I show how to create a Spring Boot Backend how to create a website: • Spring Boot
Content of the video:
* the HTTP filters. One will be dedicated to the regular authentication with the username and password, and the other will be dedicated to the cookie based authentication;
* the configuration of Spring Security. I will show how to add multiple HTTP filters, the exception handling with an Entry Point, the session management in a STATELESS mode and the path which need authentication and the one which don't;
* the creation of a token to be used in the cookie.
* The injection in the SecurityContext of the Authentication Bean for the usage in the controllers of the annotation @AuthenticationPrincipal.
Repository: github.com/serlesen/backend-s...
My NEW eBook: sergiolema.dev/git-book/
Blog: bit.ly/47ornJL
LinkedIn: bit.ly/41Nn61q
Facebook: bit.ly/47rc9nh
My Desktop:
• Laptop: Macbook Pro 16' 2019
• Gaming Chair: amzn.to/47Vu6ed
• Mouse: amzn.to/3HoBwM1
• Desk: amzn.to/48Tc5Oi
• Screen: amzn.to/48VZkCL
Icons:
* Browser by Nawicon from the Noun Project;
* file document by Phumpsky from the Noun Project;
* Lock by tezar tantular from the Noun Project;
* Share by Sujono sujono from the Noun Project;
* User by ✦ Shmidt Sergey ✦ from the Noun Project.

Пікірлер: 60

  • @fasolplanetarium
    @fasolplanetarium Жыл бұрын

    I've searched all day for docs, tutorials - anything - that explains how to configure Spring Security for authentication NOT through Spring Security's built-in form. This is the only tutorial I've found that actually gets to the point of what an actual auth workflow would look like. Thank you!

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    Thank you. I try my best to be as pragmatic as possible.

  • @livb4139
    @livb41393 жыл бұрын

    love the interlude explanations in the middle of the video like in 1:45 very helpful

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    3 жыл бұрын

    Glad to hear it!

  • @alvarito99dark
    @alvarito99dark Жыл бұрын

    Muchas gracias, Sergio. Eres un gran maestro, se agradece canales como el tuyo que ayudan a los demás a aprender. Un saludo, like y new sub!

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    Gracias a ti por el apoyo!

  • @Anthony-zc7ff
    @Anthony-zc7ff2 жыл бұрын

    Thanks, it was really interesting but there's something I don't understand : how is Spring supposed to know it needs to use your "UserAuthenticationProvider" class ? In the config class, are you not supposed also to override configure(AuthenticationManagerBuilder builder) method to specify how the authentication will execute ?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    2 жыл бұрын

    You have 3 mains components : the entryPoint which implements AuthenticationEntryPoint and will be automatically handled by Spring; the HttpFilter which extends a Spring filter and will be added to the list of Spring filter and called upon the web configuration at WebConfig; and the Provider which is a Spring component and can be injected anywhere, in this case in the HttpFilter. Check more in details in my Github repository : github.com/serlesen/backend-social-network/tree/chapter_3_2/src/main/java/com/sergio/socialnetwork/config

  • @user-my1of1wf8b
    @user-my1of1wf8b11 ай бұрын

    this was really helpful thanks !!

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    11 ай бұрын

    Glad it helped you

  • @user-zq4tb9qp9t
    @user-zq4tb9qp9t Жыл бұрын

    Hi! Thank you so much for your videos! However, I encountered an issue with authentication when I accessed the "/sign In" endpoint. The @AuthenticationPrincipal did not work, and the user argument was null until I injected a provider into filters and called provider.authenticate() to put the user into the security context.

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    First of all, thank you for watching my videos! The annotation AuthenticationPrincipal only works after adding the Authentication Bean into the Security Context of Spring. This can be done through an HTTP Filter as done in the video.

  • @nguyenhoanganh2k1
    @nguyenhoanganh2k12 жыл бұрын

    i very curious about your experience , how long have you study spring framwork?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    2 жыл бұрын

    I think I've been working with Spring for more than 10 years now.

  • @VladVlad-cy6tn
    @VladVlad-cy6tn Жыл бұрын

    So I can make a call (POST request) to programmatically authenticate and get those cookies. Then, I can set those cookies via javascript code in the user's browser. And then, if I have a frontend app (i.e., AngularJS), and it is configured to rely on those cookies, then I'll not get any login page when loading this AngularJS app, right? Since AngularJS uses the cookies that we got from the POST request, right? I have an external app (that will load my app in the ), so the external app will authenticate to my backend (via POST), set those cookies in the user's browser, and then will call my app in the . And my AngularJS app should load without the login page. Do I understand it correctly?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    You can make the POST request to authenticate with Axios from your AngularJS application. Axios will automatically read the response and store the cookie in the browser. The cookie will then be used in all the requests as they are made from the same domain. Still, to use Axios this way, you can to add another parameter, check this link: stackoverflow.com/questions/52549079/does-axios-support-set-cookie-is-it-possible-to-authenticate-through-axios-http Hope it works for you.

  • @arielcg_
    @arielcg_ Жыл бұрын

    Hola! First of all thanks for this video, it was really useful for implementinng my own authentication. However, a few questions raise, like how to make remote session invalidation possible. Say my token is stolen by someone, and I want to prevent them from using it. I'd go into an endpoint and say "invalidate all my sessions" but how could I do this in the server? The token is one per user, no matter where they log in from. Maybe include as part of the cookie a "loggedInAt" key with the current millisecond and persist that in database, along with extra identifying data like IP, device identifiers... and a false "expired" key which I set to true if the user decides so? What are your thoughts on this?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    I think you must take track of the created sessions, maybe in the database or in a cache session. Take a look at the SessionRegistry of Spring Security: docs.spring.io/spring-security/reference/servlet/authentication/session-management.html#list-authenticated-principals

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    I've also found this question which seems to handle your problem: stackoverflow.com/questions/35276554/spring-security-how-to-expire-all-sessions-of-a-user

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    Y gracias por seguirme 😅

  • @marouaniAymen
    @marouaniAymen Жыл бұрын

    Thanks for sharing this video, I'm thinking of the scenario where the cookie is HTTP only so no JS code can access, but the JWT token inside the cookie contains the user Roles and Groups that the client side JS uses to show/hide pages and UI components (example hide the button create when not admin). What can we do in this case, do we have to create a new endpoint that uses the cookie and returns user's habilitations ?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    First, thanks for watching Aymen! Yes, I would create another endpoint, maybe not only dedicated to the roles and groups but for the complete user information (first name, last name, roles, groups, language...). I don't like the idea of the frontend decoding the JWT. Because this means that I'm encoding information that must be cracked. Why don't send the information in clear directly?

  • @marouaniAymen

    @marouaniAymen

    Жыл бұрын

    @@TheDevWorldbySergioLema I agree with you in that point, but I worked with some architectures using REST API secured with JWT tokens sent on the header, so you can consider it as a signed data containing user information

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    Yes, technically, there is no restrictions this way. But I think it's not a best practice.

  • @And1997Ruz
    @And1997Ruz10 ай бұрын

    This is gold!

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    10 ай бұрын

    Thanks Andrey!

  • @arnaudpoutieu1912
    @arnaudpoutieu19123 жыл бұрын

    Hi Sergio. First of all, many gratitude for such a well done content. I have almost watched the whole videos available on your channel. I'm currently facing something very weird with Authentication (I took example on this particular video), and I would like to know if you can help me: My issue is that unauthorized HTTP call is going through the filters and unexpectedly the HTTP Client receives 200 with empty content where I expected 401. Any idea what could have been done wrong on my side?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    3 жыл бұрын

    That you very much for your interest. This may come from the WebClient configuration or from the web filters. It's hard to say without seeing the code Don't hesitate to see my github to see the exact code i've used in the videos

  • @arnaudpoutieu1912

    @arnaudpoutieu1912

    3 жыл бұрын

    @@TheDevWorldbySergioLema Thank you Sergio. I can share the code with you (Can I send the link to you using your email address?). Already cloned locally your repo.

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    3 жыл бұрын

    Or create a question in stackoverflow and share here the link. Maybe someone else fatser can give you an answer

  • @PraveenSingh-sz6zj

    @PraveenSingh-sz6zj

    2 жыл бұрын

    @@arnaudpoutieu1912 were you able to solve your problem as it is not working for me as well.

  • @itsdaitonxd
    @itsdaitonxd Жыл бұрын

    Hey, first of all, thank you for the great tutorial. I have a problem with cookies in my application at the moment. Whenever the user authenticates themselves and logs into the application and gets the cookie, they can then access the end-point again to login, and get a new cookie. Is there a way to prevent the user from login in again, once he is logged in? Basically, so they cannot do concurrent logins and 'spam' the end-point constantly.

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    Thanks. I think you can get it with the ConcurrentSessionControlAuthenticationStrategy configuration. Check it at this question on stackoverflow: stackoverflow.com/questions/57241178/spring-security-disable-multiple-sessions-on-the-same-user-not-working

  • @itsdaitonxd

    @itsdaitonxd

    Жыл бұрын

    @@TheDevWorldbySergioLema Thank you for the quick reply. I'm looking into these resrouces you linked, but it seems they are used for cases with session, and I'm using stateles application with cookies only, I do not create sessions. Is there a way to fix this in stateless app?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    I don't think there is a way to do so in a stateless application, as there is no trace of all the created sessions. Only doing it manually. I've done something like this some time ago : I had a table where I trace all the login of each users with the user-agent used. If another login occurs with a different user-agent, it's refused. And when logout, remove the link. It's not perfect, but it was enough for me.

  • @itsdaitonxd

    @itsdaitonxd

    Жыл бұрын

    @@TheDevWorldbySergioLema Thank you again, I will look into that.

  • @hardsystem9522
    @hardsystem9522Ай бұрын

    When I send the request in the curl I always get UserDto == null , I switched your code to spring boot security 6 and java 21, spring boot 3.2

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Ай бұрын

    You need to use the same cookie Id when using the curl as the received one.

  • @PraveenSingh-sz6zj
    @PraveenSingh-sz6zj2 жыл бұрын

    This code is not working. Where is authentication provider injected because i am getting null pointer exception as it is not going in the authenticate method as well as it is going to create the cookie even if wrong password is entered.Could you please reply quickly by checking your code.

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    2 жыл бұрын

    You have the complete project in the link of the description, it's all in Github

  • @Areeb949
    @Areeb9492 жыл бұрын

    Hey, why do we need to clear the security context in logout? Won't it be cleared anyway when the request is completed?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    2 жыл бұрын

    No. The first request will create a cookie. This cookie contains the ID of a session. The session will have a timeout of 5 minutes (I think it's the default timeout). After the request is completed, the context still exists within the session until the timeout. That's why you need to clear the context to invalidate the session and the cookie.

  • @Areeb949

    @Areeb949

    2 жыл бұрын

    @@TheDevWorldbySergioLema But we set the session creation policy to stateless right? Does this still happen in that case?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    2 жыл бұрын

    If you set the policy to stateless, clearing the security context will be done at the end of the request. Nevertheless, you may have some other filters which will be executed after your controller, so, it's a best practice to ensure your context is clean (no authenticated user in the context).

  • @Areeb949

    @Areeb949

    2 жыл бұрын

    @@TheDevWorldbySergioLema cool, thanks. Nice video btw! 🙂

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    2 жыл бұрын

    Thanks!

  • @ram0973
    @ram09732 ай бұрын

    Can I just put jwt token in the cookie?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    2 ай бұрын

    What's the purpose?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    2 ай бұрын

    There is no technical problem/restriction on that

  • @ram0973

    @ram0973

    2 ай бұрын

    @@TheDevWorldbySergioLema Thank you for your answer. With jwt in the cookie I can store my jwt tokens in http-only cookie, and I have stateless session. Also I can use the complete jwt library (nimbus) for auth. No need to write much code. Is it wrong way? Also thank you for your work, very interesting and useful.

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    2 ай бұрын

    So, you're sending the JWT in a cookie instead of a Header. That's an alternative.

  • @tylerdurden4563
    @tylerdurden4563Ай бұрын

    This tutorial is not working anymore. It is deprecated. Just a head up for new watchers like me

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Ай бұрын

    Yes, it uses an old version of Spring Security. I should do another video with the new version.

  • @rajivkumar-ub6uj
    @rajivkumar-ub6uj2 жыл бұрын

    Context: I have implemented Google OAuth2 login at gateway and once google login is success, I will store the user details if not exists in db and create a jwt token with roles/permissions based on type of user logged in. There are couple of downstream microservices are behind the gateway (not necessarily in same cluster or in same tenant or same cloud provide). Once login success, the gateway will respond with generated jwt token to browser which can be used for all downstream microservices later. This is initial requirement and later we got a requirement to maintain only one user login session per user account. As we already made it as stateless, for server there is no way for us to determine no. of logged in sessions. So we introduced session manager which stores these jwt tokens at Gateway and maintain the recently login session, remaining can be invalidated (now it's stateful at gateway + stateless for downstream microservices (all downstream apps are capable of self verify the jwt tokens by secret key). It is working fine but we ran into other problem. Problem: Because of our session manager requirement, the user cannot work on multiple browser tabs of the same site because it will ask for login. If he try to login, the other tabs will be logged out due to 401 error because the server thinks other tabs as separate login sessions. I know we can make it work storing that jwt token inside a cookie, which can be used across the tabs but is there any other way to solve this problem? Or we used implement a complete stateful security (at server side) with common session storage (redis) and provide access to all downstream services? The reason we haven't choose this approach is all downstream services can be anywhere and for each request, it has to fetch the session from redis, which introduce the network latency What is your thoughts/suggestions on this?

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    2 жыл бұрын

    Hello. I think that storing the token in the cookie or in the localstorage is the solution which implies less modifications in your server. Using a fully managed session needs several modifications, and more if you want to use redis to store the session. Most of the time, the easiest solution is the best one.

  • @petarmikulic777
    @petarmikulic777 Жыл бұрын

    Hi I pulld code from repository in description TAG chapter_3_2 and it's not working for me. Authetntication provider is not called at all. I am getting error: org.springframework.security.authentication.InsufficientAuthenticationException: Full authentication is required to access this resource at org.springframework.security.web.access.ExceptionTranslationFilter.handleAccessDeniedException(ExceptionTranslationFilter.java:199) at org.springframework.security.web.access.ExceptionTranslationFilter.handleSpringSecurityException(ExceptionTranslationFilter.java:178) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:147) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:91)

  • @TheDevWorldbySergioLema

    @TheDevWorldbySergioLema

    Жыл бұрын

    Hi. This is very strange. I've just checkout the same tag and it works fine for me. The Provider is used automatically by Spring because it implements AuthenticationProvider and it's annotated with Component. First, the filters are called (the cookie or the username & password), if one of those create an Authentication bean, the Provider is called by Spring automatically.

Келесі