Welcome back to the second chapter of spring social with security. We still got some work to do. We need to configure a filter and we’ve also got to put
in place a web controller. To handle the scenario where a new user is linking their account
for the first time. It’s all quite straight forward but there are a few components
that we need to put in place. There will be a big pay off because although this work will
be around 50 minutes once that’s done, we’ll
spend just a few minutes at the end of the chapter almost effortlessly plucking in
Twitter and Linked In. So it’s all worth it,
let’s start with a review of the work we did previously. What we’ve now done is we’ve plugged in a new provider, an authentication provider that is going to be able to compare a list of IDs that we have sourced from so far just Facebook. But that’s only really half of the story this is telling Spring how
to do the authentication. Are you on our list of
registered Facebook users? But it’s not actually going
to trigger any authentication. What we need, of course,
is when we visit a link. We need some way of clicking a button, saying authenticate with
Facebook and we need the mechanism to go across to Facebook and do all of that hard
work with the process. To make all of that work, we are going to need to switch to our CRM
security config.xml file. Because that is where we are
defining the http patterns. And what we’re going to do here is we’re going to insert an
entry into the filter chain now I know we haven’t really talked about the filter chain in any great detail. We’ve eluded to it several times, I am planning to do an
advanced chapter towards the end of this course where we at least a little bit of a peak under the hood and see how all of that’s working. But I think you’ve
probably got a good idea of how it works by now. That we have a series
of operations happening when we access this
particular http pattern. For instance it’s doing checks
against these url patterns. And all of those things are happening as part of a filter. But what we can do in here is we can add in a custom filter. And we did something very similar to that back in the auth part of the course and this is going to be the filter that is going to handle
the social authentication. And it’s fair to say if we’ve clicked on a particular link, a special link then it’s going to fire
off the auth process. It’s going to go across to Facebook and it’s going to try
to get an ID from there. So this is going to be a new filter that we’ve got to declare. I’m going to call it social
authentication filter and the thing that you
might not be familiar with because we haven’t covered it yet is that all of these filters have a position in a chain. Each of these positions has a label and really I’ve done is I’ve looked in the Spring Social reference and it tells me that the
position to insert this filter is in the position called
pre auth underscore filter. This position in the filter chain is where any pre authentication can be done. And pre-authentication
is what we’re doing here. We’re saying that this
user will have already authenticated themselves with another provider. And this filter is going
to go off using auth to find those authentication
details from elsewhere. So it’s quite easy to
insert this into the chain but of course this filter
has to be declared. So that’s going to be done in here. It’s just a b, so we’ll
copy the ID from there, and the filter, again I’m just
working from the manual here. Is org.springframework.social.security. social authentication filter. There are going to be some properties that we need to pass into here. I have an error in the xml here because I’m in the other file where the b font name space
we’ve sent to be security. So we’re going to need the
b’s name space in front of each of these tags. If we look in the java docs for
social authentication filter you can see here that it’s telling us that we should inject it at or before but it’s going to be at the
pre-auth filter location. You might be a little
bit horrified at first to see that in the constructor here there are again no useful information, but there are one, two,
three, four paramaters that we need to pass
in to that constructor. Actually three of these
we’ve already created, we’ve got the authentication manager which we’re well familiar with. And this users connection repository, well you remember we did that in the first part of this configuration. So we’ve already created that object. And also the social
authentication service locator that’s another one of these objects that has already been
automatically created. As a result of the Facebook
coal on config tag. So most of our work is done here. There’s only just one rather
strange parameter here, this user ID source. Now this is neither, because when you’re working
with social authentication, you don’t necessarily
have our own user records here on our site. Because some sites using some
sort of social authentication might not even bother
keeping user records. They’re just going to
keep that long list of IDs managed by the authentication provider. So for that reason,
spring social has decided that we need this plug-in here that’s going to be
responsible for working out what the user ID is. If I follow a link to user ID source it’s an interface, they
describe it as a strategy interface used to determine
the ID of a current user. Now that means once the user has been authenticated and they
have been registered by our authentication manager. Now all we need to do is
take that user principle take the user name, and
we use that as the ID. And that’s going to be, I
think, the strategy that most sites are going to
use and for that reason there’s already an implementing class that does exactly that. It’s the authentication
name user ID source. And there’s nothing to do in here it’s an empty constructor,
we just instantiate it and plug it in. But if I go back the other implementation that’s out of the box
might give you a clue as to why this might be
useful in the future. I go into here, this
session user ID source is convenient for applications
that don’t maintain their own notion of a user. Which some applications will do. I realize that’s a little bit complicated and way beyond the scope
of what we want to do. And probably what most
applications want to do. And I find it a bit confusing really that they don’t
automatically configure this authentication name, user ID source. And we don’t have to think about it until such time as we want to change it. So I think it’s, an example
here of bad defaulting. And I’m not criticizing
the social team there. I’m just kind of saying that just so if you’re finding this overwhelming you really don’t need to
worry so much about it. You can put that pretty much to one side. And so going back to the work
that we need to do right now we need to configure this
social authentication filter. And those you’ve seen now, one, two, three of those objects already exist in our configuration. It’s just this user ID source
that we need to instantiate. So that is easy to do. We’ll do that in it’s
own beams definition. And we’ll call this the user ID source. And the class is exactly as on the job, I won’t bother switching back but it’s org.springframework.social.security. authentication name user ID source. And I have xml errors here which suggests I’ve gotten one of my takes wrong. And yeah, it’s just that
should be b colon beam. Now my thinking is because
now the four objects that we need here have already been configured elsewhere
in the spring config we could potentially use that trick again of using auto wire equals constructor. But I’ve discovered that there
is a slight problem with that in that it won’t be able to identify the authentication manager correctly. So we do have to do just one
beams colon constructor aug and that’s going to be
referring to the authentication manager that we’ve defined elsewhere. That’s because by the way, under the hood there are multiple
authentication managers. We’ve defined one ourselves
and we want to use that one but there are others. Planning to talk about that when we lift up the lid
and we go into details about what’s happening underneath. But for now if you be
happy that we have to pass that e-manually but the other three dependences should be found automatically. We’ve done two jobs in this file we’ve set up the mechanism
for recording user IDs from this social authentication provider. And we’ve had to create a few
helper beams to make it work. And in here we’ve set up the filter. Which is going to be
the web based mechanism for actually going across to Facebook and making all of this happen. The remaining work is just to really pull all of this together. And to put the mechanism in place to allow the user to
initiate the log in process. But I feel since we’ve done
a lot of configuration here and I know that I will have
got typos along the way and I’m sure you will have too. I think it’s properly
worth, even though nothing is going to happen, I think it’s worth doing a deploy and seeing if we get any
errors on the ton catalog. And we certainly do. Lots of exceptions flashing past there. Let’s hum through this. These all look like
just run on exceptions. And this looks promising. We have references to xml errors here. So yes, I suspected
there was something wrong with my Facebook colon config. Because I was getting
that error in the editor. But I sort of ignored it for a little bit. So let’s go and have a look. This is in misc beams .xml. So this line here looks faulty. I think the line is okay, it’s
possibly the declaration of– that looks okay. Here on the name space. I have no idea what happened there. I’m very sorry. I must have been rushing at the time. I didn’t notice this happened
as I’m recording the video. This is the name of the xsd. Which is actually
spring-social-facebook.xsd I must have made a slip when recording. It wasn’t deliberate I promise you. Now I noticed that error is still there. And I can tell you that actually that error never went away, even during rehearsals . Even when I’ve got
working professional code, I’ve never quite made that error go away and I’m not quite sure why. It’s something to do with
the declaration here. But I think that should
make that problem go away. Let’s try deploying again. And more exceptions. This is to be expected. This one looks a little bit easier, it’s saying there’s no beam
named authentication manager. Just lost it there. I’m always making this mistake. In the social authentication filter. I passed in beam with the reference of authentication manager. But actually the authentication manager is defined in this file
and I created it here. Actually I haven’t given that beam an ID. And I know we did this
earlier on in the course. I recommend you use an alias
here of authentication manager. If you give it an ID there
it can cause problems. So very minor things so far. And I hope that’s the
way it’s going to remain. Let’s deploy again. Well this time I appear to
have a stable deployment. And that’s really good. We’ve reached a good checkpoint. But the task now is we need to give the user some way of triggering this process off. So we need to go into our login.jsp page which we’ll find under the web folder. Open that in the text editor. And so all of this existing
form will still stand. But I’m going to provide
now an alternative option you might think that’s going
to be quite complicated. But it isn’t because this
functionality is built in to the filter that we have plugged in. If we provide just a regular link. Just a common old garden a href, and we’re pointing to forward slash crm. Forward slash and this is a built in url, you can override it. I won’t be changing the default however, the url is auth be careful
there don’t do oauth, I’ve done that a few times
and found myself in trouble. Forward slash, Facebook. And this is just a regular link, I’m going to use some text here, Sign in with Facebook. And of course in a real
application you would provide an image there and there are standard images that are
provided by Facebook. You can very easily get a hold of those. We won’t bother on this course because we’re not web designing that should be enough. So this uri here is an uri that has been automatically applied. It’s going to be trapped by the filter that we just configured. So that still takes me by surprise. I always think there’s
going to be something really difficult at this stage. But that’s all you need for the UI. Now I know there is a slight
problem in our CSS file. It’s not a web design course but we do have to deal with this. In our styles.css, which
you’ll find in the CSS folder. And I’l need to open that with the built in text editor. It’s just bad design really. At present set all hyperlinks,
all a’s to be white. And the reason that we
did that on our design is at the moment all of
the hyperlinks are here in this black bar that
runs along the header. But that’s going to mean
that link that we’ve just created is going to
appear here in white and we will not be able to see it. So we need to stop that happening. Normally I’d get on the
phone to Matt Greencroft and get him to deal with this, but I’m terrible at CSS. But the links are in a header in a div with an ID of links. So I think what I’ll do here in the styles we will change this. So this only happens in the links section. I think that will work anyway. So we still got some work to do. Quite a lot of work in fact. But let’s see what happens if we try this. And we’ll attempt to visit
website all customers, looks like we’re still deploying actually. Try again, okay. So we now have our sign
in with Facebook link. Now if I click on that link. You can see that we’ve certainly
been directed to Facebook. So the links working. But we saw this error before. This is not a valid redirect uri. And that’s happening because we now have a new redirect uri. We haven’t specified this, but it has been handled
automatically by spring social. We can check it in the url bar, here at the top we can
see it in the parameters. It’s not easy to read
because it’s been encoded. But the redirect uri is
actually forward slash crm, forward slash auth,
forward slash facebook. In other words the
redirection is sent back to exactly the same url
that we used for the link. So what’s happening there
is again spring social automatically sets up this URL to handle the redirection
back from Facebook as well. It’s kind of a neat little
process that they’ve set up. All that means is then we need to go again to the dashboard under
settings and advanced we did this exactly this earlier. Previously we set this as a redirect uri. Well I’m not going to need that anymore. That was just an experiment. But we are going to want
http local host 8080 forward slash crm, forward slash auth, forward slash facebook. And be careful you get the
structure of that right sometimes I get that wrong. You will get a little
warning red symbol here if there’s anything wrong with
the structure of that URI. So we can save that. And let’s try again. So we’ll try to visit all customers. We’ll hit the sign in with Facebook link. That might look like
nothing happened there but actually the url has
slightly changed here on the bar. There’s some sort of
strange string going on at the end of there and well, it took me hours to work out what is going on here. Can I just demonstrate
that something did happen and the best way of doing
that I think would be if I go into my Facebook developer console I’m going to log out of Facebook, just to prove that something
really did happen there. I’m going to try that link again and you can see now that it is definitely going to Facebook. And when I log in and now you can see that I have been sent back for some reason to this log in page. Well what’s happening here is that at the end of the process, although we know reminding ourselves that this redirect uri, that facebook is redircting
back to the url crm slash auth slash facebook. Remember that’s been automatically provided by Spring Social. The logic behind the
control method in there is that it is redirecting to another uri. And you’d only know this if you looked in the reference manual or actually more likely probably
checked the sample code. It’s not obvious but what’s happening here is that Spring Social
is trying to redirect to a URL called sign up. And sign up is where
we’re expected to provide the logic that we want in
order to register this user with our application. And I think what’s happening
is a very simple case of– because this is the protected
urls that we’ve got. When Spring Social is
trying to go to this URL it’s protected, so it’s coming
back to the log in page. So I think step one here is
to go into the intercept urls and we want to make sure
that all users can access this forward slash sign up url. Now on line 84 here this was the url that we were using earlier to
experiment with Facebook. I don’t think we need that anymore. So I’m going to repurpose that. I’m going to change that
to forward slash sign up forward slash star star. So let’s see what difference that makes. Okay and I’ll run the process again. So sign in with Facebook. And that proves that
Spring Social was indeed redirecting to the URL called to sign up. Now, this is really the
last stage in the process. We’re expected to implement this URL and we’re expected to
provide the custom logic that we want to register this
particular user with our site. We are going to have to do
some work in implementing the URL called to sign up. But as you’re going to see, there are a lot of different ways of handling this process
and handling this flow. And the idea behind having this URL is we can kind of now slot in our own custom functionality
that we want to handle the user’s registration. I’m going to go for the
simplest possible way of handling this. What we’re going to do now is we’re going to write a handler for this in a controller and we’re going to interrogate Facebook,
we’re going to find out what that user’s ID is from Facebook. And then we’re going to register them using that in-memory social user service that we saw before. So a little bit more work to do. But it’s not too bad,
it’s just one controller. There are only about 20 lines
of interesting code in this controller but I have considered giving you this pre-written. But I know that a lot of
you like to go through every single step. So if you don’t mind I’m not going to just go to throw this file at you. We are going to build it step by step. So here in the controller’s package. The web controllers, we’ll
go for a file, new class. And I’m going to call this
the Social Auth Controller. Call it anything you like, as long as you annotate
it with that controller. I’m going to need a handler method, so this is going to return
I guess a modeling view. I’ll call this registered
user from Facebook. This method is only called when the user hasn’t been recognized. So this is a brand new user that has never registered with this site before. So we’re going to need
an at request mapping. Which is handling the URL
of forwarding slash sign up? I’m going to need to
import the model and view. And what we’re going to
ultimately want to do here, right at the end of this method, this is the overall goal of this process. Are we’re going to want to register this user with our application. Well, I hope you remember
from not too long ago we created this class called in memory, social user detail service. And that’s exactly what
the job of this class is. We have a method in there
called add a new social user. Which will register a
user with a particular ID? And remember that is the ID that we have extracted from Facebook. So we want to recall
this method ultimately as part of this process. We’ll need to get a
reference to that in-memory social user detail service. With a clear instance of it here. I’ll call this the user details service. And we can very simply auto-wire that in. So down towards the
end of this method then I’m going to be calling
the user detail service to add a new social user. All I need is the ID of
that user from Facebook. And the way that we do
that is very similar to how we did it in the warm-up section. When we were first using Facebook. We need to use a connection to Facebook where we can recall various methods to get various pieces of information including the ID. And the way we do that
here is slightly different from how we did it before. We’re going to use another helper object which will link to declare
as a private attribute and this is the class called
provider sign in utils. I’ll call it provider
sign in utils I guess. Now I must admit I’m not sure if there are other ways of doing this. But this is certainly the way that the sample application suggests. What this sign in utilities gives us is a way of extracting the
connection to Facebook. We can call, and that should be signed in utils, sorry about that. By the way, I haven’t shown you how to instantiate this yet. It’s not a simple case of auto wiring. I’ll leave that to when we’ve done the interesting bit of the code. We can call in there, there are actually only two useful methods. The first method is to get
a connection from the session, and that’s going to allow us, I can just go with the default
parameter name of the request. That’s going to allow us
to use the current session to extract the connection to Facebook. So in other words what’s happening here is that Spring Social
is automatically storing this connection in the user session. So we don’t have to worry about what the factor is in all the rest. Now the object that is
needed here is an object representing the current HTTP request and we’re sort of getting into Spring MBC a little bit here, which I don’t want to get too hung up about. I can tell you that if you just declare an object of type web request as one of the parameters into this method. Then Spring MBC will automatically inject an object representing the request. We just need to import this web request, which as you can see comes from standard spring framework web. It’s nothing to do with Spring Security. Now that is finally going to give us one of these connection objects. And again, as before, be careful importing this. This is the Spring Social object. If you’re annoyed by the warning here. This is a generic warning. We saw this earlier. That there are different
types of connections for different social media providers. So we could I guess put Facebook in here. And import that. But actually we don’t want to do that. Because we want this to
handle not just Facebook but also Linked In Twitter, and others. And actually, as I say that I realize we should probably rename this method. I’m going to change Facebook
to a social media provider. Of course, it doesn’t matter what we call that method name there. If you want the warning to go away you can put an angled
bracket question mark. That’s the standard java
way of handling generics at least from this point,
it’s fairly downhill. Because on the connection, you’ll be familiar with this one earlier we can get the underlying API which we’re probably not going to do because this is a generic
social media provider. But we can call the fetch user profile which would give us access to the ID. But actually I have a better idea. There’s a method, a very useful method in there called get the key. Now that returns a complex object in fact we actually
only need it to string. Now that is going to return
the ID from Facebook. But if you think about it, we have a bit of a problem here. We might have one user who
is logged in using Facebook. And their ID might be seven. Of course, it’ll be a big number probably, but it might be something like seven. Then we might have another user
logging in using Linked In. And there’s no way of guaranteeing that we’re not going to have a clash. The Linked In ID for a different user could be seven as well. So the great thing about
calling this get key is it will automatically
put in front of the ID a string representing
the name of the provider. So we might have one user
who is Facebook; seven. And a different user
called Linked In; seven. And we’ll know that
they’re different users. So we could have done that manually but this gets key method
is a really useful way of doing that. So that is going to form our ID. Now what we’ll do after
registering this user in the use of detail service is we will I think just to keep things simple. I’m going to return a new model in view which is going to represent a redirect. And I think we will
simply redirect to that all customers page. Which remember is in the folder slash website. I’m doing that because this is kind of the front page of the application. Now there are still a few small things that we need to add into here. But we are getting really close and I’d like to do a deploy. But what’s definitely not
going to work at the minute is this provider sign in utils is definitely going to be null because we haven’t injected it. And we can’t inject it because that’s not been declared anywhere in our XML. It is slightly tricky. And again I wish this was
a little bit of the API that they tidied up a little bit. But I’ll show you my favorite way of instantiating this object. I’m going to create a public method called initialize. Doesn’t matter what we call it. And I’m going to instantiate this object. And you can see the difficulties here there are actually two parameters needed in the structure. The first object is a type of
connection factory locator and the second is a typical
user connection repository. Now if you’re anything like me, you’re probably getting
completely drowned in this huge soup of factories and locators
and users and repositories. But if you take a step back, and actually both of these objects we’ve seen before. We’ve seen that we get
both of these for free as part of that Facebook colon config tag. So although it’s ugly we can get both of these objects without too much work. We can simply declare them. So the first one is a typical
connection factory locator. And we can auto wire that. And we can forget all about it now. And exactly the same
with the other parameter. The second is the users connection repository. Which can also be auto wired. Which, sorry that one was
called connection repository. There are other ways that
you could have wired that. But I’m not really too worried about it. It works. You might be wondering
why I’ve done this in the initialize method and I haven’t
done this in the constructor well I can’t do this in
the constructor because, at a point of construction, both of these objects will be null. We have to do this after
the constructor has run, and you remember from Stan Spring that we do that with an at
post construct annotation. And spring will automatically
call this method once the whole object has been created. It’s not going to work just yet because there’s a missing step. But I would like to see if we’re getting as far in this and if we’re getting the same value for the ID here. And what I suggest is we go into the user detail service. And we put a bit of logging in here. And I’ll keep it simple
by using the system out as I’m with friends. And I want to make it really obvious so lots of backslashes
and we’ve added the user with ID and their ID. Okay, let’s do deploy
and see how far we’ve got. We’ve done some major rewiring work here. So you definitely want to
be checking the console. Okay so that’s quite a long time, but it’s at least stable. So we’ll run through the usual process. I am currently logged into Facebook. So let’s follow the link. And it took a while. And it might not be clear from the camera, but again not a lot
seems to have happened. We seem to have been sent back to this CRM login page. I’ll explain what’s happening
with that in a few moments. But I’m hoping that if
we look on the console this is actually looking pretty good. You can see that the user service has attempted to add the user with the ID. And this is the kind of key
that I was promising you. The key is Facebook; and actually that is my Facebook ID. That long number beginning 140. Obviously you’ll see
something different in there. So we’re clearly missing something and again I’m just working
with the sample code here. There’s one missing step. Well back here in our new controller what we’re also expected to do here is we have to manually create an authentication object for that particular user. And we can do that process as part of doing this add the new social user. So we go into the implementation method and what we want to do then is manually log them in. We have done this in
several different areas of Spring Security. You might remember this
rather ugly line of code where we call the security of context holder. There’s a get context method in there. And we can call the set
authentication method. I just think of
this as a manual login. This takes an object
of tight authentication but you’ll have seen before that’s a superclass and one of the concrete subclasses of that is the username, password,
authentication token. And this is an object of
a regular concrete class that we can instantiate directly. And what we need to pass
into the constructor of this is first of all the user’s ID. Well, that’s easy we have the ID here. The next parameter is the password. Well again, we’re not managing passwords in this application and
it’s never going to be used. So I used a string here last time, and I’m not sure, I must confess if that’s going to be valid here. But know that we can use a null. That’s for the password, and then we have the authorities. Exactly the same as here. So we can use the same object that we created before. That’s the reason, by the way, I decided to put these
lines of code in here rather than the controller. Because I’ve already got
this authority object here. Although it might feel quite different, you’ll remember we did
exactly this process. Back in module one of this course. When we want to register
a new user onto this site we did exactly the same process of once the user was registered, we created this authentication token and then called set authentication. I have to admit even after many years of working with Spring Security every time I do this, I always think, why am I doing this. Why do I have to go through all this work? After all, when an existing user logs in, all of this is done for free. Automatically. And I think the thing I always forget is Spring Security doesn’t know that we want to automatically log the user in. Just because they have just registered. If you think about it, there are a lot of sites where you register an account,  but that doesn’t mean you’re also automatically logged in. Perhaps you have to wait for an e-mail and you have to confirm your membership. And my point here is there are lots of different web flows that we
could implement around this. And Spring Security doesn’t
do anything automatic here for that reason. However, in this case, I think probably when you’re working with a single sign-on. This is the first time the user has done a single sign-on. So we’re signing them up. But I personally think
we probably always want to do this automatic log in. And finally, and I promise you we are now in sight of the finish. One more line of code and we should have things working. There is one further method on this provider sign in utils. And it is the do post sign up. And we’re expected to call that when we have completed this process. I’ll invite you to check the java docs if you’re really interested
in what’s happening here. Frankly, I’m not, and
I just had to call it. Passing in the ID and the request. We’re finally done. Now there are things we
can do to improve this and we can expand the
process a little bit. But what we have here I think, worked really hard to get the smallest possible example that could work. I know it didn’t feel
like a small example, but believe me, you can make it quite a lot more complicated than this. So let’s give this a build. Okay, a stable deployment. Let’s see what happens if
we run the process now. We try to sign in with Facebook. Well I hope you’re getting
the same results as me, that was a lot of work but we have reached a really good point here. Without providing the
user name and password we have securely logged into this system. If we check the console hope you can see there that yup we have successfully added this user with that particular ID to our in-memory repository of users. Of course, that would be one big thing that needs to change
in a production system. That would need to go into a database. But I also want to show you, this console is going
to be really important. If we were to, well first of all if we visit further links. Just checking the console, there’s some hibernate
logging going on there. But I hope it’s obvious that we’re not somehow adding that user again or anything like that. But importantly if we now log out. And come back later and the user decides to
visit that page again. Oh no, I’ve got to sign in. When they click sign in
with Facebook this time I’m going to go straight
back across to the log. It might not be entirely obvious but that’s where we deployed. That’s where we added that user. And I want to be absolutely clear here that even though we’ve done no special functionality to make this happen. Spring Social is clever enough to know, this user is already registered. They’re already present in
that in-memory repository. So therefore we’re not going through that signup process again. They are automatically logged in when they already have
an account registered. I think that is one thing
that was not clear to me when I first started
working with Spring Social. The login for existing
users is all built-in and all works. The work we’ve been doing here is just for brand new users. Who has never been seen
by this site before? To try to simulate that, I’m going to use a
completely clean browser. This is Firefox that I’m using here. And I’ve never logged into
the CRM system through this. So you can just imagine that this is the user has gone away and they’ve come back a week later to a completely different computer. They’ve never had any
history from this site but they decide now I don’t want to sign in with the form, I want to use sign in with Facebook. Now because we’re new to this computer we will need to log in. And good we’ve been given that page. But going back to the log again. Can you see it there? There’s no extra adding of any users. That same user information is being used. Of course, if somebody else comes along a brand new user. Then they would go through
the registration process. So though it’s quite complicated, when you get there it turns out to be quite an elegant system. There are a few small
things that I would like to do to improve this. But I promise you, you can relax now. The hard stuff is out of the way, just a few little things I’d like for you to polish up. Not least the fact that we also need to support twitter and linked-in. And if you’re worried about that it really is very simple to add those now that we’ve done all of the hard work. But before I get there I realize that it is slightly. Log out of here. If I’m a brand new user
and I’ve never registered with the site before and I just clicked sign in with Facebook. You can see it is a little bit harsh that I’ve just immediately been allowed access to this system. What we would usually do is ask the user to confirm that they are happy to link
their Facebook account with this particular application. And we probably also at the same time get some extra information about them. Like their name, possibly address, and that kind of thing. I’m not going to give
a full solution here, but I’d like to show you the steps that you’ll need to follow to enable that kind of process to take place. It’s really just a simple case of working with this request mapping
that we have here. And if you were disappointed that we had to do this manual work. And I admit it did feel
a little bit awkward, but this is the very reason really that it had to be manual because the Spring Social team has no way of knowing exactly what steps we want to follow in our web flow. And that’s really what we’re doing here. We’re setting up a web flow. So what’s a very common approach is to split this method into two, step one will just be saying, User are you sure that you want to link your account with this application? And step two will the process of actually adding them. Doing the post sign up, and doing the redirect. So let’s do that. We’ll split the method by simply copy and paste it. And the easiest way of doing this is to make the first method be a get. So we can do that by making this a value. And then the method equals
request method dot get. Standard Spring MBC. This is going to do
step one of the process. So I’ll rename this to
confirm the user is happy to link their account. Okay, let’s work on this method first. Then we’ll come to this
method in a short while. And we don’t actually need to
get their ID at this stage. So we can remove these in
fact three lines of code. The reason we don’t need
their ID at this stage is that’s only needed in step two. What we might want to do. This is completely optional. We might want to get
some of the user’s data from social media. I’m going to demonstrate that. But I’m not going to do
anything with this data. But you could potentially. Add that into your user
details service in step two. So rather than just storing an ID, you might store their name
and address or something. So I’m going to simulate that just by getting the e-mail address of this user. And I can do that by
calling fetch user profile. Followed by get an email. And then I could go ahead and get some further fields as well. As you’ll remember from before though, there’s no guarantee that
you will be able to get all the data that you wanted. It depends on the platform, it depends on privacy. And then we’re going to
return a new model in view, not a redirect this time but, we’re going to send them
to the confirmation page. Now I don’t know about you but I don’t want to be writing web pages at this part of the course. So in the additional files folder. You fill find a JSP file
called link with Facebook.jsp. Copy that into your web folder and you can have a look at it by opening it up in the text editor. You see it’s a very simple form. It’s really nothing more than saying do you want to link this account? And I’ve shown you here how we can reflect back to the user some of the information that we’ve got from Facebook. In this case, the e-mail. And if I had time to go further with this. I would probably include this e-mail as a field in the form. that would enable me to reflect back to the user what the value I’ve obtained for that e-mail is. But it would also give the user a chance to edit it. If it’s wrong or of course
if we didn’t get one from the social provider. We could of course do the same with their address, and
any of their other details. I realize this chapter
is getting a bit long I don’t think you need me to do that. Essentially just standard web design. Now because this is a springform tag you probably remember that this is going to default to a pos. And therefore over here in the controller, we can make step two to change that to value,
and use the same URL. But we would use the method, request method.pos. And therefore this will be triggered by them clicking the button on that form. Well, I’ve not quite finished
this first step yet. I need the model in view. Which is going to be
linked to Facebook.jsp. Optionally as part of the model, we can pass for example
that e-mail across the form. Remember we could make
a map of keys and values if we had multiple
values that we wanted to send across there. So that’s step one. And then in step two, well actually there’s nothing to change. We need to get the connection again. So we can get the ID of that user. And then we get the same steps as before, the only thing that I would improve on a real production system. Is I would consider storing this e-mail, their first
name, their surname, and so on as part of
that social user record. That should be fairly
simple for you to do. I don’t think that would
add much right here. So let’s see if that works. Because we’re storing
the user’s data in memory all my previous registrations will now have been wiped away. So let’s run again. Sign up with Facebook. Had a typo on the link to Facebook. It’s actually linked with Facebook. It’s getting very late in the recording. You might be thinking that we need to add that into the URL map in the security but remember
that’s the internal name that we’re forwarding to. The address that will be
visited by the browser will be forward slash sign up. Which we have excluded
from our secure URLs. Could be a mistake, but let’s try again. So, sign in with Facebook. And great, so we’re now getting
the confirmation screen. A good exercise for you
to extend the system would be for you to attempt to get the user’s avatar
or their profile picture from social media to kind of give the user a very visual clue as to what we are doing here. I’ll just check the
console and you can see there’s no registration happened just yet. Let’s have both of those on-screen at the same time. If I click the link my account. Then great, it’s done step two. It found the ID. And it’s registered. If we now log out and repeat the process this time we’ve already registered so it didn’t do that again. So that’s all good. And the final step, well this feels like a big step. But it’s really not too bad. I promised you at the outset that we were going to support signing in with Linked
In and with Twitter. There’s almost nothing to do or at least in terms of our application. If we find our login.JSP page it is a simple case of
repeating this link. And replacing Facebook with Linked In. Replacing Facebook with Twitter. And we’re almost done. Well, we will have to repeat the process if I find my misc beams.xml file we are going to have
to repeat this process of setting up an app id and an app secret for each of those providers. And it does mean, believe it or not. I’m going to have to repeat
this namespace work. This is incredibly tedious. So I’ll copy the Facebook line there. And add an entry for Linked In. And it’s just a case of really just changing Facebook for Linked In. And we’ll do the same for Twitter. And then yeah, you guessed it. We’re going to have to
repeat the two lines here that are declaring the xsds. This is horrible. And then replace one of
the pairs with Twitter. And the other pair with Linked In. That’s the only unpleasant
bit of this process really. We will then be repeating
the configs here. So one will be Twitter and one will be Linked In. Well of course these
app IDs and app secrets are going to be different. I’m going to have to go
through the same process with these providers of
registering developer accounts. For twitter the URL is dev.twitter.com. And when you’ve logged in, and of course you will need
a Twitter account to do this. Down at the bottom, you will find a link for managing your apps. I’ve already created a couple
of apps for some other work. But should be fairly simple process. Create a new app. The name can be anything you like. 32 characters maximum. Some kind of a description. The website doesn’t actually have to be a real live website as they say here. You can just put a placeholder, but I think I’ll go for
my real company domain of virtualpairprogramers.com and we don’t need a callback URL. Once again you will need to agree to the terms and conditions of Twitter. And then we can create the application. And now on the keys
and access tokens link. You can get the key in secret, get those copied across into your Spring XML. We’re probably going to need to change some more settings in there because I guess we might have to work with the redirect URIs and so on. But it’s definitely worth deploying now, we still have Linked In to work on but let’s see what happens
if we try Twitter. The most common error here I would imagine is a fault in the namespace configuration that we did at the top. Yeah, we do have an exception there. Or at least I do. I’m sure this is just a typing mistake if we keep going up. Yeah, I’m seeing XML now. There’s a problem with the definition of my Linked In colon config. And if I go up to here, okay I should have said Linked In there rather than just Linked. Errors are inevitable there. So I’ll rerun the build, that’s looking stable. So let’s run the process again. I could do with improving
the layout of these links. I always get Twitter and
Linked In mixed up in my head for some reason. So be careful to use the right one here. We’ve only done Twitter so far. Let’s try Twitter. Bah, well I thought
this was going too well. Very unhelpful four zero
one authorization required what on earth is going on here. Now if we have a look in the logs we might have a better clue. Yeah, we can see there
is an error log there, if you’re not seeing that, then you might need to change your log to j properties. And the error is reporting, this is clearly an adjacent response that’s come back from Twitter. It’s reporting some kind of error. And it’s saying that desktop applications only support the auth callback value oob. Now oob just means out of the band. And well, that might not
be very meaningful at all, but a simple search on
this string suggests that it’s a simple case
of that callback field that we left blank, and it was perfectly
valid to leave it blank. But it does need a value. It’s this callback URL and this is not the redirect URI, so you might have been thinking about putting local hosts in or something like that. Now I don’t fully understand
the full implications of this because I don’t use the callback URLs. But it just turns out that
you need a value in there. And it really can be anything. A kind of placeholder if you like. We’re not using this callback URL anyways, so you can just put in
there any valid URL. You cant use local hosts or an IP address so I’m going to use my company’s domain name. If you don’t have a domain name, I think, I’m saying
this with some caution, but I think it would
be fine for you to use virtual pair programmers.com as well and you would be just effectively using that as a placeholder. So we’ll update those settings. Make sure you’re not seeing any kind of error here. So back to the application then. And we will repeat the
process, sign in with Twitter. Now I’m going to leave this in the video because I’ve had this a couple of times just after making changes on the console. I think that’s just a hangover
from the previous attempt. So if you see that error don’t worry, just wait a short while and go back in and reissue that URL. So we’ll try signing
in with Twitter again. Looking a lot better now, looking a lot better now. And now landed on the Twitter site, I am logged in. We have to approve and click sign in. And now we’ve gone back
to the application. Notice that the callback
URL that we used on the site has not been used. It’s done exactly the same process as we had with Facebook. Once again I’ll pull the console up. We’re currently at the feet
of that long exception. I expect when I press this button, of course, that should
not say Facebook anymore, and nor should it say Facebook there. So a minor change in our user interface, I won’t bother doing that. Click the button and that looks good, we’re logged in. And the ID you can see is now different. It’s a much shorter number for Twitter. But we do have the correct prefix. And just click the link a few times. That’s looking good. And if I log out, I’ll
do the same kind of test. And I’ll put both of these in view. If I now sign in with Twitter again, I did seed and field the
redirect from Twitter. But wonderful, it’s working with that existing user that I’ve registered. So surprisingly simple. Just a few little catches on creating the application itself. And now to complete the work, we need to do exactly
the same with Linked In. For Linked In the URL are developer.linkedin.com And this link at the top here to my apps. Now I’ve had my Linked In
account for a long time, and I’ve been a Linked In
developer for a long time. Now I can’t remember if you have to do any special steps in order to become a developer on Linked In. You certainly don’t have to
pay or anything like that. But you might have to do some extra authentication in order
to get to this page. And I think at this point in the course I probably don’t need to step through all the tedious steps of creating an application. It’s pretty much the same
as Facebook and Twitter. And the usual kinds of things apply. You will be getting yourself a client ID and a client secret
which we will need to get into the configuration. This one Linked In. And the default application permissions are just a basic profile for logging in. And you will need to
provide, as with Facebook an authorized redirect
URL which is going to be the usual pattern. CRM/auth but with forwarding slash Linked In. And that’s under the orth two URLs. Now I seem to remember when I created this I actually created this
quite a while ago now but I think you’re forced
to add an image as well. So that’s done. So that’s our final provider. I’ll check that this works. Okay so Linked In this time. I didn’t feel any Linked In there but I landed on this Linked In page. It’s annoying to me now that we still have Facebook on there. So let’s approve. We’re logged in. And there’s the key for Linked In. That’s my key, fantastic. Let’s log out. And check that we can go back in. And that’s working great. And it still kind of surprises me that after all the hard work we’ve done in these chapters, once we’ve got all the infrastructure in place
to add Linked In and Twitter was fairly straight forward. So just one last task to do
before I close this chapter as well as supporting single sign-on, it’s a good courtesy to
also support traditional form-based authentication. And of course, at present, these are broken. Absolutely no problem. All we would do in the
authentication manager here is to provide multiple
authentication providers. We can restore as a quick test of course this could be any authentication provider that you like. I’m going to use that in memory use the service with the r
coded usernames and passwords. So very quickly, one username. One password. And they have the authority of role CRN. And I will need to
remember this file at least beneath the security
names based on the front. So no problem in having multiple authentication providers there. The correct one will be used. So let’s check the form based login and that’s back to working again. Check that it fails on that password, but if I prefer I could use any of these. Let’s go back to Facebook. And I need to do a link
because I’ve redeployed. And that’s still working as well. I’m going to make two
improvements off the camera. For the purposes of practical encode, they’re very routine so I won’t take up any more of
your time on the video. But do check the practical encode solution if you’re interested. The first thing that is bothering me is we have this Link with Facebook page. And well really that’s confusing because it’s also Linked In and Twitter. My plan is a very basic
bare-bones implementation of what we could do. Here in step one, where we
forward to this model in view. I’m going to use that connection to get the key. That’s the key we’ve been seeing here. And the key isn’t a string, it can call methods on it. And one of them is provider ID. So given that I’ve got this provider. I can now do something with that. I can either create multiple JSP pages and simply insert this
provider into the page name. Or I could send that provider
as part of the model. And I could render that on the JSP page. So very straightforward JSP. I won’t do that here on camera. But check the practical encode if you want information on that. And the second thing is that when I started the recording I made a bit of a bad decision really by putting these Spring
Social beams here in misc beams. Because remember with our client, our stand-alone client that’s been very useful
through this course. And this would be exactly the same idea if we were using an integration test as well. Is that this does load
the misc beams.xml file. While this is a stand-alone client and there’s no way we’re
going to be calling Facebook from the stand-alone client. So I really don’t want to
be loading these things as part of the stand-alone client version. So just off-camera I’m going to refactor this and move these beams into the crm.security.xml file
and remember this file is where we’re doing all
kinds of web-based activities. Quite a minor refactor. It’s going to be quite dull to do. But if you check the
practical encode folder you will find the results
of that refactoring. But apart from that, we’ve
done a lot of hard work in these chapters. And I hope I’ve given you a really good sort of
bare-bones implementation of single sign-on that you can bend and extend to your own requirements. So well done if you got this far.

As found on Youtube

Categories

Tags: , , , , , , ,