Spring Security JDBC: How to authenticate against a database in Spring Boot
HTML-код
- Опубликовано: 15 сен 2022
- Learn how to authenticate against a database in Spring Boot. In previous tutorials, I have used an in-memory user which works great for demos and proof of concepts but doesn't work for production. What happens when you move your users to a database? You could start from scratch or use the JdbcUserDetailsManager class which is built-in to Spring Security.
🔗Resources & Links mentioned in this video:
Github: github.com/danvega/jdbc-users
WebSecurityConfigurerAdapter Changes: • Spring Security withou...
👋🏻Connect with me:
Website: www.danvega.dev
Twitter: / therealdanvega
Github: github.com/danvega
LinkedIn: / danvega
Newsletter: www.danvega/dev/newsletter
SUBSCRIBE TO MY CHANNEL: bit.ly/2re4GH0 ❤️ - Наука
Thank you Dan! Your video, as always, so precious and helpful!!!
Hi Dan, awesome stuff, following your spring security tutorials I managed to succesfully secure a graphApi using a neo4j no-sql db. Question though, while using a graph, I still have rest endpoints for authentication. I've always been told to choose one or the other and the same could be achieved with querries, I guess my question is would it be best practice to loose the restendpoints?
I see new Dan's video i hit the like button
You're the best! Thank you!
@Dan Vega do you recommend using records for controllers and services in Spring Boot if we are using Java 14+ or only for DTOs and POJOs?
You will need to be on 16+ and yes, anywhere possible and where it makes sense I would take advantage of records.
Thanks, very useful video.
You're welcome!
Hi Dan - Excellent video, thanks for posting. Ran into an issue, I followed the sequence and see the username/password (admin/encrypted pwd) in H2 console. However whenever I try to login it throws "Bad Credentials" sometimes and goes back to the login screen. FYI, I had no issue with InMemoryUserDetailsManger users. Any clue?
I hope u have found it by now 😅 but for others getting this problem turning your spring security logs on helped me, for me the issue was that my user had no Authority thus seen as not found.
hi Dan! thanks for tutorial. but how we could setup datasource using Postgres? is it applicable at all or only embedded solutions are supported?
You can use any relational database for this that Spring supports. I just published a video that walks through setting up a PostgreSQL database using Docker. That should help out but if it doesn't let me know.
awesome! I have to ask though! any plans to get into spring boot REST_API request exception handling?
Yes, let me get that topic added to my backlog. Thanks for the suggestion.
That was super helpful.
Glad it was helpful!
Hello Dan, Great video! I have one question. If I want user to have more fields rather than username, password and roles, like first name, last name, phone number, etc. What should I do? I thought about creating separate table and referencing username as a foreign key there, but don't know if it's the best solution possible.
This is where I would probably roll my own UserDetailsService. I have that in my backlog as the next video in this series.
Hi Dan great series of videos do you think you could make some security tutorials or even a security course that has all best production ready practices? I have been trying to find something like that and so far I have found only one but is like 500 dollar course. I think even if I had to pay but a lesser fee that 500 dollars I would goadly pay it to get everything on spring security even confirmation passwords change passwords and all the besr practices.
Great suggestion! github.com/danvega/office-hours/discussions/43
Thanks Dan.
If possible, please make a video on the following topics
1. For the Spring OAuth2 client, we have properties like spring.security.oauth2.client.registration.{partner}.client-id. If the OAuth endpoint takes any non-standard parameter like audience then how can I do that?
2. If I have 2 microservices and both of them have 1 DB table each but these 2 tables are joined with foreign key, then how can I do that in my springboot application.
1. I don't have any experience with that so I don't have much of an answer for you there.
2. A microservice is an independent service with its own database. There are distributed architectures that share databases but in the true sense of a microservice each service should be independently deployable.
@@DanVega Thank you
Thanks for the awesome videos and contents Dan! That would be great to see oauth2 - mutlitenancy videos if possible. Cheers
Thanks Dan
Just curious, what is the auth -> auth suppose to be? I also really appreciate the content! Trying to learn spring security isn't easy at all.
it is just a lambda expression as far as i can tell to provide an implementation for the customizer functional interface
Hi Dan I followed your steps but ima trying to open the h2-console with auth page but it's not comming what is the problem
Why i get this error?:
Field uRepo in com.example.api.controller.HomeController required a bean of type 'com.example.api.repository.UserRepository' that could not be found.
Hi Dan. I followd your totorail but I cannot connect to the embedded h2 console database. Do you know why that might be? It says not found
I have a video about connecting to an embedded h2 database. Maybe that might help clear some things up. Hope you figured this one out.
My main problem is that I need to use a custom schema where my table names and columns are different from the default schema, I do not want to use an in-memory database. I am using an existing database. I keep getting an SQL error saying column name "enabled" doesn't exist. My application keeps trying to use the default schema instead of my custom schema. Do you have any resources for my situation?
This class is meant to get you up and running quickly. If you want to provide your own schema you can implement the UserDetails interface and provide your own. I don't have a video on this but I will add it to my backlog.
@Dan Vaga, I request you to make a tutorial on new Spring Authentication/Authorization Server, as you are creating Spring security based videos, it will be very helpful. Again thanks for the new and nice tutorial, you always show the right and efficient way to do things with spring boot.
Appreciate the feedback. I will add it to the backlog.
Thanks Dan for very useful video. Can you please show us how to invalidate/blacklisting of JWT token for logout proper way?
It can be tricky to use JWTs for session management because there is no idea of a session. You could ask a separate service with the JWT is still valid either using introspection or by maintaining a revocation list. At this point though you might want to start asking the question "Would moving to an authorization server be a better solution"
kindly give a video of implementation using daoauthenticationprovider
There is no USERS table after manually defining the datasource for me..?
@Bean
DataSource datasource() {
return new EmbeddedDatabaseBuilder()
.setType(H2)
.addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
.build();
}
Yes excellence explanation but in the controller still hardcoded the role. How to dyana mic the hasrole in Controller? Thanks
Just curious what your use case is to have a dynamic role there? It could be done but usually I know what the role or roles is that should be guarding that method.
Dan this works until your data source comes from JPA then you get conflict. Anyhow have a quick workaround?
Yes, you won't be able to use this approach for that. In that case you will need to build out your own users / roles and implement UserDetailsService. I have that video in my backlog.
@@DanVega Cool. I would also like to see how to combine an AuditorAware to use the previous videos on customized UserDetails. I am looking to leverage the usage of annotations like @CreatedBy and @LastModifiedBy etc. This is critical for any application that has objects that need auditing. Generally I use a base entity to handle those universal entity properties.
How can this API be called from Postman or from another codebase?
Thanks you
How can we enable CORS for everything in Spring Boot?
You can create a bean in that Security Configuration class
docs.spring.io/spring-security/reference/reactive/integrations/cors.html
you don`t use postman, i try with postman, basic authentication, but i can`t pass de default form login, can someone help me, please
I was looking for the same.
@Component
public final class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
Instead of using .formLogin use this
.httpBasic(httpSecurityHttpBasicConfigurer -> httpSecurityHttpBasicConfigurer.authenticationEntryPoint(authenticationEntryPoint))
U won't get basic auth form in browser but curl works for me.
curl -i --user admin:password localhost:8080/api/v1/info
Found better solution for all those working with basic auth just use this instead of `formLogin`
.httpBasic(
httpSecurityHttpBasicConfigurer -> {
BasicAuthenticationEntryPoint basicAuthenticationEntryPoint = new BasicAuthenticationEntryPoint();
basicAuthenticationEntryPoint.setRealmName("test");
httpSecurityHttpBasicConfigurer.authenticationEntryPoint(
basicAuthenticationEntryPoint);
})
Cannot resolve symbol 'auth' 3:28
Usually your tutorials are great!
But example like this does not help to figure out real things.
Working with mysql or postgres wouldn't have been longer or more complex than this abstract example.
But thanks for your work anyway!
Any idea how to get this to work with mySQL? I'm stuck at the part where he creates a custom datasource, whenever I try to log in it will just tell me that there is no AuthenticationProvider.
an Inmemory database, which no one would ever use..
I had an issue accessing the H2 console using Spring Boot 3.0.1, using authorizeHttpRequests and requestMatchers. I was being redirected to the login page, even with the "/h2-console/**" patterns. If you're here looking for a solution to this, the solution that worked for me was to import toH2Console() from org.springframework.boot.autoconfigure.security.servlet.PathRequest and use that instead of the "/h2-console/**" paths:
import static org.springframework.boot.autoconfigure.security.servlet.PathRequest.*;
return http.csrf(csrf -> csrf.ignoreRequestMatchers(toH2Console()))
.authorizeHttpRequests(auth -> auth
.requestMatchers(toH2Console()).permitAll()
.anyRequest().authenticated()
)
.headers(headers -> headers.frameOptions().sameOrigin())
.formLogin(withDefaults())
.build();
Thanks RM, got stucked there too but now it is solved!