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