Implementing a UserDetailsService7:35 with Chris Ramacciotti
Connecting Spring Security to user data can be accomplished through several means. In this workshop, we'll take the approach of implementing a
UserDetailsService, which will supply Spring Security with authentication and authorization data.
Git Command to Sync Your Code to the Start of this Video
git checkout -f v4
Using Github With This Course
You can complete this course entirely using code created by you on your local machine. However, if you choose to use the code I've made available to you, you have two options:
- Use the project files linked at the bottom of this page, or
- Use the Github repository I've made available (recommended)
If you choose the recommended option of using the Github repository, it can be found at
To utilize Github with this course, you can download the Github desktop client for your system or use the command line interface provided with Git.
Clone this repository to your machine using the Github desktop client, or using the following command:
git clone email@example.com:treehouse/todotoday.git
To update your local repository to match a video's starting point, you can use the
git checkout command in combination with the stage and video number. For example, to update your local repository to match the starting point of Video 4, you'd use the following:
git checkout -f v4
Notice the use of the -f option. This forces Git to override all local changes, so be aware: this will cause any changes you made to be lost.
Our next order of business is to integrate spring security with our user and 0:00 role entities. 0:04 In general what we'll need to do is to implement the user details service 0:05 interface. 0:08 If we open this interface in the spring docs when we go there now, 0:09 we open this interface we'll see by scrolling down, 0:15 that there is exactly one method to implement and it's this load ByUsername. 0:18 Method. It locates the user based on 0:24 the user name. 0:27 So when we implement this method we'll call upon our user DAO which we 0:29 haven't written yet to grab the user entity from the database via hibernate and 0:33 use it as the methods return value. 0:38 Let's start coding our service in dao now. 0:40 I'll switch back to IntelliJ and first I'll create the user service interface. 0:42 So in my service package I will create a new, I'll choose Java class, 0:48 user service and all select interface. 0:54 There we go, and I'll make this service, 0:57 extend user, details, service. 1:00 So that my implementation class will need to include that load by user name method. 1:06 And the one additional method that all include here is a find by user name 1:12 method, which is a method that's completely for our application purposes 1:15 and that doesn't have anything To do with spring security so let me add that now. 1:20 I'll say, findByUsername(String username). 1:24 And let's make sure to import the right user here. 1:30 Now, this is our users so if you choose one of the ones up top, 1:34 you're gonna be importing the wrong user. 1:38 It's the user that comes from com.teamtree house. 1:41 Right there, cool. 1:44 And that's it for our interface. 1:47 Let's now create the implementation. 1:48 So again in the service package I'll right-click New Java Class and 1:50 I'll call it UserServiceImpl. 1:54 And let me include that service annotation here. 1:59 As well as indicate that it should be implementing the user service. 2:03 And in doing so, we'll need to add all unimplemented methods. 2:11 There should be two, one that comes from that user detail service that 2:19 the user service extends, and one that comes from user service that 2:24 we explicitly coded in the user service interface. 2:28 Now before we dive into this class we'll first need a way to grab 2:33 user data from the database. 2:36 Of course this will require a da o. 2:38 for the user entity. 2:40 Let's go ahead and create that interface in the dao package right click. 2:41 New job a class I'll call it user dao and 2:47 I want this to be an interface there it is right there. 2:50 The cool thing here is how little work we have to do. 2:54 If you recall, we are using spring data JPA. 2:57 So all we have to do here is extend CrudRepository. 3:00 And when you extend CrudRepository, 3:06 you tell it the kind of entity that you're after in the database. 3:09 As well as the class used for the identifier again. 3:12 Make sure you are importing the correct 3:17 User com.teamtreehouse.todotoday.model.User. 3:19 And after this we intelligently code our query methods. 3:23 In our case it will suffice to include a findByUsername method. 3:29 So let's do that now here's how that looks. 3:35 I want it to return a single user and 3:38 will say findByUsername(String username). 3:40 And finally let's apply the repository annotation to this interface. 3:47 And this is to make sure spring picks this up as a DAO and 3:55 now when we boot the app spring data will generate the implementation of the DAO so 3:59 we don't have to code it that is. 4:03 It will see a method name FindByUsername. 4:05 And it includes a string parameter so 4:09 it will generate a method that will find a user in the database 4:11 that has a user name column that uses the method name right here. 4:16 It has a user name column equal to whatever value was passed in so 4:21 cool okay back to the user service amperes class. 4:27 We can now auto wire a user dao into our service which will 4:33 need to start combining our user database data that is users and rows So 4:37 that we can integrate it with spring security. 4:41 So lets auto wire that up top. 4:44 Auto wired, private, user DAO, user DAO. 4:47 Cool. 4:52 Let me make sure to import that class. 4:54 There we go. 4:58 User DAO is imported. 4:58 The find my username method will be fairly quick here since it only 5:01 involves calling upon the DAOs method of the same name. 5:04 So let's return whatever value. 5:08 The DAO returns. 5:10 By calling its method of. 5:11 The same name. 5:13 As for the load by user name method this one will involve barely more work 5:17 Here's what will need to do. 5:22 I'm gonna add some comments in here. 5:24 First we'll need to load the user from the database. 5:28 And we'll throw an exception if not found. 5:31 And then we'll return the user object. 5:39 So really, we're just doing one extra thing here. 5:45 And that is that we are throwing an exception if that specific username 5:49 is not found. 5:53 And that is expected by the load by user name method which, again, comes from that 5:54 user details service interface, which our user interface extended. 5:59 Let me go back and remind you of that. 6:05 So the load by user name method comes from the user details service interface. 6:07 Okay, so back to these comments. 6:15 For loading the user from the database we use the same approach we did 6:18 in the findByUsername method. 6:22 That is will use that userDao so let's create a user object. 6:23 And call upon the DAO to find the user by the username and 6:27 we'll pass in the username that we received here in this method. 6:32 Now, because this method should throw the username not found exception, 6:37 which will be detected by Spring Security, 6:43 if upon authenticating, a user is not found with the provided username. 6:46 Then we should do that now if the value that stored in user at this point 6:51 happens to be no. 6:56 So will say if the user is null then we'll throw that exception. 6:57 UsernameNotFoundException. 7:06 And will throw a message in there too. 7:09 User not found. 7:11 Cool, and let's not forget to return that user object instead of returning null. 7:15 All finished. 7:22 So we finished our service and DAO layers. 7:24 Next we'll add some application level configuration to our Spring app 7:27 that switches on all of our Spring security functionality. 7:31
You need to sign up for Treehouse in order to download course files.Sign up