Thanks for making. Can you make videos on spring Authorization server and fit this in microservices architecture behind the gateway. Explain oauth 2 + openid flow (from web app to auth server through gateway, can be standard or federated authorisation) and communication among resource services (client credentials grant) etc.
Hey Max! Great video. I did have issues with the login end point where an 401 error is thrown. Using the debugger it said it has something to do with InvocationTargetException.
Hi Max, in my implementation even after doing all the things you mentioned /token api throws 401. In the stacktrace I see the error "Failed to authenticate since the JWT was invalid" your help will be appreciated here
Thanks for the great video. Is it possible to do this with the new spring authorization server? And a client (API gateway)-spring authorization server- with backend resources (services)?
Hello, great curse!. when i uses postman to get the refreshToken at /token endpoint its Ok!, but when I get a 401 error in the Angular Interceptor HttpErrorResponse and i call the service that handle the post of the refreshToken, it always crash the spring server "java.lang.IllegalArgumentException: token cannot be empty", I don´t know what to do
hello, .antMatchers is no longer supported by spring security , what is the alternative , although i tried using .requestMatchers and mvcMatchers and got 401 in postman
Hello, based on the docs docs.spring.io/spring-security/reference/5.8/servlet/authorization/authorize-http-requests.html you can simply replace the use of ".antMatchers" with ".requestMatchers"
Can you please explain. It turns out that the resource server here is also an authorization server, because it generates tokens? Will you make a video in which you will show an example of a separate own authorization server. Or you can suggest materials where the implementation of your own authorization server is shown, please
Yes in this example the resource server acts as an authorization server, it allows exchanging a user password for an access & refresh token. An own spring authorization server can also be used for login into the application but it does not support exchanging a user password for an access & refresh token see github.com/spring-projects/spring-authorization-server/issues/126. When using the spring authorization server, a browser is needed for a user to perform a login (think OAuth login flow). The best materials to learn about it would be the spring security and spring authorization server docs.
hello, is there any tutorial or resource you recommend to add all of this into an external authentication service? instead of keeping it on same application
Hey, it sounds like you are looking for an authorization server, the one responsible for all the auth stuff, your simple backend then integrates with this auth server. Docs for the auth server are here: docs.spring.io/spring-authorization-server/docs/current/reference/html/getting-started.html
Is that possible to separate resource server and Authentication server? How does the newly added Resource Server use the existing authentication? spring.security.oauth2.resourceserver.jwt.issuer-uri=?
Excellent, great explanation. In some videos I've seen the programmers add jwt filter implementing once per request filter.. why you did not add it and whats difference ?
Thank you, the resource server already has inbuilt filters, all we have to do is configure certain beans to leverage existing filters. Other videos like you mentioned that add new filters may not be using a resource server or want to implement custom logic for token validation.
Hi! Can you please explain one moment. I get different authentication objects: in register it is user entity and password and in login it is email and password, so token can not be created correctly, what can I do?
Hello, when registering, the user does not exist in the database yet so we create an Authentication object whose auth flag is set to true and then we create the jwt tokens. When logging in, we ask the daoAuthenticationProvider to authenticate the user (username and password) against the record stored in the database, if authentication passes we proceed to generate the jwt tokens.
The video was great, but you should try the code more often as it would be easier for people to get the idea of each particular concept, one at the time
Hi, in this project I used stateless sessions. If you want to limit sessions you will have to keep track of them somehow. Have a look at this page: docs.spring.io/spring-session/docs/2.2.x/reference/html/spring-security.html
Hi, great video. I have one question. Try to run your project and get one issue during user login. Firstly, I see that user in DB save as 'username' even if I'm using 'user'. Second one during the login I retrieve 401 and log message o.s.s.a.dao.DaoAuthenticationProvider : Failed to authenticate since password does not match stored value.
if you used table that already exist in the database try to remove "username" directly from the database and rerun the app , if not check you model it may have both "user" and "username"
I didn't make any changes to the logic other than DB. Used PostgreSQL instead of MongoDb, the code is completely your implementation. I'll try to debug the app and leave comment as soon as I find the reason. Anyway, thanks for the video and the answer. Good job!)
Hello, I haven't removed any comments so not sure what happened to your comment. Anyway, according to the docs I believe there is an example config of an authorization server + resource server in one project: docs.spring.io/spring-authorization-server/docs/current/reference/html/getting-started.html, hope that helps
Great video, thanks. But why we just can't use Spring sessions in database or Redis, and http-only same-site secure session cookie ? If JWT is stolen, nothing will stop hacker in the access token lifetime period. And with sessions we can delete all user sessions. I know REST is known as "stateless". But it's not, if we want to authorize a user.
Thank you! So if you want stateless authentication you'd go for using a JWT. But if you want stateful authentication then you'd need to store session information somewhere. Each option has its own advantages and disadvantages, and the choice really depends on your use case. For example if you want to limit the number of sessions a user can have and your web app is in the browser only, you can use cookies and store session information somewhere in order to detect multiple sessions (stateful). But if you don't care about the number of sessions and you web app is a mobile app, and want to have long lived sessions, then you'd go for a stateless authentication using JWTs.
The authorization server is used for third party authorization, think "login with Facebook, login with google, etc." where other applications want to login with "your app". You still want to have a way for users to login to your app directly. If you want to add an authorisation server you'd want to configure it to use the same user's database table for authentication source. For issuing and verifying JWT's the authorisation sever does that by itself when calling the right endpoints.
Many thanks for this helpful tutorial!! Is ok to use a resource server to authenticate users? what is the correct way to check if the user exists in the db when spring is authenticating it? How can I disable authorization for certain endpoints?? with endpoints with .permitAll() if I set the header authentication for that endopoints, spring rejects me saying "Bad authentication" but that endpoints should be with the authorization check disabled. Hope you can help me! Thanks
You're welcome. Yes it's ok to use the resource server to authenticate users if you have the necessary endpoints for authentication. As long as you provide spring with a DaoAuthenticationProvider linking to your user service, spring will use the user service to look up the user in the db when authenticating. For the header issue that is due to the BearerTokenAuthenticationFilter, which looks for the authorization header in the request, if present it will try and authenticate even if the endpoint is not secure, to resolve the issue you will need to ensure the client doesn't set the authorization header for endpoints that are not secure.
When using stateless authentication like JWT, there is no session information stored in the database, therefore there is no logout operation to perform, the JWT (access token) will simply expire after a short time for example 5 minutes, afterwards that JWT will fail validation and REST API calls will fail with authentication error. Now you could store some information related to the session in the db but that kind of defeats the purpose of using JWTs. From the client side perspective, when a user clicks log out, you can clear the tokens from the local storage.
Hello, thank you very much for the video you're doing a great work. im trying to implement and oauth server where a randomly generate string is used by user and saved in the database when user login. i wanna use a manytoone to get the correct user and check if the token is expired , if the user is enable and if the have the correct roles (authority ) . how can i do that thank you in advance for the answer?
where is the randomly generated string used by the user when logging in coming from? Are you trying to implement something like a OTP (one time passcode) or one time login code for multi factor authentication?
Do you have a discord server? Also I need help running the repository. I tried to run docker and it runs the mongodb server. Then I build and start the project but got the following error. Error creating bean with name 'tokenGenerator'. I'm still new to spring boot and would appreciate some assistance to this error.
Hello, in the repo, the default active profile is "prod" and the application expects to be given the keys to use for token generation. Change the active profile to "dev" so that the application generates the keys it needs. I also updated the code in GitHub to have "dev" as the default active profile.
@@codingwmax Sorry for very late reply I haven't noticed the respond. I did that and managed to run mongodb perfectly at docker. But got the following problem on post request. No server chosen by com.mongodb.client.internal.MongoClientDelegate$1@74c1d86f from cluster description ClusterDescription{type=REPLICA_SET, connectionMode=MULTIPLE, serverDescriptions=[]}. Waiting for 30000 ms before timing out also do you have plan to try it on postgresql?
The error means the database can’t be reached. Check the docket container logs to ensure the database started correctly. I don’t have plans currently to do this with postgres, maybe in the future.
Hi Max, thanks for your videos. Question is if an IOS/android app want to use this server, does this security implementation works fine or we need another implementation?
@@ramin2881 it would be the same for iOS. What happens behind the scenes is that your mobile api client automatically gets a new access token when it expires. But for the refresh token you’d have to refresh it for example 1 week or 1 month before expiration, because once it expires you can’t refresh it anymore. This gives the impression that you are logged in forever. But if the user is inactive and the refresh token expired, the user would have to login again.
I believe you are asking why is CSRF disabled? CSRF attacks depend on browser auto authentication, e.g. when using cookies, the browser automatically authenticates requests, this is susceptible to CSRF attacks. In this video we are using JWT authentication via an "Authorization" header, which must be explicitly set for requests, the browser doesn't do this automatically and therefore we don't need CSRF protection.
Thanks a lot for this very good video. One question please: is it possible to use this authentication mechanism and combine it with Google, facebook etc ? thanks in advance
I believe it's possible yes but you may need to do a lot of wiring things together. To leverage third party logins I believe it's best to use an authorization server.
Hello, here is some code I threw together, it's untested but I hope you get the idea (note: you need to add a new dto: UserUpdateDTO): @PostMapping("/{id}") @PreAuthorize("#user.id == #id") public ResponseEntity user(@AuthenticationPrincipal User user, @PathVariable String id, @RequestBody UserUpdateDTO dto) { User retrievedUser = userRepository.findById(id).orElseThrow(); retrievedUser.setUsername(dto.getUsername()); userRepository.save(retrievedUser); return ResponseEntity.ok(UserDTO.from(retrievedUser)); }
sir, i got 2 errors, both of them are java.io.FileNotFoundException: "access-refresh-token-keys\access-token-private.key" (The filename, directory name, or volume label syntax is incorrect) "access-refresh-token-keys\access-token-public.key" (The filename, directory name, or volume label syntax is incorrect) also i got question regarding those 4 file path you create in properties file, what is its uses? to store the key like a DB? it's still fuzzy at that point sir
Hi please consider increasing your font size when recording these so that we can still read the text comfortably when not in fullscreen
Thank you for the feedback
Thanks for making. Can you make videos on spring Authorization server and fit this in microservices architecture behind the gateway. Explain oauth 2 + openid flow (from web app to auth server through gateway, can be standard or federated authorisation) and communication among resource services (client credentials grant) etc.
Excellent and great explanation .. Very useful Please create more contain like this .
Thank you
this is super helpful, concise and just what i needed. Thank you so much for making this video
Thank you 🙏
Thank you
Finally latest Spring Sec OAuth
No WebSecurityCongifAdapter
you're welcome :)
Спасибо Максим, мало примеров с рефреш токеном, обычно везде только access token
Excellent explanation ..Keep uploading new ones.👍
Thank you!
Being steady when there is happiness or failure seek peace and patience
Thanks for detailed explanation👍
thank u sir , its a great video, please continue your chanel
Nice video!Looking forward to your next video.
Thank you
Thanks for watching!
wow this is super helpful, concise and just what i needed. Can you make tutorials on everything ???
Thank you 🙏
Hey Max! Great video. I did have issues with the login end point where an 401 error is thrown. Using the debugger it said it has something to do with InvocationTargetException.
Amazing detailed tutorial
Thank you! Cheers!
Hi Max, in my implementation even after doing all the things you mentioned /token api throws 401. In the stacktrace I see the error "Failed to authenticate since the JWT was invalid" your help will be appreciated here
Hey, are you adding the "Authorization" header to the request you are making with a value of "Bearer "?
@@codingwmax Bearer and access token
can you implement using user role authorization?
Thanks for the great video. Is it possible to do this with the new spring authorization server? And a client (API gateway)-spring authorization server- with backend resources (services)?
Great suggestion
the same thing I would like to have, thanks!
can u make tutorial to use ur mongodb and docker please?
Great Content!. Thank you.
Probably keep bigger fonts next time :)
Thanks for the tip!
Hello, great curse!. when i uses postman to get the refreshToken at /token endpoint its Ok!, but when I get a 401 error in the Angular Interceptor HttpErrorResponse and i call the service that handle the post of the refreshToken, it always crash the spring server "java.lang.IllegalArgumentException: token cannot be empty", I don´t know what to do
Hello, if you follow the stacktrace, you will see what exactly it complains about. Angular is probably sending an empty refresh token.
hello, .antMatchers is no longer supported by spring security , what is the alternative , although i tried using .requestMatchers and mvcMatchers and got 401 in postman
Hello, based on the docs docs.spring.io/spring-security/reference/5.8/servlet/authorization/authorize-http-requests.html you can simply replace the use of ".antMatchers" with ".requestMatchers"
Sir, mongodb uri you mention to connect the db is not working. Could you help me with this please?
Hello, please check the source code linked in the description for the url to use
Thank you so much, can you do with Spring Authorization Server in microservices ?
Can you please explain. It turns out that the resource server here is also an authorization server, because it generates tokens? Will you make a video in which you will show an example of a separate own authorization server. Or you can suggest materials where the implementation of your own authorization server is shown, please
Yes in this example the resource server acts as an authorization server, it allows exchanging a user password for an access & refresh token.
An own spring authorization server can also be used for login into the application but it does not support exchanging a user password for an access & refresh token see github.com/spring-projects/spring-authorization-server/issues/126.
When using the spring authorization server, a browser is needed for a user to perform a login (think OAuth login flow). The best materials to learn about it would be the spring security and spring authorization server docs.
Greate explanation!
Thank you 🙏
Great !!
Fantastic. I did some changes like use mysql without docker. thank you.
Great to hear!
nicely explained , Thanks👍
You are welcome
yo, is it possible implement logout? How can I do it?
hello, is there any tutorial or resource you recommend to add all of this into an external authentication service? instead of keeping it on same application
Hey, it sounds like you are looking for an authorization server, the one responsible for all the auth stuff, your simple backend then integrates with this auth server. Docs for the auth server are here: docs.spring.io/spring-authorization-server/docs/current/reference/html/getting-started.html
Is that possible to separate resource server and Authentication server? How does the newly added Resource Server use the existing authentication? spring.security.oauth2.resourceserver.jwt.issuer-uri=?
Excellent, great explanation. In some videos I've seen the programmers add jwt filter implementing once per request filter.. why you did not add it and whats difference ?
Thank you, the resource server already has inbuilt filters, all we have to do is configure certain beans to leverage existing filters. Other videos like you mentioned that add new filters may not be using a resource server or want to implement custom logic for token validation.
Thank you. your video a help me to much.
You’re very welcome 🙏
Hi! Can you please explain one moment. I get different authentication objects: in register it is user entity and password and in login it is email and password, so token can not be created correctly, what can I do?
Hello, when registering, the user does not exist in the database yet so we create an Authentication object whose auth flag is set to true and then we create the jwt tokens.
When logging in, we ask the daoAuthenticationProvider to authenticate the user (username and password) against the record stored in the database, if authentication passes we proceed to generate the jwt tokens.
"EnableGlobalMethodSecurity" is deprecated....
yep, now we must use EnableMethodSecurity
The video was great, but you should try the code more often as it would be easier for people to get the idea of each particular concept, one at the time
Thanks for the tip!
How to unit test this implementation?
Hi @Max, I just want to ask how you can limit the number of active session of a user on this project?
Hi, in this project I used stateless sessions. If you want to limit sessions you will have to keep track of them somehow. Have a look at this page: docs.spring.io/spring-session/docs/2.2.x/reference/html/spring-security.html
Hi Thanks for the session. Do you have postman collection for this?
Hello, sorry I don't, I will try to provide one next time.
Hi, great video.
I have one question.
Try to run your project and get one issue during user login.
Firstly, I see that user in DB save as 'username' even if I'm using 'user'.
Second one during the login I retrieve 401 and log message o.s.s.a.dao.DaoAuthenticationProvider : Failed to authenticate since password does not match stored value.
if you used table that already exist in the database try to remove "username" directly from the database and rerun the app , if not check you model it may have both "user" and "username"
Thank you.
Not sure about the issues without seeing the code, do you have the code available on GitHub?
I didn't make any changes to the logic other than DB. Used PostgreSQL instead of MongoDb, the code is completely your implementation.
I'll try to debug the app and leave comment as soon as I find the reason.
Anyway, thanks for the video and the answer. Good job!)
@Max I think you don't like my question as you have removed from here. is any specific reason you removed?
Hello, I haven't removed any comments so not sure what happened to your comment. Anyway, according to the docs I believe there is an example config of an authorization server + resource server in one project: docs.spring.io/spring-authorization-server/docs/current/reference/html/getting-started.html, hope that helps
so OAuth2 with monitoring using Prometheus & Grafana, please!
Great video, thanks. But why we just can't use Spring sessions in database or Redis, and http-only same-site secure session cookie ? If JWT is stolen, nothing will stop hacker in the access token lifetime period. And with sessions we can delete all user sessions. I know REST is known as "stateless". But it's not, if we want to authorize a user.
Thank you!
So if you want stateless authentication you'd go for using a JWT. But if you want stateful authentication then you'd need to store session information somewhere. Each option has its own advantages and disadvantages, and the choice really depends on your use case. For example if you want to limit the number of sessions a user can have and your web app is in the browser only, you can use cookies and store session information somewhere in order to detect multiple sessions (stateful). But if you don't care about the number of sessions and you web app is a mobile app, and want to have long lived sessions, then you'd go for a stateless authentication using JWTs.
Any idea how can we integrate this with spring oauth2 authorization server?
The authorization server is used for third party authorization, think "login with Facebook, login with google, etc." where other applications want to login with "your app". You still want to have a way for users to login to your app directly. If you want to add an authorisation server you'd want to configure it to use the same user's database table for authentication source. For issuing and verifying JWT's the authorisation sever does that by itself when calling the right endpoints.
Many thanks for this helpful tutorial!! Is ok to use a resource server to authenticate users? what is the correct way to check if the user exists in the db when spring is authenticating it? How can I disable authorization for certain endpoints?? with endpoints with .permitAll() if I set the header authentication for that endopoints, spring rejects me saying "Bad authentication" but that endpoints should be with the authorization check disabled. Hope you can help me! Thanks
You're welcome.
Yes it's ok to use the resource server to authenticate users if you have the necessary endpoints for authentication.
As long as you provide spring with a DaoAuthenticationProvider linking to your user service, spring will use the user service to look up the user in the db when authenticating.
For the header issue that is due to the BearerTokenAuthenticationFilter, which looks for the authorization header in the request, if present it will try and authenticate even if the endpoint is not secure, to resolve the issue you will need to ensure the client doesn't set the authorization header for endpoints that are not secure.
or any path to add the /logout endpoint?
When using stateless authentication like JWT, there is no session information stored in the database, therefore there is no logout operation to perform, the JWT (access token) will simply expire after a short time for example 5 minutes, afterwards that JWT will fail validation and REST API calls will fail with authentication error. Now you could store some information related to the session in the db but that kind of defeats the purpose of using JWTs. From the client side perspective, when a user clicks log out, you can clear the tokens from the local storage.
Hello, thank you very much for the video you're doing a great work. im trying to implement and oauth server where a randomly generate string is used by user and saved in the database when user login. i wanna use a manytoone to get the correct user and check if the token is expired , if the user is enable and if the have the correct roles (authority ) . how can i do that thank you in advance for the answer?
where is the randomly generated string used by the user when logging in coming from? Are you trying to implement something like a OTP (one time passcode) or one time login code for multi factor authentication?
Super !))
Many thanks!!
Do you have a discord server? Also I need help running the repository.
I tried to run docker and it runs the mongodb server. Then I build and start the project but got the following error.
Error creating bean with name 'tokenGenerator'. I'm still new to spring boot and would appreciate some assistance to this error.
Hello, in the repo, the default active profile is "prod" and the application expects to be given the keys to use for token generation. Change the active profile to "dev" so that the application generates the keys it needs. I also updated the code in GitHub to have "dev" as the default active profile.
@@codingwmax Sorry for very late reply I haven't noticed the respond. I did that and managed to run mongodb perfectly at docker. But got the following problem on post request.
No server chosen by com.mongodb.client.internal.MongoClientDelegate$1@74c1d86f from cluster description ClusterDescription{type=REPLICA_SET, connectionMode=MULTIPLE, serverDescriptions=[]}. Waiting for 30000 ms before timing out
also do you have plan to try it on postgresql?
The error means the database can’t be reached. Check the docket container logs to ensure the database started correctly. I don’t have plans currently to do this with postgres, maybe in the future.
Hi Max, thanks for your videos.
Question is if an IOS/android app want to use this server, does this security implementation works fine or we need another implementation?
Yes this would absolutely work as a backend for a mobile application.
@@codingwmax in Android apps once user logs in he is logged in for ever!! Whats happening behind the scene?
@@ramin2881 it would be the same for iOS. What happens behind the scenes is that your mobile api client automatically gets a new access token when it expires. But for the refresh token you’d have to refresh it for example 1 week or 1 month before expiration, because once it expires you can’t refresh it anymore. This gives the impression that you are logged in forever. But if the user is inactive and the refresh token expired, the user would have to login again.
Excellent, great explanation... please can you do it with JWT?
Hello, thank you. Can you please explain what you mean? We are using jwt tokens in this video for both access tokens and refresh tokens.
@@codingwmax sorry wrong video, my bad
No problem 👍
sound is quiet, nothing changes when i turn the sound up, make it louder next time please
Why can we enable CSRF?
I believe you are asking why is CSRF disabled?
CSRF attacks depend on browser auto authentication, e.g. when using cookies, the browser automatically authenticates requests, this is susceptible to CSRF attacks. In this video we are using JWT authentication via an "Authorization" header, which must be explicitly set for requests, the browser doesn't do this automatically and therefore we don't need CSRF protection.
Thanks a lot for this very good video. One question please: is it possible to use this authentication mechanism and combine it with Google, facebook etc ? thanks in advance
I believe it's possible yes but you may need to do a lot of wiring things together. To leverage third party logins I believe it's best to use an authorization server.
Can u do one video email implementation jwt using spring boot
Hello, could you please explain a bit more the email part? Thanks
hello, I watched all your videos, thank you very much for the information. I'm trying to do user update but I can't. Can you help me write updateuser?
Hello, here is some code I threw together, it's untested but I hope you get the idea (note: you need to add a new dto: UserUpdateDTO):
@PostMapping("/{id}")
@PreAuthorize("#user.id == #id")
public ResponseEntity user(@AuthenticationPrincipal User user, @PathVariable String id, @RequestBody UserUpdateDTO dto) {
User retrievedUser = userRepository.findById(id).orElseThrow();
retrievedUser.setUsername(dto.getUsername());
userRepository.save(retrievedUser);
return ResponseEntity.ok(UserDTO.from(retrievedUser));
}
@@codingwmax Thank you sir, I solved it with a similar code.
sir, i got 2 errors, both of them are java.io.FileNotFoundException:
"access-refresh-token-keys\access-token-private.key" (The filename, directory name, or volume label syntax is incorrect)
"access-refresh-token-keys\access-token-public.key" (The filename, directory name, or volume label syntax is incorrect)
also i got question regarding those 4 file path you create in properties file, what is its uses? to store the key like a DB? it's still fuzzy at that point sir