hi! this type of tutorials are amazing :) definitely better than skipping and showing copy-paste code of any app :) helps people to get to know how to learn instead of just how to solve particular problem. subbed for future :)
Immediately subscribed ❤❤ I hate these "typer" videos without explaining where and why and how, this is very much like a proper engineer style ! Well done 👍👍👍👍✔✔
Hello, thank you for this! And yes, this is better, at least for me since it can help me learn extensively when I explore the materials by myself afterwards. Even just pointing out where to reference which stuff is helpful enough. Once again, thanks a lot!
Thanks. It is a good tutorial. I would recommend to increase the font size for recording the video, is very difficult to see the code, even on a monitor (dont even try to do it on my phone). Also I've got a question, now that you got the info, what should be the next steps?
There are multiple things you can do with the attributes, but one example is that you can use the "sub" property as a unique identifier for the user if you want to save user preferences or other actions to the database with that ID.
I would need to read some of the open source code to see where they are stashing it. However, Java Spring should be managing the token for you and determining when the session has expired. Do you need it for something else?
Thank you for the tutorial! I'm building an application that has Users stored in my database with specific UserRoles, and I want to be able to authenticate with google to require the access token for each request. How would I go about assigning these authorities to specific users in my database based on the UserRole?
You could store the user information that you get back from Google and then use that to fetch a role that you assign the user that you would store in your database.
Hey, I've setup OAuth 2 with google on the backend, However i'm so confused on how can we access restricted endpoints on the front end. I can authenticate in spring but i believe there's a gap in knowledge of how can our frontend app redirect to this backend login and once it's authorized get the protected endpoint data?
One question though, once the authentication is done, how do you manage authorizations of users ? google and facebook (let's say) probably do not have the same GrantedAuthorities in their models. *a)* you need a database of your own to CRUD authorizations _or_ *b)* you write data to google or facebook's own user repositories so that at login time they are given back to you. Any comments ?
I haven't dug into this recently, but the last time that I looked into it, you still had to manage your own roles. For my implementation this involved using my own database as you already assumed and then checking to see which role the user had after Google confirmed the user identity.
@@stonedcodingtom9097 I haven't really thought about it. Spring is a fairly well maintained open source community so I typically don't bother to recreate features that it already provides. Similarly, in JavaScript I would have probably used Passport.js for Google Auth: www.passportjs.org/concepts/authentication/google/
Hello @Tech Tutor , From your implementation how can I further call the Endpoint in Postman or Browser to get the User detail from google and save it automatically into my database for future login?
In the controller you can take that Map object that is coming from getAttributes and save it using a repository layer. For best practice, I would suggest autowiring in a Service to your controller and then autowiring a Repository class into your Service to perform the save. There are some other videos on my channel that show how to easily add a database to a Spring Boot project.
Do you know how can I manually redirect the request? I have only a specific case to redirect to an AuthProvider (many if elses), so I don't want Spring/SpringSecurity to handle the auto-redirect.
Are you using the same Maven dependency that I used in the video? If you are, then the code from that dependency uses Spring Security, so I would highly suggest using Spring Security to configure any security chains.
@@TechTutorRyan yes I'm using Spring Security, also not limited on using any external library. I have one @PostMapping("/login"), which does multiple (different) authentications (2 databases, 1 SOAP request), and the last case (depending on user's configuration on previous database checks) might be an OpenID redirect to ADFS. Currently I handle the flow by calling different service classes, but I'm stuck at the ADFS redirection/authentication step. I don't know if this is achievable using Spring Security filters :/
If I am understanding your question, it sounds like you want to redirect based on the authentication that was used? I think you may be able to do something like this: @RequestMapping("/") public String page() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth instanceof SomeAuthenticationToken) return "someAuthPage"; if (auth instanceof SomeOtherAuthenticationToken) return "someOtherAuthPage"; }
You may also be able to set a specific redirect for each auth method using defaultSuccessUrl: docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/configurers/AbstractAuthenticationFilterConfigurer.html#defaultSuccessUrl-java.lang.String-
@@TechTutorRyan actually it is much simpler/primitive, the following 'pseudocode' describes the workflow: @PostMapping("/") public Boolean login(@RequestBody Login login) { if(login.getProperty1() == xx) //internal auth return isFirstAuthOk(login); var sourceDb2 = db2GetInfo(login.getUsername); if(sourceDb2.getProperty2() == xx) //external service auth return isAuthUsingSoap(login); //if you reached this step, do an ADFS/OpenID redirect //todo: open ADFS login page and handle auth/token response } My initial approach was to use LDAP, which has an "authenticate(username, password)" approach, but it didnt support SSO (Single Sign On) which is the next step :(
Hi Ryan, thanks for making this tutorial, it was very helpful. One thing I would like to do is create a working logout button, do you know how to do this correctly?
Hello! I just created a new video showing how to logout. I didn't create a button for it, but it would be very simple. All you need to do is create a button that leads the user to "{{siteURL}}/logout". Here is the new video for reference: ruclips.net/video/OtFLR-MReI0/видео.html
I didn't push this one to my git. It actually isn't that much code though. If you use follow along in the video and use Spring Initializr, it will basically generate all of the code you need except for the changes to the application.yml file, which you will still need to change to match your Google account. Let me know if you have any trouble after trying the steps in the video.
Hello, thank you for your video. I have this problem: antMatchers in my security config block redirecting to google login, how can I solve this? code: .antMatchers("/api/login","/api/register","/").permitAll() .antMatchers(HttpMethod.GET, "/api/v1/teachers").hasAuthority("admin") //block google login
make a new class, say AuthHandlar: import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; public class AuthHandlar extends SimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler { public AuthHandlar(){ super(); setUseReferer(false); // do not redirect user to same endpoint when request occurs } } Then in in securityConfigin class do the following -> httpSecurity.oauth2Login() .successHandler(new AuthHandlar()).and()....etc
Try using this @Configuration @EnableWebSecurity public class AppConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().authorizeRequests().antMatchers("/endpoint name").permitAll() //endpoints where you want to disable security .anyRequest().authenticated() .and() .oauth2Login().permitAll(); } }
I have a similar method to yours: @GetMapping("/auth") public Map loginTest(OAuth2AuthenticationToken authentication) { return authentication.getPrincipal().getAttributes(); } Setting spring.security.oauth2.client.registration.google.redirect-uri=localhost:8080/oauth2/callback/google property and localhost:8080/oauth2/callback/google in the API console uri redirect. And was not able to pass the login. I see the google form, but when I log in, I get the next message: "Error 400: redirect_uri_mismatch"
@@TechTutorRyan The issue was: The redirect URI was blocked by spring boot as an URI that required authentication. So that would redirect into the login, and there was the endless loop. I had to create a configuration class with the following: http.authorizeRequests() .anyRequest().authenticated() .and() .oauth2Login(); And now its working. Thanks anyways.
@@FellTheSky that updating the google api console and that change being present can take some time. Generally only a few minutes but sometimes it seems longer.
hi! this type of tutorials are amazing :) definitely better than skipping and showing copy-paste code of any app :) helps people to get to know how to learn instead of just how to solve particular problem.
subbed for future :)
Super helpful how you explain how to find stuff. I wish every tutorial was like this
Immediately subscribed ❤❤ I hate these "typer" videos without explaining where and why and how, this is very much like a proper engineer style ! Well done 👍👍👍👍✔✔
great tutorial, best one on this topic. took too long to find
Hello, thank you for this! And yes, this is better, at least for me since it can help me learn extensively when I explore the materials by myself afterwards. Even just pointing out where to reference which stuff is helpful enough. Once again, thanks a lot!
It's helpful. Thank you!
But how we can get access token and use it in future ?
example: use for google API driver
Hi, thanks a lot for your tutorial, you helped me a lot. Greetings from Ukarine :)
Thank you very much. This was very helpful.
You're welcome!
Thanks. It is a good tutorial. I would recommend to increase the font size for recording the video, is very difficult to see the code, even on a monitor (dont even try to do it on my phone). Also I've got a question, now that you got the info, what should be the next steps?
There are multiple things you can do with the attributes, but one example is that you can use the "sub" property as a unique identifier for the user if you want to save user preferences or other actions to the database with that ID.
Great video, Thank you so much
You're very welcome!
Hi, thank you for the tutorial. Just a question, how to get the token value in Principal? I couldn't find the method in OAuth2AuthenticationToken
I would need to read some of the open source code to see where they are stashing it. However, Java Spring should be managing the token for you and determining when the session has expired. Do you need it for something else?
Thank you for the tutorial! I'm building an application that has Users stored in my database with specific UserRoles, and I want to be able to authenticate with google to require the access token for each request. How would I go about assigning these authorities to specific users in my database based on the UserRole?
You could store the user information that you get back from Google and then use that to fetch a role that you assign the user that you would store in your database.
Hey, I've setup OAuth 2 with google on the backend, However i'm so confused on how can we access restricted endpoints on the front end. I can authenticate in spring but i believe there's a gap in knowledge of how can our frontend app redirect to this backend login and once it's authorized get the protected endpoint data?
Got any solution?
Yeah I started using .net 😅
You are the best
One question though, once the authentication is done, how do you manage authorizations of users ? google and facebook (let's say) probably do not have the same GrantedAuthorities in their models. *a)* you need a database of your own to CRUD authorizations _or_ *b)* you write data to google or facebook's own user repositories so that at login time they are given back to you. Any comments ?
I haven't dug into this recently, but the last time that I looked into it, you still had to manage your own roles. For my implementation this involved using my own database as you already assumed and then checking to see which role the user had after Google confirmed the user identity.
Thank you very much!
Nice tutorial, thx!
You're welcome!
@@TechTutorRyan Are u planning to create tutorial for oauth2 without spring? I mean oauth2 just for desktop java app.
@@stonedcodingtom9097 I haven't really thought about it. Spring is a fairly well maintained open source community so I typically don't bother to recreate features that it already provides.
Similarly, in JavaScript I would have probably used Passport.js for Google Auth:
www.passportjs.org/concepts/authentication/google/
@@TechTutorRyan Okay, thank you for reply. Have a nice day!
Hello @Tech Tutor , From your implementation how can I further call the Endpoint in Postman or Browser to get the User detail from google and save it automatically into my database for future login?
In the controller you can take that Map object that is coming from getAttributes and save it using a repository layer. For best practice, I would suggest autowiring in a Service to your controller and then autowiring a Repository class into your Service to perform the save. There are some other videos on my channel that show how to easily add a database to a Spring Boot project.
Do you know how can I manually redirect the request? I have only a specific case to redirect to an AuthProvider (many if elses), so I don't want Spring/SpringSecurity to handle the auto-redirect.
Are you using the same Maven dependency that I used in the video? If you are, then the code from that dependency uses Spring Security, so I would highly suggest using Spring Security to configure any security chains.
@@TechTutorRyan yes I'm using Spring Security, also not limited on using any external library.
I have one @PostMapping("/login"), which does multiple (different) authentications (2 databases, 1 SOAP request), and the last case (depending on user's configuration on previous database checks) might be an OpenID redirect to ADFS. Currently I handle the flow by calling different service classes, but I'm stuck at the ADFS redirection/authentication step. I don't know if this is achievable using Spring Security filters :/
If I am understanding your question, it sounds like you want to redirect based on the authentication that was used? I think you may be able to do something like this:
@RequestMapping("/")
public String page() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof SomeAuthenticationToken)
return "someAuthPage";
if (auth instanceof SomeOtherAuthenticationToken)
return "someOtherAuthPage";
}
You may also be able to set a specific redirect for each auth method using defaultSuccessUrl:
docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/configurers/AbstractAuthenticationFilterConfigurer.html#defaultSuccessUrl-java.lang.String-
@@TechTutorRyan actually it is much simpler/primitive, the following 'pseudocode' describes the workflow:
@PostMapping("/")
public Boolean login(@RequestBody Login login) {
if(login.getProperty1() == xx) //internal auth
return isFirstAuthOk(login);
var sourceDb2 = db2GetInfo(login.getUsername);
if(sourceDb2.getProperty2() == xx) //external service auth
return isAuthUsingSoap(login);
//if you reached this step, do an ADFS/OpenID redirect
//todo: open ADFS login page and handle auth/token response
}
My initial approach was to use LDAP, which has an "authenticate(username, password)" approach, but it didnt support SSO (Single Sign On) which is the next step :(
Hi Ryan, thanks for making this tutorial, it was very helpful. One thing I would like to do is create a working logout button, do you know how to do this correctly?
Hello! I just created a new video showing how to logout. I didn't create a button for it, but it would be very simple. All you need to do is create a button that leads the user to "{{siteURL}}/logout".
Here is the new video for reference:
ruclips.net/video/OtFLR-MReI0/видео.html
Can I get the Git Link?
I didn't push this one to my git. It actually isn't that much code though. If you use follow along in the video and use Spring Initializr, it will basically generate all of the code you need except for the changes to the application.yml file, which you will still need to change to match your Google account. Let me know if you have any trouble after trying the steps in the video.
Helllo, Why ? -> Invalid Redirect: must contain a domain
It sounds like you may have missed a step configuring your Google Settings.
Hello, thank you for your video. I have this problem: antMatchers in my security config block redirecting to google login, how can I solve this?
code:
.antMatchers("/api/login","/api/register","/").permitAll()
.antMatchers(HttpMethod.GET, "/api/v1/teachers").hasAuthority("admin") //block google login
make a new class, say AuthHandlar:
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
public class AuthHandlar extends SimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
public AuthHandlar(){
super();
setUseReferer(false); // do not redirect user to same endpoint when request occurs
}
}
Then in in securityConfigin class do the following ->
httpSecurity.oauth2Login()
.successHandler(new AuthHandlar()).and()....etc
Try using this
@Configuration
@EnableWebSecurity
public class AppConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/endpoint name").permitAll() //endpoints where you want to disable security
.anyRequest().authenticated()
.and()
.oauth2Login().permitAll();
}
}
I have a similar method to yours:
@GetMapping("/auth")
public Map loginTest(OAuth2AuthenticationToken authentication) {
return authentication.getPrincipal().getAttributes();
}
Setting spring.security.oauth2.client.registration.google.redirect-uri=localhost:8080/oauth2/callback/google property
and localhost:8080/oauth2/callback/google in the API console uri redirect.
And was not able to pass the login. I see the google form, but when I log in, I get the next message:
"Error 400: redirect_uri_mismatch"
/auth is the issue
Yes, I agree with Karthik, /auth is likely the issue without being able to see the rest of the code.
@@TechTutorRyan The issue was: The redirect URI was blocked by spring boot as an URI that required authentication. So that would redirect into the login, and there was the endless loop.
I had to create a configuration class with the following:
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login();
And now its working. Thanks anyways.
@@FellTheSky that updating the google api console and that change being present can take some time. Generally only a few minutes but sometimes it seems longer.