This workshop will be retired on May 1, 2025.
Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Now that we have users let's provide a way for them to log in, or authenticate.
This video doesn't have any notes.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
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 upYou need to sign up for Treehouse in order to set up Workspace
Sign up