Adding Authentication10:35 with Craig Dennis
Now that we have users let's provide a way for them to log in, or authenticate.
Welcome back. 0:00 Are you feeling refreshed? 0:01 Okay so let's get started. 0:02 One second first though. 0:04 I wanna show you something that I did I made a mistake while we were going through 0:05 this and I just automatically created this constructor and 0:08 I assume that it was going to be username first over here. 0:12 And so when I built all those constructors there were three strings in a row. 0:18 And I put the username first and then I put the first name of the last name, but 0:22 the order was different so I just want to point that out. 0:27 Be careful when you generate constructors like that and kind of assume that that's 0:29 how things work and then I was never looking and I was just filling it out. 0:32 So, what we do have is this user entity and a matching repository and we added 0:35 a search that lets us find an entity using the method find by a user name. 0:40 So Now what we need to do is have our code play well with Spring Security. 0:45 So, what we need to do is to create what is known as a user details service. 0:50 Spring Security expects us to provide this customized for our specific environment. 0:55 So, let's build one. 1:00 So in the user package let's go ahead and 1:01 we're going to make a new Java class and we gonna to call it DetailsService and 1:03 we gonna have it implement the user details service. 1:09 And there's a lot of the using of the word user, right? 1:11 So let's talk about here in a second so we gonna say extends userDetailsService and 1:15 I meant actually implements here cuz that's a interface. 1:22 Now this user here is what Spring Security is calling the user it's not our 1:27 user entity. 1:32 This is a common confusion and one that you find on Stack Overflow all the time so 1:33 pay close attention to the differences here and I'll point them out. 1:37 So our class definition is saying very loudly that we have not 1:40 implemented the methods. 1:43 So let's go ahead and 1:44 we'll do that so the one that we have is this load user by username. 1:45 Again not our user, this is somebody that implements user details, and 1:49 if we can't find it, what we need to do is throw a user name not found exception. 1:54 So, we need to get ahold of our User. 2:03 So let's get ahold of our repository, right. 2:05 So we are gonna go ahead and autowire that up. 2:08 And we'll say UserRepository users, and 2:14 we also wanna export this out so that somebody else can find it so 2:17 let's go ahead mark this as Component so we don't forget. 2:21 So that when the components scan comes, 2:25 we can find this is what we can find a user detail service. 2:27 All right, so let's do it. 2:30 Let's go and use our users. 2:32 So we'll say user equals users, our repository and there's our method, 2:34 findByUsername, and we'll take the user name that was passed in. 2:38 Okay, and if that's not found, so if user name is null, 2:42 what we'll do is we'll throw a new username not found exception. 2:47 And as you'll see it takes a message, or msg as it says there, 2:53 don't be confused with monosodium glutamate. 2:57 So username + was not found. 3:00 And remember what we're expecting to return is that something that 3:07 implements the user details interface. 3:10 So, we could make our entity actually implement the user details interface. 3:13 But first, let me walk you through the other side of the problem, just so 3:16 you can see this. 3:19 So here's the naming issue that I was warning about. 3:20 So let's just say new and will say user and notice that's not our user. 3:22 That's the org.spring.framework.security.core.somet- 3:27 hing right. 3:30 So if we do that it's going to auto complete everything there. 3:31 That's exactly what we want. 3:34 Now let's take a look here so the first it takes a username it takes a password and 3:35 then it takes a collection of granted authorities. 3:39 Okay so let's do that we can definitely get easily get this user.getUsername 3:43 right. 3:48 And we have the password user.getPassword. 3:48 Finally what we want to do here is use a handy 3:52 little utility called AuthorityUtils. 3:56 And it has a static method that it exposes called create authority list and 4:00 that takes an array of roles and we have those under get roles. 4:05 Okay. 4:11 Our service is looking great and 4:16 it can be found because we've marked it with a component. 4:18 So what we want to do now is overwrite the default Spring Security and 4:21 use this service. 4:26 So let's do that. 4:27 So if we go to our project, defining the security is pretty core right so 4:28 let's drop it in here let's drop it in core. 4:34 So we're going to say going to call this WebSecurityConfiguration. 4:36 Naming doesn't matter really but except for discoverability by people but 4:44 we're going to extend The WebSecurityConfigurerAdapter. 4:50 So let's start configuring first thing we want to do is we want to make sure that 4:57 Spring knows that this is a configuration file, right? 5:02 So we're going to market with configuration. 5:04 And the next thing that we're going to do 5:07 is we're going to let Spring Security know. 5:09 So we're gonna say EnableWebSecurity. 5:12 So that lets us bring security now. 5:14 And to complete the annotation trifecta. 5:17 Let's say EnableGlobalMethodSecurity and 5:21 we want prePostEnabled to be set to true which is gonna allow us to 5:25 secure our methods and we'll get to that here in a second. 5:30 Okay. So 5:36 we are going to inject that service that we just built, Autowired. 5:36 And the service is called a DetailsService and 5:41 it's called userDetailsService. 5:49 Now we want to overwrite a couple of configuration methods. 5:56 So the first one that we're going to do is this one here, this 6:00 configure(auth:AuthenticationManagerBuild- er). 6:03 Now notice there's a couple of other method signatures that 6:06 are called configure, but we're gonna do this one first. 6:08 All right, so this is going to pass in an authentication manager builder. 6:11 And what we're gonna do is we're gonna build up. 6:17 We're gonna say auth.userDetailsService and 6:19 we're gonna pass in that service that we just made the user detail service and 6:21 we're going to make sure that it knows how to decrypt the passwords, all right? 6:27 So we're going to say passwordEncoder and 6:32 we expose that using a static method off of our entity, right? 6:37 So that way if we ever change it, this is where it comes in. 6:40 It knows how to do it, it knows how to check things. 6:43 So what it will do is it will take the password and 6:45 see that it matches our encoded password. 6:47 Cool. 6:50 Okay, and the other method that we need to override here, is for HTTP security. 6:52 So we're gonna say override methods and 6:57 we're gonna say configure the HTTP security. 7:01 And this also uses a chainable, sort of fluid API. 7:05 So we're gonna say http and we're gonna say, .authorizeRequests() 7:08 And we're trying to make this as friendly as we can. 7:17 But, this is not something that you should run on production, keep this in mind. 7:21 So we'll set the authorization, .authorizeRequests() and 7:24 say that any request must be authenticated. 7:28 Okay, so we're going to say any request must be authenticated, meaning logged in. 7:32 The dot here. 7:41 [SOUND] Okay, 7:41 so this is all chaining and so we're going to say and we wanna use httpBasic. 7:46 Now you typically wouldn't do this but again we're just trying to make this 7:54 simple so that we can explore it and I can kinda show you what's going on. 7:56 And the other thing that we wanna do is we wanna turn off a great feature that you 8:01 should probably never do except for when you're trying to do something like this. 8:05 When I turn off the CSRF or cross-site request forgery stuff. 8:08 Now Spring does this for you, it's really nice Spring Security. 8:13 And you don't want to turn this off really, but we're going to. 8:17 So we're gonna do csrf and we're gonna say .disable. 8:20 And the reason why we're doing that is so that we can easily test in and out, but 8:24 do not do that in production. 8:29 So again, this is a lightweight implementation and we just use it for 8:31 testing, but the nice thing is you can just tweak the setup here, and thanks to 8:34 the powers of abstraction, everything else that we're going to write will just work. 8:38 Now as long as we've got everything working correctly, 8:42 you need to be logged in or authenticated to access our API. 8:45 Let's see how we do. 8:49 So I want to make sure that our app is running, and that we don't get any errors. 8:51 Awesome, and if we come over to Postman. 8:57 And we hit our API view on courses. 9:08 We should be told that we are unauthorized. 9:11 We get a 401 on authorized. 9:13 Now that's great. 9:16 That's what they asked for. 9:17 They asked for every time that anybody uses our API to be logged in. 9:17 Perfect. We have done that. 9:21 So let's log in as one of your fellow students. 9:22 I wanna pop back over to our list and look at the database loader. 9:25 Let's grabbed the first student who responded here, 9:32 Jacob Proffer the first student response. 9:34 So, Jakob Proffer, let's grab his name and his password is password. 9:36 Hm. 9:40 All right, so let's go and in Postman there is an authorization tab and 9:41 there is a type and we're gonna choose basic auth and 9:46 the basic auth we're gonna put in Jacob's name and we're gonna put in a password. 9:50 So Jacob if that's your actual password you might want to change it because now 9:57 everybody knows it. 9:59 And we're gonna click update request, and what that does is it added a header. 10:01 Okay. So it added a basic header here. 10:04 So now we should be logged in as Jacob, so let's see. 10:06 Boom, there we go. 10:11 We're currently logged in as Jacob Proffer. 10:12 Now since we didn't set any authorization yet, Jacob is pretty much able to create, 10:14 read, update and delete everything in our API and that's not great. 10:19 I mean Jacob’s a great guy and he wouldn't delete Karen's reviews but he could. 10:22 There's nothing stopping him. 10:27 So let's set up some proper authorization specifically on those deletes 10:29 right after this quick break. 10:33
You need to sign up for Treehouse in order to download course files.Sign up