Spring Security JDBC: How to authenticate against a database in Spring Boot

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
lately I've been creating a lot of tutorials on Spring Security in those tutorials I've used an in-memory user to authenticate with this is great for demos but not really a awesome solution in the real world so what we're going to do today is move away from that in-memory user and talk about how we can store users in a database welcome back friends my name is Dan Vega and I'm a spring developer advocate for VMware as I mentioned we're going to move away from that in-memory user today and what we're going to do is create a new project we'll include spring web we'll include Spring Security and we'll talk about this class that we have called the jdbc user details manager similar to that in memory one but this gives us the ability to store our users in a database so I'm really excited about this again a lot of the tutorials I've been working on lately have been Spring Security related but I get a lot of questions like this is great Dan this is a good start but I need to do this or I need to do that and you know this has been with intention we gotta establish a baseline of what we're doing here in Spring Security and then we'll start to say well for the situation that you're in maybe you need to do that so that situation that you're in today you're probably not using an in-memory user you want to store users in the database but you don't want to create the entities by yourself you don't want to write all the SQL that goes along with that this is what that's going to give you it's going to give you all that right out of the box and I think you're really going to enjoy this as always all the links to anything that we're going to talk about will be in the description below along with the GitHub repository with all the code that we're going to go through today so what are we waiting for let's start writing some code all right we're going to get started as we always do at start.spring.io I am using Java I mean using the latest stable version of spring boot which is 2.7.3 at the time of this recording we're going to fill in some metadata here I'm going to say dev.dan Vega we're going to call this jdbc users everything else looks good we just need a couple dependencies here we're going to use spring web and we're also going to bring in Spring Security that should be enough I'm going to go ahead and hit generate and that will go ahead and download me a zip and I'll go ahead and open this up in my favorite IDE IntelliJ you can open it up in whatever text editor or ID you're most productive in all right I have the application open here I'm going to go ahead and start by creating a new configuration package so let's say package config in here I'm going to create a new Java class and we're going to call this security config and I'll go ahead and Mark this as at configuration and at enable web security again this is something we've been doing a lot in in recent videos that have been created if this looks new to you if you're used to kind of extending the web security configure adapter I will go ahead and link to a video below that you can watch on some of the changes that we've made in the security configuration but what we're going to do here is to make this happen we're going to register a bean of type security filter chain and we'll call the security filter chain and that is going to take in our HTTP security as an argument and what we're going to end up doing is returning http.build and here's where we're going to go ahead and kind of customize our security so I'm going to start with authorized requests and what I want to do in here is I'm going to go ahead and pass off and I'm going to say oops auth and then we can come down here and say any request we want to go ahead and be authenticated right so we want to be authenticated for any request this is going to have to throw an exception and then let's go ahead and add a form login so that when we go ahead and visit a particular route we're presented with a nice form login and we'll say with defaults and I'm going to make that aesthetic import just to clean things up and then we go ahead and build that and that is what we return so that's a good start that will kind of lock down any request so what I want to do is go ahead and set up a controller so we can uh have a request to authenticate against so let's go ahead and create a new package we'll call this controller in this controller package I'm going to create a new class called home controller just a simple one we'll mark this with that rest controller and then what I'm going to do is create two methods in here we'll say public string home and this is going to return hello world and this is going to be a git mapping so that will be at the root context and then what I'll do is create one more and this will be for slash admin which we are going to come back to a little bit later but while we're here we can go ahead and set this up so I'll just return uh hello admin when I'm in here so that is everything that we should need to get started if we go ahead and run our application here what we're going to see is it starts up but it also generates this password so by default anytime that you kind of introduce Spring Security spring boot is going to set up a default user for you with the username of user and this randomly generated password and the reason we do this is we don't want you to end up taking this to production with some username and password that could be Googled so I'm going to go back to the browser and go to localhost 8080 and you see no matter what route I go ahead and try to hit it is going to reroute me to the login page that is what we get when we use the form login security configuration so as I said default users user and that randomly generated password and you can see we are now authenticated so so far nothing new right now what I want to do is go into my security configuration and do something that we would have done in the past just to kind of show the progression in case you're new around here I'm going to go ahead and use an in-memory user details manager we'll call this users and in here I'm just going to return a new in-memory UT user details manager rolls right off the tongue and what we're going to do is we'll use this user dot with username and so we'll pass in a username we'll say Dan we'll say password is going to use password we're going to use a rolls of admin so that they have access to that admin route and then what we'll do is we'll go ahead and build that so that will give us everything we need to have a user with the username of Dan and a password of password all right so now that we have this new user we just need one more thing one more setting here and what we're going to do is enable method security because even though this user has a role of admin we haven't done anything to this admin route to kind of lock it down to someone with an admin role so what we can do is say pre-authorize we'll say has roll and they should have a roll of admin so with that in place we have a new in-memory user so again this is not something you do in production this is really done for demos and kind of proof of Concepts but now that we have that in place we can come down here let's rerun our application and the first thing we should see is that there is no user generated password in here because we've overridden the default we now have a username of Dan and a password of password so let's go here it's going to ask us for a username and password we're going to say Dan and password and it's going to say nope I don't think I like that so let's see what's going on here okay we have to set up a password encoder here so I'm going to say no up um let's go ahead and rerun this and Dan and password and there we go so um we are able to go there now we should be able to go to slash admin as well and we are so so far so good this is if again if you've been watching some of the latest security videos that I've been doing we've done this a lot right so now you know the whole premise of this the entire time has been let's start with the bare minimum and as we kind of start to work through these we'll start to add on to it like we know that in memory user details manager is not something we're going to use in production but let's start to introduce something that we might use in production and so we might store our users passwords groups authorities all of that stuff in a database so the next progression of this is I want to talk about this user details manager so if you look at user details manager it implements something called the user details manager and the user details password service if we look at the user details manager if you're new to IntelliJ most IDs or text editors can do this but if you look over here it will show you which implementations there are of user details manager so we've used the in-memory user details managers but there's also a jdbc user details manager and this is jdbc user Management Service based on the same table structure as its parent class jdbc Dao implementation so there's a whole bunch of stuff going on in here we're not going to look at every line of this that would be this would be a very long video so there's all the SQL needed to insert update delete users groups authorities Etc there's a whole bunch of really useful methods in here things like you loading a user by a username creating users deleting users Etc so this is the helpful class that is going to give us all of that functionality without us having to do it ourselves and without us having to create a schema so now this is the important part it's based on the same table structure as its parent class now if we look at jdbc Dao implementation there is a at the top of this public static final string default user schema ddl location so you could go ahead and grab this user ddl if you wanted to if you're in IntelliJ you can do command shift o look for a file called users.ddl and there it is and you can see it's just a basic schema with the table users and authorities so you could copy this you can create it in resources schema dot SQL and that would work but there's an easier way because this is a static string where that DDO is we can go ahead and use that so let's talk about how we can go ahead and make this happen without using this in memory user so the first thing that we're going to need is a database and to do so I'm going to go into the Palm we could have done this right from the get-go in the start.spring.io but I figure I'd just show it here so I can come in and say dependency I'm going to look for H2 I'm going to use this in the scope of runtime so I'm going to say this is a runtime scope and I'm going to go ahead and reload these changes once that works we know that's good to go I'm going to come into application.properties and I'm going to do a couple things um I'm going to go ahead and set the data source name to dashboard I'm going to set the generate unique name equal to false and I'm going to set the H2 console I'm sorry H2 enabled I want to enable the H2 console so that is true so let's go up here and talk about this so I'm going to create a new bean and this instead of end memory user details manager now is going to be the jdbc user details manager so let's just call this users again and what we want to do here is return a new jdbc user details manager and actually let's go ahead and because we're going to do some things here let's go ahead and extract this into a local variable and we'll just return jdbc user details manager so if you look at this jdbc user details manager there is a Constructor that takes in a data source so we need a data source to pass in here now when we set up these properties here like data source name like generate unique name is equals false when H2 is on the class path we know that we're setting up an H2 embedded database so what happens is a data source Bean gets created for us so what we could do is we could come in here and say data source data source and we can go ahead and pass that in here if we wanted to this doesn't like that I bet you I pulled some weird data source in um you know what I think I probably forgot so again we started with just the web and the security um we do need to bring in something else here bring a boot starter data gdbc let's go ahead and bring that in we need the relevant bits in there which will give us what we need so let's see uh yes so that is going to clear that up Okay so what that will do is set up let's just start there so what I want to do is start the application and then be able to just kind of look at the database and make sure that that um schema gets created which it's not going to but just as a little teaser so let's go ahead and rerun this and we're going to have to fix a couple of problems here but everything looks like it started fine let's go to localhost 8080 H2 Council okay and so here's our first problem so right now we don't have any users and to be honest I don't want the H2 Council locked down it's not going to be used in production it's only used in development and I want to just be able to hit that without being authenticated so how can we fix that um well one thing we can do is we could come in here and say hey on our ant matchers I want you to go ahead and look at H2 Council and I want you to go ahead and permit all so that would be your first thought of kind of fixing that there's actually two other small things you need to do to make this work and it's something I knew about but I forgot and then I had to look it up so the first thing you need to do is csrf you need to set ignoring ant manatures to the same things so H2 Council star star and then you also need to set headers here so we'll say headers headers dot frame options dot same origin so if you forget this and you go to H2 console it'll load but then it you will you'll see a bunch of like nothing and that's because you need to set this headers so with that in place we should be able to get to our H2 Council now without authenticating let's try that okay so H2 counts okay so good so we're here the name of our data source was dashboards if we go in okay we are able to get into our database but there's no tables or columns something's not getting created right so again I said if you wanted to you could come in here and say create a new file called schema.sql and go ahead and find that schema that is part of that jdbc Dao implementation but that's kind of a pain in the butt right um so what I can do here is I'm going to get rid of this and I'm going to create my own data source beam and now what that will allow me to do is configure a couple things so again I'm going to come in here and say Bean so I'm going to say data source data source and what we'll do here is we'll return a new embedded data source configure nope I want to build our data source database Builder that's what I'm looking for and in here we're going to set the type to H2 what we're going to do is we're going to set the name so I'm setting the database name to dashboard and here's where it gets fun so I can go ahead and add a script so we know that that again if we look at here and jdbc Dao implementation there is a static string for default user schema DDO location so let's use that so we don't have to kind of copy paste so let's say jdbc Dao implementation dot default user schema ddl location so that will load that and then we can just say build so we are going to return a new embedded database Builder um that okay so that will give us the data source so now that will override the original data source being and now that is what I'll get passed into here and so let's go ahead and rerun this and I think we should see some progress now we should at least we should be able to log into the H2 Council again and this time I think we should see our column our tables and our columns and we do so we go ahead and do that we have select star from users we have username password and enabled if we select star from authorities we have a username and an authority so so far so good looking good here now what we need to do is get some users in there so we can do this in a similar fashion to how we did in the in-memory user details right what I want to do is create a new user so I'm going to say user um nope I don't want user user Builder I just want user Builder and what we'll say is username is going to be admin change it up password is going to be password roles we want to set as admin and we want to go ahead and build that so now that we have a user we can use the jdbc user details manager to create one so we can create a user and we'll go ahead and pass in that admin do we not call them admin okay let's go up here we need to introduce a local variable let's call this admin so now we create that user and then we go ahead and return this so let's once again go ahead and restart this application head over to our H2 Council and we'll look at dashboard we'll look at users and great we have a username of admin a password a password and that user is enabled and if we look in authorities we have admin has a role of admin so so far so good we're moving right along doing exactly what we wanted to do um one thing that I see a problem with there is we are storing plain text we don't want to do that I'm going to create one more being in here of type password encoder we'll say password encoder and I'm going to return a new bcrypt password encoder um so you could uh go ahead and like you know encode this password from the command line if you wanted to for this purpose I'm that if you look at the spring CLI there's actually a way to encode passwords using bcrypt and I believe I've done a video on that so we'll see if we can find a link for that as well so I'm going to say password encoder encoder and let's just say encoder Dot and code and we'll say this is my super Secret password one two three four dollar whole bunch of characters right okay so that should be that let's just print this out I want to see what this looks like um let's say ass out admin dot get password and let's go ahead and run this again so we should see an encoded version of this password which we do if we look in the database we see the encoded version that's good so I'm going to copy this and then our username is admin so let's try and visit just the root so admin and then that password great and then we try to visit the admin URL and we do we are able to get to the admin URL so cool I think that was a nice progression one thing I just want to mention again is the jdbc where we jdbc user details manager there are a bunch of methods in here take a look at this structure if you need to like create a user updated user Insight delete change password find out if the user exists create a group add user you know all the things that you would need to do with user management is here now the one thing I will say is this works if you don't have a table structure in place for users if you have an existing application and you need to use an existing structure you'll need to modify a lot of things here to fit that now I would say too if it's much different then you may not want to use this approach you may want to create your own entities you may want to create your own user details service and those are things that we'll look at again where we're kind of just going down this road of progressing and things that you might do in your application so I think that's where we'll leave it I hope you found value in this if you did please go ahead and leave me a thumbs up friends subscribe to the channel and as always happy coding [Music]
Info
Channel: Dan Vega
Views: 22,362
Rating: undefined out of 5
Keywords: dan vega, spring security jdbc, spring security, spring boot, spring framework, spring boot security, spring security tutorial, authentication, authorization, spring, spring security in spring boot, spring security tutorial for beginners, security, spring security in spring mvc, spring security userdetails
Id: d7ZmZFbE_qY
Channel Id: undefined
Length: 24min 53sec (1493 seconds)
Published: Fri Sep 16 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.