“Escape to the mountains” — The angels told Lot to escape to the mountains because that was where Abraham had been all this while. The mountains speak of the high place of moral elevation. However, wouldn’t it have been better to have stayed in the mountains all along, instead of fleeing destruction to reach them?
Spring Framework: Authenticating Users with Spring Security
Hi, everyone. My name is Brian Hansen and welcome to my course spring security fundamentals. I am the CEO of Complete Programmer and a director of practice development at Software Technology Group. Security is a complex topic, and doing it correctly can be challenging. In this updated course, we're going to cover authenticating users against l'd app also, how to authenticate them against l'd app and authorize them against the database. We're going to customize the's spring security object at details that will be unique to your application and your instance. We're going to look at creating a custom registration process for spring security and also how to handle a forgotten password using spring security. By the end of this course, you'll know all the fundamentals of spring security and how to implement that inside of your Java application before beginning the course. You should be familiar with spring and some spring NBC. Some I hope you'll join me on this journey to learn spring security with the Spring Security Fundamentals course at Pluralsight
Configuring an Application to Use Spring Security
It was 2003 and the development space in Java was far from standardized spring. NBC wasn't even a widely accepted web development framework yet, although there were a lot of options for front end frameworks then there weren't many options for security frameworks inner spring security, although at the time it wasn't called spring security, it was called a C G spelled a c e g I. That is what fueled the original release of this course. Now, years later, this course was due for an update. We're going to talk about the reasons to use spring security and what has been updated in this course since then.
What Is Spring Security?
spring security is a framework written on top of the spring framework that will provide you security features inside your web application. IT handles things like authentication and authorization for web app SA's well as web services and can tie into just about any authentication store or authorization store that's out there. Spring security was how I got my start into spring development as there wasn't a robust, full featured security framework out there. Candidly, Spring security is still the most feature rich security framework that I have worked with in the web development space to date.
One of the best reasons to use spring security is its integration strengths. Its roots are in just securing web applications, but it's a great client when used in a cast installation as well. Many people think that when using cast that you just have to use their client tools. Hooks and spring security are actually great for integrating with casts and are one of their preferred methods similar to cast. Spring security makes handling the tokens of O off Great. Both can be a very complex animal, but spring security can help manage its complexities. L'd app is also a great authentication mechanism. And using spring security, we can authenticate and authorize against l'd app or just use it for authentication and then authorize against a database. This is, in fact, one of the most common uses of spring security for internal apse and not to leave out web services. Spring security is great for wrapping them with security as well
let's cover the architecture of spring security a little. We'll go into more detail in some of the areas as we continue throughout the course, but I want to give you a baseline for the start of this course. Spring security is built on top of and uses spring. IT is centered around web APS and uses a filter entry point. It is built around multiple authentication models and handling the various roles inside and app. It also encourages APS to-be inherently more secure through encouraging the use of salts. If you don't know what assault is, don't worry, we will cover it later. But suffice it to say it helps hackers not be able to crack stored passwords. One of the main reasons I began using spring security years ago is it helped to avoid session hacking, session hacking or a man in the middle attack is where someone can fool the server into thinking IT iss someone else. Spring security has a few mechanisms in place that helps safeguard against that, and lastly, spring security is very full, featured from authentication and authorization to remember me services, an email confirmation. It's all baked into the framework. Let's look at some of the prerequisites that we will need to complete this course
Getting the Code
in an effort to make this course shorter. We've started with a pre developed application that we've actually built in previous courses of mine. There are two ways to get this code you'll need to do one or the other. If you want to develop the examples as we are in the course, I have a sample projects set up and running and get hub that you can fork to your own repo and use source control. If you don't want to use git hub because it does add a little more complexity of the app. These source code is available in the example files section under the home page. For this course, the instructions for setting it up there are in the Zip file for each module of the course. Let's walk through forking the project to your own repo now and setting it up locally for your instance.
There are a couple of ways to use git hub, and I'm going to show you the simplest. As you can see from our u. R L here, get hub dot com slash b h five k slash Spring dash Security Dash Conference that here is our project and I'm running this off of the master branch. If you know nothing about get Hub, it's not a big deal. Choose clone or download and download Zip. This will download a ZIP file containing all of the current source code to our desktop. Now the other options in here open and desktop the URL. If you don't know what they are, then I'm going to recommend again that you choose the download zip option. If you understand what those are, then you can go ahead and use. Get have desktop or one of the other tools that will allow you to interact with get hub locally. Another option is for you to fork this, and I'm going to click on this to show you your options. Gonna look different. You'll have your local repository that you could fork this over to, and if that makes sense to you, then great, you may want to choose that option so that you can continue to use source code control on your local project in case you want to roll something back or you make a mistake or you just wanna compare the changes through each module. If those air options to you and are entertaining, I recommend you do that. If not, I'm going to show you how to go through the downloaded ZIP file that we just did and set up your project locally.
Demo: Project Import
Once you have downloaded that zip file and open it up, it should look very similar to this. You'll see a source directory and a palm dot XML, and I've also got a dot get ignore. That's kind of great out because it's a hidden file you see inside of here. We have our basic web application that has all those pieces configured. I'm going to copy that over to my Dev Workspace directory that I use in all of my courses. If you've seen that before, here you can see where I have copied it into my workspace. And I created a spring death security folder, and underneath that, the conference folder now I would recommend naming your project conference. You can name it whatever you want, but if you name it conference, IT will follow along what we do inside of the examples as well as it does affect your u. R L. If it's not tied to the Palm the same way that doesn't make any sense. Don't worry about it. I would recommend having IT named the same way, but this is the folder structure I have set up. Let's go ahead and open up. Intel Ajay and import that project in. Now, if this is the first time you've used in tell Ajay ultimate you'll be presented with this dialogue that asked you if you want to create a new project or import of project or if you remember when we were showing the get hub Io URL you can pace at your Ellen here to get it from version control. We're gonna go ahead and choose import project and you want to navigate to the directory where you copied IT. Mine is Dev Workspace Spring Security. And I just want to go to the root of that project and navigate into that folder structure. Choose open. Then we'll ask me if I want to import that project from an external model and I'm gonna choose maven and finish. And for a minute it will be building the project and indexing files and all of that stuff. In fact, if we click on the Maven selection over here, you'll see that it now shows our project inside of here and all the different things we can do to our project as well as if we click on our project structure we-can C conference and our source directories and all of those features inside of here. So we have our project. It's all imported. And now we can start setting that up to begin with. If your project does not look like this now, you have missed a step. So don't try to go any further. If you don't have the maven selection on the right or your conference structure doesn't look similar to mine on the left, you have missed something somewhere. So go back and double check yourself. I'm gonna open up conference inside of our maven tab on the right and go toe life cycle, and I'm gonna double-click package. And this will bring up a dialogue at the bottom where it goes through and builds all of my source code, compiles IT and gets it all packaged up, ready for me to go as it's built and deployed. Now, this did a couple of things. IT set up my target directory for me, but it also created a deployable artifact that we're gonna to use to set up Tomcat Now. Now that we've built our app, I'm going to go ahead and add a server for it. I'm going to go up and choose are edit configurations option. You'll notice there's already one created for us, and that's because they're trying Thio automatically deploy it to TC Server. I don't want to use that. It's springs proprietary server that they have that they do different things with. So I'm gonna click edit configurations and click the plus sign, scroll down to Tomcat Server and say, add new Tomcat server configuration local and inside of here. Mine already chose tomcat 9.0 dot 30 and that's because I have a tomcat instance already downloaded. If you don't, you need to choose configure and point IT Teoh a downloaded Tomcat server. So I've already got one downloaded. You just point it to whichever version you've downloaded and you're good to go Click. OK, You'll notice, though, before we go any further, there is a warning down here saying no artifacts marked for deployment and a fixed link. We're actually just going to click on the deployment tab over here, and this is why we ran maven package a minute ago. We wanna click the plus sign and say artifact and choose conference colon war IT okay, and click, apply and okay. And now, our server tab should pull up, and we can choose to start that it will deploy our application. If you've added your project, you can choose to not ask for all those files. Automatically be added to your get instance because you probably don't want them there. And once it loads, it should pull up this application just like this. So you should see exactly what I'm seeing here. Notice it started us off by not going to the log in page, and that's because we haven't created one yet. So if we go in here now and click add registration, it'll go through and we can put in a add registration and it just functions like how we had left it at the end of the spring. NBC Fundamentals course. So now we go through and start adding all the security features that we want to to our application
Demo: Exercise Files
if you've gone the other route of not looking at the Git Hub instance, which is fine. You can navigate to the home page for this course and choose the exercise files and download exercise files, and we'll download a ZIP file of all the before and afters for each module that we've done. Once that is finished downloading, you can open it up and see there's a folder for each module has a before and after, as well as a set up doc, I'm not going to go through and read Duplicate from here how to set that up inside of the I. D. Because it's the exact same as the get hub demo from this point. So if you need to see how to set up the Tomcat instance or configure maven and that type of stuff, you just go through and follow those same set of instructions, and the set up doc will explain that as well
Spring Security Vocabulary
now that we have our project set up and before we dive into code, let's go through some vocabulary to start. The entry point of security is authentication, and that is where we will begin to finding our vocabulary. Authentication is determining. I am who I say I am after the app has authenticated us. We need to see what we are authorized to do. Thes two pieces are the key components of our app. The other things that we talk about our how we honestly do these two activities. The entry point to our application is through a filter. The filter is a standard J doubly filter. It really isn't important if you haven't written one before, just realize that it's the entry point of our app and we will configure things to utilize IT. Once you have entered the application, you have specific roles that you can perform or rights inside of the application. From here, roles are defined and stored in three user. This is the basic information about the logged in user, while more specific details and the contract of what we can do is accessed through user details. The last two items that were going to cover aren't specific spring security terms, but rather mawr General Spring terms, the first being a service, not a web service, but the service tear where business logic is stored. The second is a repository tear, and this is how we access data and work with it. This is definitely not all the terms we will work with, but the main points that we will cover throughout this course. If those last two give you any concern or you don't understand what they are, you may want to revisit the spring NBC fundamentals course.
to recap what we learned in this module. UI briefly covered what ISS spring security and spoke about the update to this course. The second thing that we spoke about is the integration of spring security in the web, APs and how this is done. Then we covered the architecture of the app and how we integrate security into IT. Then we spoke about the prerequisites to run the code for this course. And as I mentioned, we're choosing Java 11. I've get all sorts of people asking about 12 13 and 14 that they're out. Why aren't we using that? It's because 11 is the long term support I do recommend following the versions we have in the course, as I mentioned previously, because that will guarantee that the examples work the way we intended. After that, we looked at both ways to get the code using Git Hub and the exercise files, and we went through the sample project. Lastly, we discussed the vocabulary for the course and covered the main term that we will use throughout. Now let's look at how we begin securing our application
Securing Your Spring MVC Application
as I mentioned before spring security was what actually brought me to the spring framework to begin with. At that time Spring NBC wasn't very robust, but spring security had all of the features. I needed them to secure my app in this module. We're going to take the scaffolding application that we just downloaded in the previous module and wire it up with spring security. If this is the first time you've used spring, NBC or spring Security, we will just enable the basic configuration to get our app secure and get it wired up for the remaining modules. Before we start wiring up, though, let's talk about the architecture of IT.
the architecture or process that is associated with securing an application is typically broken down into two parts. Authentication and authorization. I'm going to mention this quite a few times throughout. This course is it really is the pieces of the application that we need to configure to have a secure application, and subsequently every piece that we deal with throughout this course will tie to either authentication or authorization.
authentication is all about determining that I really am who I say that I am. A lot of authentication is typically done using L'd app or an active directory server for the authentication store. But we consume plea, use a database or flat file and determine who we are based off the credentials that are entered into our system. It really boils down to just determining that I am who I actually say I am. For development purposes, there is an in memory authentication mechanism that we can use to get up and running quickly. Making the distinction between authentication and authorization is one of them or confusing parts of security.
authorization is what we can do inside of our application. Once the app is determined who we are, it now looks to see what we can dio. Authorization will always follow authentication. We first need to determine who we are and then determine what we could do inside of that app. What we can do can be very coarse grained descriptions, such as a Web application. Or it might be as fine grained as a user being able to see a specific filled or button on a page or possibly perform a certain action inside of our application. It can even be used to filter the data set we are able to view to set both authentication and authorization up. We need to add a few libraries in maven in our app.
since our app started as a spring boot app and we broke it out to be a standalone app. We can continue to use thespian boot dependencies for security. Doing this will give us a few things pre configured that we can build upon. There are two dependencies that we need to add spring boots Starter security, which has transitive dependencies for the other libraries we need and spring security test. This provides us with libraries that we can utilize to set up our app and get up and running quickly. Although we aren't going to utilize great URL in this course, let me show you the same configuration using great URL.
Although we aren't using great URL, you can see here we need to utilize thesis aim to files inside of our great URL file. If you aren't familiar with grade, all, don't worry about it. They are in fact, downloaded from the same maven Central Repo. Let's go ahead and add that maven configuration to our app now.
Demo: Adding Maven Dependencies
I've gone ahead and opened up our project How we had IT from when we downloaded the scaffold application. We want to open up our palm dot xml. Now, our pond that XML file has this dependency section in here where we've added in all of the dependencies that are application needs. And if you've used may even before and you followed my other classes, this shouldn't be new to you, but we'll go through it. Still, I'm going to go down below or IT dot hibernate validator and give myself some white space. And your should be pretty similar to this is well, and I've already copied. And I'm just gonna paste these to dependencies in there and I'll walk through them with you. And it's just so you don't have to watch me type these in. I've got to dependencies inside of here. I've got spring boots, starter security and spring security test, and you'll notice they were red for a second while they downloaded those versions in there. And so now I have these two pieces in here, and I wanna point out these two different classes, what they're doing or what these artifacts are doing for us. We have the spring boots start a security which will add some default configuration files for us. In fact, we'll have a log in page out of that by default and then the spring security test, which will enable us to go through and write test against our application notice here on line 48. In my app, there is a scope of test in here, so spring security test will not get bundled with our war. When we deploy it, that's what that scope is associated with inside of maven. So now we have this in here. Let's go ahead and look at the other pieces of our app and what we're gonna start wiring up.
a major change that was just beginning in the previous release of this course was the migration from XML in our application. IT started first with not having XML in your spring code, and then other standards pushed for it as well. More recent serverless specifications have even called for not having a web dot XML. XML is often thought to be more complicated and at a minimum is more air prone for copy and Paste airs. Not using XML, though, it could be a little bit black box. Feeling in what I mean by that is, if you start using it but do not understand what's going on behind the scenes, it could be a little confusing. So this often leaves developers confused about how their application is working and furthermore, left wondering what to do when something breaks. Since this is an update to an existing course, I wanted to show you the old security config dot xml, and if you go look at other examples, you may see XML configuration code that was written this way, and so you'll see we had an authentication manager and a provider and a user service inside of here and the username Is Brian the password? A secret on I have the authorities or rolls inside my application of a role underscore user. That same thing can easily be written in Java code. Now here you can see we created a user with the default password encoder scheme. UI added. The username user to it in the password password to it and the roles of user, and we build this object. So it's a standard builder pattern. If you're at all familiar with that, now that we've shown you a couple of techniques, let's go right this code into our applications so you can now see how to utilize this.
Demo: Configuring Minimal Application Security
alright. To begin adding security to our application, I've gone ahead and closed down everything we did to running a sample app and any of the previous demos and just got it down to three. The default workspaces closest possible. I shut down the servers and everything else. We're gonna start by opening up our pom XML file. We're gonna add three dependencies inside of here, so I'm gonna go below my or dot hibernate, validator. And if you're starting from my example, you should have the same exact code inside of here in a paste in these three dependencies. Now, I realize you won't have the same dependencies that I do to pace in here because you don't have anywhere to copy them from. You can actually go grab them from the exercise files or you can type them in. It's actually not that hard to do so because the context sensitive help will help you do that with any I d they choose. I will point out three things here, one that we have the spring boots starter security dependency. And there's not a version tied to that because we are using dependency management. If you don't know what that means. It's a maven term that it chooses the correct version based off of our parent Palm. I have spring security test inside of here, and it has a scope of test that you can see to find their online 48 no version, because that's also being pulled through that dependency management. The spring security test gives us some sample libraries to create an in memory database or l'd apps server. That type of things will use it for that. And then I've added one for some J E stuff. The Java serval. IT JST l library job serval IT JST library that allows us to do some simple navigation things inside of JST l like including and excluding fields and some binary logic that way. So these air three dependencies we need Now, let's go ahead and start by opening up our registration page and selecting all the code inside of here. So I'm just gonna do a command, a command, see, Or if you're on a Windows machine, control a control, see right-click on jsp and create a new JSON PJ SPX file. Call IT log in dot jsp IT dinner and I'm just gonna replace all the code we have inside of here with that registration page that we just copied. I want to add a new tag library at the top, so I'll get myself a little space there and do an open left angle bracket percent at sign. Wanna choose tag library and the prefix of that we're gonna choose C. The u R I is equal to http Java Sun com gsp GST l corps. She was that one. I'll give you a second Look at that. And if you don't want to type all this stuff in there again, you can grab this out of the exercise files and just copy and paste it as Ugo and walk through. So you're not hung up on the syntax, but rather looking at the semantics of it. Or you can go ahead and pause and type it all in there as well. Want-to scroll down and change line 11 from registration to log in. And then we're gonna go down a little bit further and online 41. I'm gonna change this to log in as well. And then I am going to replace this form completely. You may want to go ahead and change the fields that are in there. But I would not like you toe make a typo or miss a step that's doing that. So you may want to completely delete it because there's a bunch of things we're gonna change in here. I'm gonna walk through that right now, okay? Replacing mine. I'm going to highlight that and paste in a new DIV online 44 45. And this is utilizing that tag library that we just put in their of the core or C tag live that It looks for an air in our response and displays that air if there is one. The example work just fine without that. But if you get any areas, you won't be able to see them. And then I replaced our form with lines 47 through 52 where we now have an action equals perform log in and a method post, and this will all tie into what we're doing on the back end here in a minute. And I'll pull both files up side by side so you can see what's tying to What if there is an air online 48. We're going to display it with a form colon errors. Path equals all of the air's that are out there. Use this CSS class air block and then you the element div. For that development that we have to input boxes. IT username in a password. Very simple, just standard input fields and then a submit button. It's a just roll button, and it will go ahead and post that back to the server. So very simple. A two filled input form with a submit button tied to log in and displaying error. If it's there now, we can save this and exit out a full screen.
Demo: Configuring Security Using Java
Demo: Configuring the Login View
we do need toe add a view controller and there's a really neat little technique we can use to do this because all we want this to do is display the log in page and go to our security on the back end and back out to the front. It used to be we had to create this default controller that did nothing Except for now. We can go ahead and open up our conference config and add one method inside of here. I'll just go ahead and do it below my class declaration. But above everything else doesn't have to be there. But just put it up the top so you can see it with the imports and things that were using E going-to say at override. Thank you, and we'll give this the signature of public void. Add view controllers and instead of here, has a method signature of final view Controller registry, and we'll give this a variable name of registry. In sight of this method. We-can Add one line where we just say registry dot ad view controller and we'll tell it to you handle log in, finish that off with a semi colon and we're done. We're ready to run our example. So a lot of work to get it to this point. Let's go ahead and start our server now instead of our app. If we click add registration, it will take us to a log in page where if we enter in Brian and pass and click log in, it'll log us in. Redirect us back to the default URL, which is our index page. Click add registration again. We're logged in, so we're unauthenticated user. We're gonna go ahead and build on. All of this is we go out through the rest of this course, but your-app actually now has authentication. Let's quickly look at what it took to get us there inside of our palm UI had toe add three dependencies to the bottom section. Here we had our spring boot started Security Spring security test and RJ STL dependency that we had IT. UI copied our registration page in tow, log in and added a basic form section in there which had the u r l of perform underscore, log in for what we wanted to tie. Our request to the majority of our work was spent in this conference security config file where UI configured the HTP security object and the authentication manager builder and then a password encoder. And then finally, we added a view controller to just redirect that log in page and handle our log in back and forth from thes jsp page to the controller. We didn't have to create a whole separate controller just for that. This all enabled us to have security inside of our application. Let's continue on with the rest. Of course. Now, where we're gonna remove from these default pieces and add in databases. L'd app that type of stuff, but you've added security to your application now.
Fixing Maven Errors
I wanted to take a second and show you one tip or trick that you might need throughout this course, and it doesn't happen very often, but it's one I get asked enough in the discussion forums that I wanted to show it to you. If you have a problem with the deployment of your project or something doesn't seem to be working quite as you had expected to, you may want to go over here to your maven, sidebar and click the Clean Goal and have us go through and completely delete all of the resource is associated with your generated files in your target directory and then compile IT. That's often enough. I actually like to do a package or even install. If you're unfamiliar with those terms, you may want to go through the maven course that we have out here on Pluralsight. It's actually another course of mine that will explain what's going on when it does this, and essentially, it's gonna go through and completely rebuild your whole deployment artifact that you send to your Tomcat server. So if something stuck and I see this more with Windows machines than I do, other machines, not just with them. But that does seem toe have a resource every now and then gets hung up because it's stuck in unemployment or something is not quite right. If you're having problems, try that clean and compile or package. I will say that I see this more often. If you are using, get hub or a source code control repository and you're checking out versions of code and you might have a file that's newer than what you had before or vice versa. So it doesn't look to force a compile on it because the time stamps have changed on that file. So if that's a problem, something seems stuck. Just click that may have in sidebar Clean Compile package and 99 out of 100 times. It cleans up any problems you may have going on in your workspace.
Let's recap what we learned in this module as it is a bigger module in our overall course. The architecture of spring security is important to learn is that will help us understand how and what to configure throughout our application. It helps us understand the authentication and authorization portions of our app. We know that authentication is proving we are who we say we are and authorization is what we can do inside of an application. UI then added the dependencies inside of our application through maven and showed the difference between Maven and Gradel UI are using maven in our course. UI also showed the configuration oven app using XML and the transition to know XML. After that, UI briefly showed the minimal configuration and then broke out our app into use its own separate configuration. And that's what we de mode through the last portion of the course. All of these concepts will help us to secure our app against a database, and that's actually what we're going to do in the next module. So let's dive into that now.
Configuring Spring Security to Use a Database
Securing your application almost always involves a database. If it's for both authentication and authorization or just authorization, we will need to be able to utilize a database to do so. This module will focus on the various methods to access and use data for security purposes.
In Memory Storage
we're going to start off this module with a simple and memory database. This is a great way to get things up and running and try some things within your application, but not really something that you should deploy your application to production in the long run with the good thing about it is switching to a different database from Thean memory version should require very few code changes. In fact, usually just some basic configuration changes. Spring enables you to add a couple lines of configuration and not need to know anything else about the underlying data store. And this is the code that we will configure in our app, using in memory authentication a user named Brian in our case and a password of Pass. This user will also have the role of user assigned to IT. We could have other roles or have a different password. As you can see, it's just defined by us as to what we're looking for inside of this. Let's add that to our application now
Demo: In Memory Storage
If you follow along in the previous demo and set up your application to have the basic security configuration installed, you've actually already done the work required to have the in memory authentication set up. If you open up your conference security config file and scroll to the bottom, you'll see this configure section that takes a final authentication manager builder off argument. And instead of here, we have off dot in memory authentication. So that just tells us that we're going to start off with using in memory authentication. And then we define it to use with user Brian and a password that uses Thebes password encoder and encodes thebe password of Pass and then assigns a roll of user to our application. So this was already done. If you haven't done that, then you'll maybe want to add that in here now, but realized that this is using the equivalent of an in memory database, and we now have basic authentication set up inside of our app utilizing thes features. So this is how it all ties into IT. Now I want to go through and talk about how you change this off dot in memory authentication into J. D. B C authentication
switching to a real databases not much more difficult than what you already had configured. Since this is an updated course, though, we're going to do something different. Instead of just installing a database natively, we're going to use Docker to install a container and access the database through the Docker instance. This really is how development is moving, and it is as a simple as's using maven. If you've never used Docker, don't worry, it's quite easy, and we will walk through the configuration of doing so with this course, Just like with the in memory configuration, we need to configure the BBC authentication. But before we make those changes, let's talk about Docker. You do not need to use Docker to do this course, but it is the industry standard preferred way. If you haven't used Docker yet, you should. But if you just want to install my sequel natively, you can or you could just watch this demo and not do it at all, you will still be able to do other stuff in the course, not having used Docker. So if you don't want to do this section, I just wanna watch it. That's fine. We are going to go walk through the Docker configuration now, though, and you can see how that all works
all you need to do to run Docker is to have the Docker desktop installed. And you just go to Docker dot com for that and download the version specific to your operating system. From there, we're going to add this Docker dash composed file to your application, and it will set up everything. And in this case, we have a database. Its image type is of my sequel. 57 Thekla Tainer Name is Conference Underscore Security. We're gonna bind the ports that are exposed on your operating system to this port inside the container of 33 06 Gonna show us where it's going to store the data, which is underneath our project in a dot data directory slash D B and then for our environment. We're going to say that the my sequel Root password is pass and the database name is Conference underscores security. So we have all of our stuff set up and configured right here. Let's add this to our application now and we can start up our Docker instance
Demo: Docker Database Setup
I've closed down everything that we had open from our previous demos, and I am ready to now start adding the Docker composed file to our application. And like I mentioned before tohave Docker running all you need to do is go to Docker dot com and download the specific version for your operating system, which I've already done now, at the root of our project under confidence, I'm gonna right-click and say new files and I'm going to call this Docker dash compose, and you need to name yours the same dot y m l. So Just like XML. But with a y y m l and hit enter. And it does offer some context sensitive help for us in intelligent ultimate in some of the other IEDs do as well. But if you don't have one of those, it doesn't matter. You can write this in a note pad going-to say version. Give this 3.8 because that is the current version. As of writing this course down below there, I'm going to say networks and we're just gonna choose the default network and then for services. We want to have the database service, so db and we're going to have an image of my sequel, colon version 5.7. Now I do know that there are later versions after this. In fact, my sequel eight is out. You may go. Oh, that's a big jump from 5 to 85 is actually the most stable one that's in production, and eight has some naming convention things that actually break with a lot of applications. So for our image, we're going to use my sequel. 57 The Container Name. We're going to just call Conference, underscore security and then for ports. And this is what we're going to export from. Our application to the inside of the container. Will say 33 06 will be exposed to 33 06 UI could map different ports if we wanted to, but this works just fine for what we're doing. And then we will want to have a volumes and for the volumes will say that we want a double quote dot slash dot data slash d b colon slash var slash libel slash my sequel, and this is kind of a standard naming convention for where it's going to store the data at You'll notice that mine turned green and that means that it's been entered the correct way for us. And we'll say environment. We're going to add some environment variables underneath here. We're gonna say my sequel underscore route underscore password. And we're going to just have our password be passed. You could obviously choose something mawr secure. If you want my sequel underscore database and we're going to call this database conference underscore Security. This is everything we need to have Docker inside of our application now have switched over to our terminal. And I have started typing in here the command to start up Docker and run that image that we've just created on All I have to do is type in Docker dash composed space up space Dash d When I hit inner it will go through and fire it up and run our project for us. So my Docker instances actually running now. And if I launch my Docker desktop and look at it, I could see that it has fired up our instance for us and you can see that everything is running. It's got its ports tables. All that stuff is created for us. My application is up and running and ready to go
before we make the last changes to our application to switch it over to J. D. B C. I wanted to show you just a couple of Docker tips that will help you as your running this first. There are some Docker commands that are really simple that will utilize throughout this The Docker composed up dash D which you saw me use a minute ago, is to start up a Docker container and instance the same thing with down effectively shuts it down. P s will show us the currently running processes and the last to inspect and inspect with a grip will let us look at what's currently running inside of our container and help us troubleshoot a few things.
Demo: JDBC Configuration
to configure our application to talk to a database. There's actually three steps that we need to do to start by opening up our pom XML. Let's go down to where we lost edited this, which was below JST L and gives ourselves a little bit of space in between that previous dependency in the next one, and we're going to put two dependencies inside of here. We're going to put the spring boots Starter Data J P. A. Dependency. We're actually not doing anything with J P. A. Yet. It's not really the focus of this course, but there are some transaction libraries that are part of that artifact that we need inside of our code. And then we're going to add the my sequel, my sequel connector, Java dependency. Those both use dependency management from Maven, and so we don't have to specify a specific version in there. And when we say they will automatically download those and add them to the class path of your application, the next thing we need to do is to find a data source, and we do that by going to application properties, and right now ours is blank. We're going to go ahead and add in four lines. I have already copy these, and I'm just gonna paste them in. So you don't have to watch me type them and make typing errors. You see, the four lines we have here are spring dot data source dot u r l. And that's tied to local host Colin 33 06 If you remember when we created the Docker composed file, UI exposed the port 33 06 to 33 06 and we named our database conference Underscore security. We had a username of root in a password of pass and R J D B C driver for my sequel is just calm dot my sequel dot j d b c dot driver. Let's save this. And if you have any red errors here, you need to figure those out before you proceed. If there any things read, it means you haven't got something configured quite right. Next, we want to open up our conference security config. And at the top of this file, I'm going to go ahead and inject a resource I'm gonna type in at Auto Wired and I'm gonna make this private and say data source data source. And save that. And you can see how it's gray that says that there is one configured and since that's configured, it's pulling that from our application dot properties. So that's how I know that those two are actually configured correctly. Then I'm gonna scroll down Thio are configure method that we created before we had all this in memory authentication. I'm actually going to replace that with dot J D B C authentication and we're gonna pass in a data source. And it's that data source that we just injected into our code. Believe it or not, that is everything that you need to do is far-as your application configurations concerned to wire it up to use J. D. B C to read from your database and authenticate and authorize against now for our end. Since it's the first time we've done this, we do have to add a couple of tables into our database and insert a record in there for us to go against. So I'm gonna open up my my sequel workbench and run a couple of statements on there to put some data in there
Demo: MySQL Configuration
Since this is a new scheme, I'm gonna have to create a new connection to it. So opening up my my sequel workbench and Click The Plus Sign and I'm gonna get this connection name just conference and local host thirty three hundred six. It's gonna ask me for the password is UI dio so we'll click. OK, and we have our basic scheme is set up in front of us here. So now I can insert a couple of records into the database. I'm gonna right-click on conference Security and say, set as default schema. And that way I don't have to pretend any of my statements with anything saying Put it in this schema. So we're connected to that database and now have this set of default schema start off by creating a table named Users. It's gonna have a username and a password and and enabled column And the primary key will be username gonna execute this and we can see by the green output at the bottom that it was successful. The next thing I'm going to dio is create the authorities table and I can highlight that one statement and execute IT and you can see that it was successful. Now I'm going to create an index between those two. If I highlight that same thing, I could execute that one statement and now is where it gets tricky. I need to insert a user and a roll inside the table, and I'm gonna grab both of those statements and paste them in here. But I'm going to show you how I got one of those values. You'll notice that we have the values, Brian. And this weird long string that is my password. And that is the encoded version of pass. Let me show you how I got that switching back to the I d. E. If I exit full screen and I go to source main test Java calm Pluralsight conference and open up this conference applications test. I can auto wire of being inside of here because this class is already annotated as a spring boot test. So we wanna auto wire in that being UI created before which waas the password encoder. I'm just gonna call this encoder and say that and then inside of our context loads I can do a real simple system dot out dot print Lynn. There much better ways to go about this, but this will work for what we want to do. Well, say encoder dot and code. And if you remember, we use that string of pass, and we can close off that method and just simply print it out. So we'll save this right-click and run IT say run context loads And when it scrolls off the screen, you'll see IT load up spring. We'll come back to the statement at the very bottom. You see, IT dumped it out there for a second. It was really quick. This string right here is pass encoded using our password encoded. So that's literally that character sequence that we have encoded using our password encoded being that we have defined in our conference security config. If we go to the bottom of our conference security configure, you see the being that we have created here. We're just using that be crypt password encoder to encode that. So if your password is not pass, you've done something else. You don't want to go to that test and put in whatever your password is in there and run that test to get that value out and then go back over to my sequel and inject that value in there because your statements will check encrypted passwords, not clear text passwords. IT never decode them. It only uses them in encoded fashion. Now back over to arm icicle workbench. You can go ahead and paste in whatever your password is here. I've already done that to mine, and you can execute those two statements. And when you're all done with that, you can run a select star from users, which I've already done here, which will show me that I have my user in this database. So if I execute that, I will see that I've got Brian and my password in there like I think I would. And also, before we leave this, let's run a commit statement in here so tight that in their committed, you'll see the commit was successful. If you don't do that, you'll leave your my sequel workbench with these changes working in your work bench. But it won't work inside your application, so don't forget that very important step. You can select users, but if they're not committed, it won't show up outside of this transaction. Let's switch back to our ID
Demo: Configuration Recap
I'm going to restart my server just for good measure, Get a fresh connection. Should have those changes that we just committed to our database and all that in there. When it pulls up our browser, UI should be connected to our database Now now in our browser. If we click add registration, it'll take us to the log in Page UI. Type in Brian and pass Click Log in. It actually is going out to our database and round tripping back through our application using that instead of the in memory model. Let's look at what we had to do to our i d to get that all set up again. Inside of our palm, we had to add the spring boots Starter Data J. P. A. Dependency and the my sequel connector Java dependency in our application properties, we had to add these four lines spring data source, your l username password and our driver class name that connects us up to our database. Under our conference security config UI injected that auto wire data source data source of the top and changed our configuration to-be off dot j D. B c authentication using a dot data source where we passed in that data source. And the other code thing that we had to do was I showed you how to use the password encoder by auto wiring it in and then just doing a system out print. Lynn, where we use that encoder to encode the password that we're using from there, we used our my sequel workbench, too. Update our record with the correct password and had that set in there. Once we did that, we saved everything, restarted our server, and, as you could see, it pulled it back correctly from the database.
all things considered, it's actually quite easy to use J. D B C. To authenticate and authorize your application. We started off this module with the in memory configuration from the previous demo. Then we went through all the steps to set up J D B C. But before we dove into that, UI used Docker to stand up a my sequel instance. And then we switched over our app to utilize the J. D. B C authentication mechanism that we injected that data source in that was pointed to my sequel running on Docker. Then finally, from there, I showed you the trick of using the password encoder that we had to update your clear text password to being encoded that UI stored inside of my sequel.
Authenticating Users Against LDAP
l'd app is one of the most widely used approaches to authenticate a user. L'd app itself can be a fairly complex server to set up, as it usually is quite foreign to people as the structure that is required to use it. We're going to set up a server populated with data and test our configuration against IT. Let's start with configuring our app to have the dependencies. IT needs to start up that new server.
there are three dependencies that we need to add to our app in order to use l'd app. It's easy to miss that. These are from different group I. D s. So pay extra close attention to that. The first dependency is thes spring. L'd app core artifact from the or Google Spring Framework l'd app group I d. This dependency is used for all l'd app libraries and interactions for spring. The next dependency is thes spring security l'd app artifact It is from the Orig Spring Framework Security Group. It is actually from this different group i d because it contains just the interfaces to deal with l'd app and security related protocols. The last dependency is an artifact from unbound i d for the eld app SDK This is actually the elder app server we're going to use for testing our app out. It will create an in memory l'd app instance for us to test against Let's add these into our app now
Demo: Adding Maven Dependencies
I've gone ahead and shut down all of the's servers and everything else I had running just to have a clean starting point for this module. Want to start off by opening up our palm dot xml? I'm gonna go to the bottom of the dependency section, and it doesn't really matter. But before the test artifact, I'm going to give myself some white space here. I'm going to start adding those three dependencies that we need inside of here. So the first one is the org's spring framework dot l'd app group I d with the spring l'd app core artifact i. D. This is for our spring application to do any type of interaction with l'd app, and it's actually the libraries that these spring security artifact that we're going to copy in here in a minute will require to do those interactions so thes air to our kind of dependent upon one another. We're going to specify both of them. They could be pulled into the transit dependency, but by specifying them were sure of which libraries were going to be importing. The next one is the or got spring framework dot Security group ID with e spring security l'd app, artifact id And this is just what does the binds and searches and things that were expecting underneath the hood in l'd app for our spring security application to authenticate our user against IT. And then we'll finally have one more here and that is the unbound. I'd artifact for the elders app SDK So it's a group idea of com dot unbound i d and an artifact of unbound i d dash l'd app SDK a little bit of a weird name, but it's actually the preferred l'd app server If you go researching the spring security documentation about what? To test your spring security, l'd app against Let's look at the next configuration pieces that we need inside of our app.
the change will need to make to our conference. Security config dot java file is very similar to what we did for J. D B C authentication. We're going to swap that out with l'd app authentication and we have a user d n patterns for the user idea we're going to be searching for and the group or organizational unit that it will be under, which is people and our group search base. And then that will build up our u R l. And you can see we just haven't hear our local host 83 89. This string, I might point out, could be submitted in through age. Andy, I look up through a database. Look up. There's a bunch of ways that this could be in here, so don't think this has to be hard coded in there, but to make this example simpler, we've gone ahead and just pasted this in here and then notice we're going to use the same password encoder down below that we used for our database configuration. Let's switch our code to this now and get it updated to using these configuration parameters that we have listed here
Demo: Security Config for LDAP
I wanna go ahead and open up our source Main Java com Pluralsight conference package and open up our conference security config class. I'm gonna make this full screen while we work on this for a little bit. Let's go down to our J D. B C authentication data source, and I'm gonna comment that out. Now, below that, we're going to start putting in our l'd app configuration. So we're gonna say off dot l'd app authentication. And underneath here I could give it the new line and use that builder pattern approach that we did before So I could say dot user D N patterns. And then here, we're going to put in the contextual string of you I d. And that is equal to a search parameter base of zero. So this is the first character we're gonna pass in for our search. Our first parameter. We're gonna use an organizational unit equal to people. And this will make more sense when we set up our server here in a little bit, we're going to specify all these things. They're going to do a group search base and for the group search base, we're going to do an organizational unit equal to groups. Now we're going to build our context source and then from that context source going to pass in the URL. And as I mentioned in the previous slides, that this could be passed in is a variable. But to not make this example any more complex than it needs to be, I'm just going to put this string in here. That's a standard practice of using a variable to pass this, and we could just IT jet inject that resource. And if you've gone through the spring fundamentals, course you saw how we did that inside of there, you could also look it up out of the database. There's a lot of different ways that you could go about doing that. So we'll do Pluralsight and we'll have a D. C. Or directory context equal to com. Now. Once we have this, we can now start building upon this with our password compare features. We're gonna do dot password compare and do a dot password encoder, and we're going to call the password encoder that we have to find down below. And last but not least, we're going to pass in the password attribute and that is user password. At the end of this line, Put a semi colon because we're done using that builder pattern and I'm gonna save that. Make sure you save your palm dot XML as well so that it will do those automatic imports for maven. Now, your application is all configured to go against the elder app server that we need to set up.
to start up the test server that we created the dependency for and referenced in our Conference Security convict file. We need toe add three properties to our application dot properties file. The first one is thes spring l'd app embedded l def. Which we're going to add to our class path with the name of test dash server dot ldf. This is not how you would typically populate a production server, but we have to have a starting point to test something inside of our application. So we're going to add this test dash server dot ldf file inside of our code and that will populate our server with some default users that we can run against the next one is thesis aim properties on a pending dot based to the end of that for our d n, which will contain our directory context or our structure which will be Pluralsight and a context of calm. And then, lastly, our port, which is 83 89. So let's add these three properties in there, and then we'll go ahead and start creating our test server dot ldf
Demo: Creating the Embedded Server
picking up where we left off and our last demo. I'm gonna go ahead and exit full screen and open up. Source Main resource is application dot properties. We want to go ahead and here and add a couple of configuration elements UI going-to spring dot l'd app dot embedded. And that's what's going to signify IT. Starting up the embedded server for us and we're going to have this specified on our class path. And the name of that is going to be test dash server dot ldf. Now, the next thing that we want to add inside of here is spring dot l'd app dot embedded, and we're gonna do the base d n and that is going to be D C equal to Pluralsight and a comma for a D. C equal to calm and you'll see where these air specified in that ldf file here in just a second. And then the last one that we need is spring dot l'd app dot embedded and we want to choose the port. We're gonna make that equal to 83 89 now. This configuration here will start up our embedded server for us point to this ldf file load that context and begin are searching on this d n for any of the users that we go through inside of our application until it to search for.
the LDF file can be quite confusing to people at a first glance and honestly ah, lot of l'd app can be a bit foreign to most people that have ever worked with it before this fall here designates an entry in sight of it as a person, and you can see it's very similar to the J. D B C configuration that we had before us far-as structure of a user i D and a password. But there's also structure defining this user that's contained inside of here, so you can see we have a no you or what's referred to as an organizational unit, a D. C or a directory context. There's organizational information inside of here. You can see that there is our surname and that type of information also defined inside of here. There is also the user password field, and if you remember back to our Conference Security config file that we had, there was a password attributes, which we defined as user password. And if you'll remember through the B crypt demonstration that we did earlier, this is an encrypted password that is defined here. So let's switch over to R I D. E. And start entering this information in and the rest of the structure that we need to create this server
Demo: Creating the LDIF File
alright to create our test server LDF file. I'm gonna be real honest with you. You'll probably just want to download it out of the exercise files or fork the source code that I have at get hub and grab it from there and add to your project hand typing this all in here is going to be very monotonous and very air prone. So to do this, I am going to go to our source. Main resource is directory again right-click and add a new file and the file name is going to be test dash server dot l'd if and I am going to do exactly what I just said and paste all of this in here, but I'm gonna walk through this with you. First off, we have our context of Pluralsight com. You can see that we have next to find our users groups and it's tied to that structure. And then we have subgroups down below and then we define people inside of here and finally, halfway down here, you can see that we have created a user. So I'm gonna point out a couple of specific things here. If you want to add your own user or change it to your name and password. You're going to want to go through and search where I have my name inside of here and replace it with yours. So the u I d. Of Brian up here, you would want to change to whatever your name is Bob or whatever else you're doing there. So I'm gonna change that back to Brian, and you can see that it's all over throughout this application. In fact, if I do a search inside of my file here for Brian, you can see that I have six matches inside of here where it is throughout this because I'm part of the managers group and sub managers group and all of that different context. Now, this is a little bit of an overkill for this simple example. I could have not had them join these groups and other things. Except for if we do more complex stuff with this user, they will need to be in those various groups. So as we do some of the role based stuff later in this course, I will need this stuff. So I've gone ahead and set up the server from the get go the right way. If you want to add your password in there, remember that we got that encrypted password by running that unit test that we created earlier that had the system doubt Print lin of our encoder dot n code with your password and clear text typed in there so that you can see what the encoded value looks like so we can do a compare on IT. And that's exactly what's happening is in our conference security config UI Do a password. Compare on that password from that attributes so you can see things tied together. Here we have our password attributes of user password that's under test server l'd if where our user passwords to find. You can also see inside of here that we are going to use that. Compare with the exact password and code er, which is how we can encode are clear text, password and store in that file and compare those two up
Demo: Authenticating Against LDAP
before we start running are examples I wanted to point out. A couple of things currently are conference security. Config is not referencing j d B C anywhere, but our application dot properties is. So we have a data source defined here on these lines where we're still trying to talk to J. D. B C. My sequel ever. Route password. All of that information or driver class name. You could either comment these lines out using a pound sign so we could go through and comment them out. Or you can make sure that your Docker instances up and running. So your Docker instance may have gotten shut down If you re started your machine had to reboot for whatever reason and update. Or you just shut down Docker because it was tying up. Resource is the reason I'm leaving these in here is because in a future module here, we're going to reference our database again when UI customize three years or details objects. So even though our conference security isn't referencing anything right now, our application properties is so now when we run this, we'll go ahead and fire up that server. It will start up our application and it will switch over Thio our browser for us once it's loaded. If you chose that option for it to do it now, when we pull up our application, if we click add registration just like before, it'll take us to this log in page. And when we enter in the correct credentials UI click log in it will go through an authentic APIs against l'd app. So it really actually wasn't that bad. We had to add some dependencies inside of here, go to our conference security and add l'd app authentication inside of here inside of our application properties. We just added three lines for our l'd if are based in and our port. We ran the example of showing our password and how to get that encrypted. And then finally, the most complex part was are ldf file, which is rather large for the simple example. But it's set up for all the things that we want. Thio and we even had our password entered in from running that unit test before. So if you wanna add yours in there, you can change the u I. D. S throughout here to your name or added as a second entry and can then take and put in your own password here instead of my password, which is just passed in this example and run that example.
recapping what we learned in this module we went through and had to add those three dependencies for maven. And it's a little odd because they are from different group ID, so that's something to definitely watch for in your application. UI modified our conference security config to remove the J. D B C section and add the eld app authentication and remember that we also did a password compare inside of their utilizing the password encoder that we already had to find, which is B crypt and be crypt is a great password encoder. Then we added the application dot properties, and it should be noted that the application dot properties is one how it fires up that l'd app server for us. And to that UI referenced that test dash server. L'd if not something that you would want to do in a production database. But that's how we can easily set up our application and run it how it is now. Then we created that test server dot ldf, which enabled us to have that user in place, which we could run against when it's all said and done. It actually executed quite well and is a simple way to go through and have a secure storage for users for authenticating against which held app is great for that. Now let's go ahead and see how we can customize our user details object to take advantage of some of these other fields that we have stored out there.
Customizing the Spring Security Object
customize ing. The spring security object is where I believe most people start to get frustrated with security and rightfully so. This is where they're trying to make it work with their project, and it would seem that you could add things or that they would just naturally be there. In reality, some things aren't in there by default because they are a risk. But other items should be more readily available. Let's look at what we're going to add to our user object and how we're going to do that now.
Authentication - Authorization
the previous module was all about l'd app UI used l'd app for both authentication and authorization and the module. Before that, we did the same thing with a my sequel database. Instance. We used the database for both authentication and authorization. Well, in almost all the production implementations of spring security that I've done, we've had to authenticate from one and authorized from the other. The combination of l'd app plus a database is one of the wider used approaches that I've experienced when creating a spring security based application. You may recall, in one of the previous L'd at Demos, I had left my configurations set up for the database. And this is the reasoning as to why this is also where we begin customizing our spring security object. Let's look at that configuration now.
Custom User Details
the beginning of the steps to customize our spring security object is to build our own user details object. UI actually chose to do this theme or realistic approach and a scenario very common to which you may run into in your own app. And that is to extend the user object, which is also the default object from spring security. You can see here in this snippet of code that we had to fully qualify the package to the user class. The reason for this is that we already have a class inside of our app named User, so we had to specify which one we were extending. Also, you can see in this code that we're going to add a property named Nickname. A nickname is a common attribute in an app, because people might not always use their given name as to what they prefer to be called. Let's create this object in our code now
Demo: Creating the Custom User Details Object
I've shut down my server and closed all my files so we could start from a fresh workspace while adding this new conference user details object that we're about to create. I'm gonna go down into source Main Java com Pluralsight conference and underneath our model directory, we'll see we have registration and user right-click on model and say, New Java class. We'll call this conference user details and it's a class, so we'll just hit. Enter on that now inside of here. Make sure your package structure looks the same as mine. Say that this extends and we're going to fully qualify. Organ dot spring framework dot security dot core dot user details and inside of here we want the user object. Now this is going to give us an air by default because it wants a specific constructor that we don't have yet. So if we hover over our red line and click the down there says to create a constructor matching super. So we have two choices. Here we have the simpler one, which takes thestreet ing and the string for password and a collection of authorities. And then there is a larger, more complex constructor for all of the attributes I'm gonna choose the simpler one, which is the first-one listed here. Click OK, And then I wanna add a member variable of private And this is just a string and we'll call this nickname. Say that now. One last thing we want to do here is generate our getters and setters and we-can. Just use the keystroke for command end or option n depending on which machine you're running on. OS a getter and setter And we're gonna choose Nickname String and we'll click OK, and there's are customize user details Object. So it's under the calm Pluralsight Conference model package we've extended and fully qualified our path to thes spring security user details, user object. We've added our basic super constructor in there and then we've added our private variable for nickname
the most complex part of customizing the spring security object when dealing with l'd app is the context mapper. The context mapper is required to take the user that has been authenticated and build the object that gets returned. We're going to import the data source we have defined for our database. Pull the username of the authenticated user. Out of that l'd app search, then use the context to see what that username is inside the variable CTX and finally query the database to return the results we want. In this case, the extra fields were storing, such as the nickname. Before we could do that, though, let's alter our database that we used before to include that column for nickname, and then we could build our context mapper.
Demo: Adding Columns to Our Database
I've opened up tar my sequel workbench that we used earlier in the previous module. I'm gonna right-click on users and say, altar table, This will bring up a table editor that I can just click to edit here. And it will give me a column, which I'm going to call nickname. And I'm gonna change that to be a var char of 50. And by default, we don't care if this is no, that's all I actually have to do to edit this users table Click apply. You actually see the sequel that it's going to run to do this. So this is just a nice, convenient helper through the you I to do this. This is the actual sequel that gets ran behind the scenes. So now our table has that column added to it. Go back to our query editor that we had earlier, and I've already typed in an update statement in here, and I could say update users set nickname equal to big be kind of a nickname that some people call me where username equals Brian. So I'm going Thio, highlight that line and run IT here and make sure you choose the option that says to run the one that's underneath the current cursor and then I'm going to execute that commit statement again. So now we should have a select statement for users. UI execute that you'll see that it has updated that user Brian, and it still has our password there, even though we're going to be authenticating against l'd app. Now, it says it's still enabled, and it has updated the nickname to store that in there as well. We have our database set up. Let's go build that custom context mapper.
Demo: Creating the LDAP Context Mapper
picking up where we left off before. Let's create our conference user details, context mapper. We're gonna do this in a new package. So I'm gonna right-click on com Pluralsight conference and say New Java class, then inside of here. We're gonna say service dot conference user details context mapper. Wanna make sure we get that camel case in er and this is going to implement the user details context mapper interface will say implements the user details context mapper. And this is gonna give us an error because we need to implement some methods, so we'll click. Okay. And really, the only one that it really cares about is this first-one The second-one is if we're going the other direction and we don't care about that for the code that we're writing. So we're going to be working in this one here now to do this, we need to do a handful of things First, we're going to start with auto wiring in a data source. So we'll say at Auto Wired, and we'll put in hair private. Yeah, data source. I want to choose the Java extra sequel package and we'll save this. The next thing that we want to do is create a sequel statement for retrieving our username out of the database. And we're going to do that by saying Private static Final String and we'll call this load user by username query. You could call this sequel. It doesn't have to be named this or whatever else you want, and we'll have a select username. We're gonna name all the columns out, password enabled and the column that we just added nickname from users where username is equal to question Mark and we'll put a semicolon on the end of their Now let's make this break over to where you can see it easier all in one line. We'll save that there. This is the statement we're going to use in a J. D. B C template that we're gonna create here in just a second to load those users from the database. So inside of this map user from context method, we're going thio create a J D B C template, and we'll call this just J. D. B. C template equals new J. D. B. C. Template will pass in the data source. You could if you wanted to create the J. D. B C template as a being and share that Being inside of here, that is a great approaches. Well, either works well now because we're going to create an anonymous in her class in here. We're going to create this instance as final. So we'll say final conference user details and we'll just call this the user details object. We'll see that is equal to a new conference. Use your details object, and it's going to want all those parameters that we just created passed in. Now, this is going to seem a little bit odd to start with, and I'll walk you through what we're doing here. We're going to put in here this directory context, operations object dot get string attribute, and that string attributes is you I d. And that's the user. I d and you probably don't remember it, but that's what we created inside of our test server LDF file. Now, the next one we wanna put in here is the password, and I am actually going to put the string fake inside of here because we don't wanna be passing around the password inside of our application for other people to grab and be able to hack our session with. So once they're authenticated, we have a token. We don't need to pass that password around anymore, so I'm actually going to just put that place holder of fake in there. If we needed it later, we could come back through here and edit it, but not going to for now. And then the last thing I'm gonna put in here is an empty granted authorities list because we're not using it right now. We're going to later. So we'll say collections dot empty list. And now we have our conference user details object this variable store to user details and its final so we can access it in this next piece. We're going to use that J D. B C template that we just created, and I'm actually going to paste in this line because it's a little air prone for type errors inside of here. We have our JBC template, and we're going to do a query for object and passing that load user by username query string that we just created up above. We're going to do an anonymous inter class using the new Rome app er conference, user details and that's going to require us to override this'll map Roh method that we have here and you can see inside of that. It executes that query and we grabbed that nickname column out of there and assign it to our user details object and return that. Then inside of here, we can finally return Our user details object back to the u I so a little bit of a Harry piece here. But we have this all define. We want to do one last thing inside of here, and that is defined this as a service. We haven't done that before in this class. So when I say at service, this being we're object will now be registered inside of spring as a service object, we can go ahead and grab this and use it anywhere inside of spring as a fully registered bean. Now, ah, lot of times you'll also see at transactional here. We don't need to do this because one we're just doing reads and everything is contained in the side. The scope of this one method, we're almost ready to use our newly created mapper. We just need to go ahead and configure our conference security object to utilize this new mapper that we've created
now that we have created our mapper, we need to configure our spring security config to inject this new service. UI defined arm app er as a service and that service, since it's registered as a spring bean, can now be auto wired. How we have defined here. Lastly, in our elder app configuration, we need to add the context mapper to our configuration so that when it builds our user, we can intercept and make the appropriate calls. Let's add this last little bit of configuration and then we can run our demo.
Demo: Authenticate Against LDAP Authorize Against the Database
Let's open up our conference security config. And at the top of this class, let's auto wire in another variables will say at Auto Wired and we'll make it private conference, user details, context mapper and for the instance name. I'm gonna call IT CTX mapper. Just so we don't have a crazy long instance name, we'll copy that. Now we need to go down to our configure method where we configure IT are l'd app authentication and after that user password. And before that semicolon. We want to keep that semicolon on the end, gonna add another dot and statement. And from there we want to say dot user details, context, mapper and paste in that context mapper that we just created. That's all we had to do to inject that being inside of this class and then configure it and use it on our elder app authentication to go ahead and authenticate against l'd app but authorized and pull those other user details back from our database. Now we could go ahead and start up our server, and once it fires up, it'll pull up our browser we-can run our application and it will pull back that user from both l'd app and the database. Once our app pulls up we-can click on add registration, type in Brian and pass Log in and it's still authenticating us exactly how we would expect us to the next module. We're going to customize these pages. So you we-can now utilize those extra columns that we've added into our database and pull back out our nickname or other things that you may be added in there as well. You get to see this visually take hold inside of Are you I?
this module really encompassed what I feel like a lot of people run into problems with when adding security into their application, and that is authenticating against one resource and authorizing against another. And so we covered authentication and authorization from l'd app and my sequel or a sequel database doesn't matter if it's my sequel or not, and UI customize that user details object. We just added a nickname, but you could add whatever fills you want to be pulled out and stored in that object and passed around is part of your spring security session. We did that by creating a custom context mapper that intercepted that l'd app call to then authorized against our database. And finally we added a couple of configuration items in there and that we created that context mapper as a service, and Otto wire that into our conference security config, thus injecting that resource and making it available to us inside of our app. Let's look at how we now customize our log in page to utilize some of these features that we've now implemented
Creating a Custom Login Page for Spring Security
we have already created a log in page. IT made things easier for integrating into our existing app. But we haven't wired up the air handling nor some of the other services yet in this module. We're going to do just that. We're going to wire up some of those back end features and displaying air messages from our log in process on the U I. We're also going to implement Remember me services that will not require us to log in with each visit as well as log out functionality. Let's start off with getting those air messages back to Are you I?
Demo: Error Message
Let's first demonstrate the problem that we're going to solve with this particular demo. If we fire up our application, this is just where we left it off after the previous module. I've just closed down all of the open files. We're going to see that when we have an air message, it will not display that even though we are capturing IT and returning it to the user, it won't display that air message on the u. I. And so once our applications launched UI, go ahead and click. Add registration. It goes to a log in page. If I put in a bogus username and password and click log in, we have a log in air. In fact, you can see up in the address bar. IT changed our parameter to log in question. Mark error added that air parameter. On the end, we should be displaying something. Well, we put all the code in there to do it, but we haven't quite configured IT yet, So let's look at what is going to take for us to do that and some minor changes inside of our application that will make it a little bit more user friendly.
from our security configuration that we had before. We have already defined the failure. U R l and we're going to verify that you have this in your project as well. And that is simply a forward slash log in question mark. Error equals true. We need to send that air messages the u R l parameter back to the servicing page. This isn't the Onley way to handle errors, but it's definitely the most common. As you can see here in our configuration section, we just add two pieces to our security configuration. First is the failure. You are l where you can see that UI upended the air true parameter on the end and then the permit all which is just saying that we want toe let everyone be able to see it. Let's add this to our code now
Demo: Configure Login Error Handling
all of the configuration on the Java side takes place in one file, and that's our security config. So we're gonna go down to source Main Java com Pluralsight conference and open up our conference security config. Then inside of here, I'm going to start breaking some things up so that you can see them a little bit easier. Go down to this dot and and give a little white space between those sections because we're going to start adding more and more sections throughout this module. But for now, when your dad two things Thio here, I'm going to go to our log in processing you URL line and go to the end of that and add a new line below that and type in dot failure. You are URL and I wanna put in there a log in question mark. Error equals true. Now notice there's not a semi colon on the end of that. I can't stress that enough that this is using the builder pattern approach. Then I'm going to add one more line here and say dot permit all And now this and section contains all the configuration that we need inside of our app to-be handle a u R L failure that sends it back to the processing page. Now you don't have to do it this way. There's other ways, but we're going to redirect back to our log in page with a parameter on the U. R L saying error equals true. And then we specify permit all because we wanna be able to allow everybody who does this to see this. If not, it would require them to be logged in to that failure you URL.
we put the logic into Are you I to display airs already, but we haven't added any CSS to IT yet. We've actually already defined a simple CSS class in the top of our app and this could simply be applied to our div. As we have here in this example, you can also define them in their own CSS file. But for the sake of this example, let's just add that class to the code that we have already defined in this Div.
Demo: Login Error Messages
going to go ahead and exit full screen and actually going to stop my server as well. Just so it's not trying to redeploy as I'm making changes here. I want to navigate down to my source main web app, web by an f jsp and open up our log in page inside of here. We have the Div for are invalid username and password, and that will display now that we have that failure. You are l set up correctly, but let's add a CSS class on here that is just a class equal to error and save that. And just so you can see where that's coming from, it's from the top of our head section in this JSP page. So we have that air block right here online 19 in my code where you can see it's just defining a red color block that's going to surround this. So now down below in our log in page, we can go ahead and specify that we have this air message tied to this, which is just an invalid username of password. Like I mentioned before, you can handle errors differently. You could have different parameters that you pass back. There's access to that inside of the spring object to redirect back to a different parameter so you could have more specific errors set up here now. One word of caution is that it's generally good advice to send back Mawr generic errors that doesn't expose any of your security model. So just a just a word of caution there. That's why we've left IT somewhat vague just saying I invalid username and password. So let's start this up. And now that our app has launched we-can, click on Add Registration, let's put in that bogus username and password, and it now redirects us back and displays that red air message of invalid username and password. Ah, little later in this module will show you another method to displaying that. But for now, all of your air messages are being sent back to the U I. And we've even highlighted them in red
remember me. Services have become essential for a good user experience. You may already be getting tired of logging in as many times as we have throughout this course. Remember me services apply a cookie in the app to verify that we are who we say we are. And as long as the user allows cookies, your-app doesn't require you to continually log in going to have to add a few pieces to do this, though we're going to have to modify, Are you? I change our security configuration and add a table to our database that it will go back and reference to see that that cookie is in fact still valid. From a log in perspective, let's start by looking at the front end.
Remember Me Frontend
the front end component of Remember me services is actually quite simple. You may recognize thes fields already because this was thief form that we used on our log in page. We had our username and password. We just need to add a third component inside of that form, and that is thes check box. We're going to select to choose to have our app remember who we are. Notice that there is a name for this that is Remember, dash me that is specific to spring security. And if you change that, the service will not work, you can override IT. But for our example, we're going to leave it to the default. Just keep in mind that if you change yours, you're going to need to change that configuration inside of your security config. Let's add this to our application now.
Demo: Remember Me UI
for the U I portion of the remember me services. UI wanna open up our log in dot Jsp page and I have mine open from our previous example. Want to scroll down to our form where we perform our log in and underneath our password input? Want to give ourselves some white space and add in another div label? Remember me Input type check box name equals Remember Dash me label Div So this check box it's really simple. It's just basic html This check box that we're adding in here is just the box that we will select on the you I to enable these Remember me services. I've said it multiple times, but I'm afraid you're going to miss IT. Yours does have to be named the same, remember? Dash me. If not, it will not work. When we add the back end configuration, let's start our server up and see what this does on the u I. Now that our app is up we-can click on add registration and we'll see our check box down here Currently it won't do anything. It will submit it to the back end. But we haven't configured that security config to accept those yet. Let's look at that configuration now
Remember Me Configuration
the configuration in our security config is actually in two parts and you can see that we've got these separated out with a comment in between to show you the break we need to add in our configure section. The remember me method call. Using that builder pattern will give it a key. And I just put in their super secret key. You can actually put one in there that is unique to your organization and the call to token repository where UI referenced this being We're going to define down below the being that we're going to create returns, an instance of persistent token repository which inside that method, uses a J D B C token repository in pull where we pass in our data source and this will actually be used to communicate with our database, which will actually be one of the next steps that we configure to enable. Remember me services. Let's add these two pieces to our security configuration, and then we can look at the changes we need for the database. IT
Demo: Remember Me Security Config
inside of our conference security config. In the previous demos, I had you space out from your aunt Man. Cher's any request authenticated and the next section which starts off with the dot and method builder call to give yourself some logical space and breaking those up. We're gonna go ahead and do that again. I'm gonna go in between that last line in that semi colon and give myself a little extra space here and create another dot and using the builder and another line below that and inside of here, I want to say dot Remember me? And this will start building out the remember me services going to do another line below that. And this is where we'll pass in that key. And our key is going to be, for my example, the super secret key. You can change that to something unique to your organization. We have one more line inside of here, and this one is UI. Type it in. It is going to break because we're going to have to define a method down below. So we're gonna say token repository, and that is going to call the method token repository. And this doesn't exist yet We're going to to find this down below inside of our code, so it will give us an air right now. I'm just gonna go below that method and at a new being. So we're gonna say at being and this is a public being that is going to return an instance of a persistent token repository. And for the signature, we're going to match that name that we have up above their of token repository. And it takes no arguments in its method signature. And this is an instance of a J. D. B C token repository in poll. And we could just call this token. This will be a new J D B C token repository ample. And on our token, we want Thio set the data source. We have already defined a data source inside of this class, so we'll say data source and then return that instance of our token. So we'll say it's really not the token itself. It's the implementation of that class. And that class implements the persistent token repository interface. So now we have defined our token repository and we've configured our remember me services. But there's one last step we need to add a database table that this J D B C token repository in pull talks to on the back end and then we'll be able to run our demo.
Remember Me SQL
The last piece that we need to implement is adding a table to the database that will store the reference to the cookie from the user's local machine to verify against our server to make sure that they're still logged in. I should point out that too, if we want to invalidate anybody logged in UI congest delete their entry in this table and it will force them to log in the next time they visit, regardless of whether or not they're Cookie has expired. We're just gonna go ahead and add this table using the my sequel. You I and then we'll be all configured to run the rest of our demo.
Demo: Performing Remember Me Example
to add that table into our database. I've just opened up the my sequel. You I and I'm going to paste this in here and I've just got this sequel of Create Table Persistent Underscore Loggins username var char 50 Not null Siri's Var Char 64 Primary key token var char 64 Not null and the last year's time stamp, Not Noah's well. And then we create a foreign key to our username, which references three users table and the username column inside of that. So if we highlight this and then execute the sequel underneath the cursor, it will create that table. I'm going to scroll down and highlight our comm IT and then execute that as well. And so we've now created that table and committed that to our query. Let's go back to our application now, and we're ready to run our application. So I'm gonna exit full screen and I'm actually gonna restart my server. And I want to do this because we have made changes to the database. We've made changes to our Java configuration, so it's a good idea for us to get a full deployment out of it. And now, when we click Add registration. It will take us to our log in page where we can put in here, Brian and the password of past And I can click. Remember me when I click Log in, it will go out and create an entry in that table and a cookie on my local box. So I'm logged in. Now I can switch back over to our my sequel. You I and I'm gonna create a little select statement inside of here and just say, select star from now, just copy that persistent Loggins so that we don't have a spelling air here. And if I highlight that sequel statement and execute that, you'll see that we now have a record created in that persistent Loggins table for Brian. And it has our Siris in token as well as theory, last year's date so we can set an expiry on that if we want, or if we just close our application and open it back up, that cookie will still be there, and it won't require us to log in again. So we now have our remember me services configured and working, and you can see that records stored in our database to do just that
if you will notice. Right now, we are logged in and unfortunately, you are stuck in a loop. If you wanted to log into a different account, the way we could break this loop is toe log out. Logging out will invalidate our session and once configured, also delete the cookie associated with the log in as well.
log out configuration is very similar to the remember me configuration in our conference security configuration file. We start off by defining the log out functionality UI then have a log out successful you URL. And in this instance we are returning back to the log in page and adding a parameter of log out equal to true so that we can display a successful message. From here. We will invalidate our session and then delete the cookie associated with the log in and the remember me services as well. Lastly, we want to allow everyone to be able to log out. So we add a permit all configuration to the end of that log out configuration.
Demo: Logout Configuration
it doesn't matter if we implement this functionality before or after our log in and remember me, it will all get built the same way I'm going to go to the end of our configuration. But before that closing, semicolon gonna move that down a couple of lines and I'm going to start typing in here and say dot And from here we can start adding on all of our functionality for the log out. So we'll say, log out. And then we want to do the log out successful URL. And in our instance, we want to send them back to the log in page and we want to add a parameter of log out equal to true. And then on the next line, we're actually going to do a dot log out request match, er, and that will enable us to do a get instead of a post for our log out function. And I'll show you on the u I what I'm talking about here in the next demo. But for this instance, it will make it. Where are you? I Configuration is simpler, and it's only one more line on the back end from here. We can say that we want thio dot invalidate http session equal to true. Then we want to delete the cookies, and this is all caps will say J session ID and that is case sensitive. And then last but not least, we're going to throw on the end there. A permit? All now, before I move on to the next step, I want to show you one other line of code that we are not going to use because we're using that log out. Request match. Er, we do not use this line, which is three ila gout. You're l You may look at some other examples that air using dot log out your l on this would be some performed log in, log out functionality, whatever. We're not using that because we want to use a get. So if you see examples with that and you're wondering what the difference is we have bought that did not use that because we're going to do the log out request match. Er, let's look at what the U I aspect of this same call is
to display that we have successfully logged out. It's almost exactly how we also displayed errors. We had a div in there, but I opted to show you a different example using the Twitter bootstrap CSS. So I wrapped R div with a see if statement and put our div inside of that and then used our alert, alert dash success message from Twitter Bootstrap. So as UI display this, you'll see a lot cleaner message. We do need to add one other anchor tag inside of our app, but we'll do both of those at the same time in Are you I?
alright To start with the modifications to Are you I Let's open up our log in dot jsp page and you'll see we have that div class air of above. We're not showing anything unless that air exists there. Well, toe, try something different with are you? I we're gonna go ahead and throw in another div above here, and I've wrapped that with the see if, rather than putting the CF inside of here because it is visible by default. So I've said cf test not empty. Parham log out So that u r l handler that UI configured in the previous demo for the conference security config UI rewrote that you were able to add a parameter of log out equal. True, on the end of it, this now is looking to see if that parameter exist and if it does exist, then we're going to display this div class alert, alert, dash success and say that log out was successful. But the one thing missing is we don't have a way for us to call this u r l just yet. So let's open up our index dot jsp page and we want to come over to this guy and inside of here. We currently don't have the sea tag library in here, So I'm gonna go up to the top of our log in page and actually, just copy it just to make IT easier and not have to type all of that end. So we'll grab that core tag library out of log in and go to the top of the jsp page and paste that in there at the very top. We'll save that. And now we have in sight of here this knave header of get started gonna add an anchor tag below that that is a C out or a your l builder to call the perform log out and using that see out tag just formats are your l the correct way with our application context ahead of it? And so it just basically builds are your el correctly for us and displays a log out button at the top of our page for us. Let's exit full screen here, and we'll go ahead and restart our server just to make sure that all of our changes their up to date. Okay, now, once we're in our application we-can log in I'll click that ad registration button, click and Brian and pass for our username of password. And now we have our log out link at the top of our page. If I click log out, it will redirect us back to the log in page and say that our log out was successful. So this is our Twitter bootstrap success message. It looks a little nicer and a little cleaner than the read text that we had there. You can go ahead and change that in your own application. If you want to use the alert for failure and browse thesis y-excess that comes with Twitter, Bootstrap and see. There's all sorts of different boxes. So if you want to change your other app over to match this green bar, you're more than welcome to. But we've implemented the log out, and all we had to dio was go through our code and add a log out section. You can see the log in question mark Log out equals true. Now you understand that that log out request match er and path request match er is so that we could perform a get normally it looks for a post so we would have had to set up a form and post that in here by implementing that request match where they get it bypassed that we deleted our session and our cookies and permitted all to access IT. Then for our log in. We just added that nice Twitter bootstrap dialogue that pops up at the top of our page to display success, and we added a simple anchor tag to perform the actual log out. Pretty simple. To actually add that functionality inside of your-app and have a delete the cookies have IT delete the session that's currently logged in, and all we had to do is add a little bit of configuration and an anchor tag.
alright. In this module we learned how to display air messages a little bit cleaner in Are you I We had most of the functionality in there, but we weren't fully utilizing IT. UI then added. Remember me services, which are a nice benefit. Most standard you guys now have this where it creates a cookie on your local machine and then on the back end stores a reference to that token in our database. So we added the database tables and tie that all together and then you almost immediately need to implement the log out functionality because once that cookies created every time you re visit that page, IT will try and log you in automatically. And if you want to test something different or change anything, you need to be able to break that cycle. As part of that, we implemented the ant path matters so that we could go ahead and implement a get instead of a post for that log out functionality, which is by default, requiring a form to be built. And then we also looked at utilizing bootstrap messages. We did a successful log out bootstrap message, and if you want to go ahead and change your alert messages on a invalid username of password to utilize that bootstrap message. It's a little bit cleaner. You I and we already have all the pieces built inside of our application to do that. Next, we're gonna go ahead and implement a registration or an account creation page and do that programmatically inside of the app.
Creating a Custom Registration Process for Spring Security
creating a process for people to register within your application, while not requiring an admin on the back end can be a fairly complex process in this module. We're going to build out the registration process and all the moving parts that it requires to do this. We're going to outline the process and then walked through the flow of how registration occurs.
to understand the end end solution that we're going to build. Let's actually see the demo first of what we're going to build in its entirety. We're going to walk through gathering registration information, submitting the request, sending the email, confirming the account and finally logging in with our new account you can see on our index page I've added a create account link at the top, which will take a username, first name, last name, password and a confirmed password, as well as an email address. Now I have created for me a sample just test account on Gmail that I can send the stuff through. You'll want to use your own or create one like I have for this. When I click submit, it will go through a round trip to the server, and it's created the account. And if I go over to our test email address that I've set up, you see we've already received our registration confirmation. When I click on it, it will take me back in the app and tell me my account has been confirmed. Now, if I pull up a new page and go into our conference app here, it will allow me to log in with that new account that we've created. So if I click, add registration and put in the username and the password that we created, it'll log me in. And in fact, it's going to bring up our password manager and see if we want to save that for our app. So you can see we've gone through all the pieces, had the correct username email address, password and walked through that entire round tripping process of creating the account, storing it in the database. Having that send a confirmation email that we click on, have the account confirmed and then be able to log into our app. Let's start adding that functionality to our application. Now we're going to start with the U I. Where we gather that account information.
this module has a lot of complex moving pieces. And honestly, that is just sometimes the case with security to make this easier, though, we're going to switch back toe having authentication and authorization done through just the database so that we don't have another moving part. What we're going to do, though woodwork just-as good with l'd app for authentication and the database for authorization. It just makes it easier to not have to also add in the process of binding a user to the eld app tree. Switching this back is a simple is opening up our conference security config and commenting out that l'd app authentication that we had put in. And I'm just going to use a block comment for that. And we're going to uncommon the J. D. B C authentication that we had left in her earlier now to verify that we're actually using the same password encoder. I'm also going to go ahead and add that on the end of this line as well. So now we have the same password encoder using be crypt that we had before down there. So we've just switched from off dot l'd app authentication to off dot j D. B C. Authentication supplied the data source and the same password encoder that we have to find just down below here, which is a B crypt password encoder.
for this module we're going to use to email accounts. I have set up to Gmail accounts to demonstrate this process. For this course, you can use your own personal account, use something you might have at your work or set up two accounts, as I have here is, Well, let's look at those accounts that I have created and show you a configuration that you'll probably need to make on your own account if you choose to use that.
Demo: Email Configuration
at the demo at the beginning of this module already showed you a email account that I had received the registration confirmation email to and clicked on that. What I didn't show you is that I also have another server email set up in IT doesn't make any difference. You could actually use the same email. In fact, for one of the demos that I did, I had used the same email account that I was sending the application messages from two also receive an email that I could click the registration confirmation in. Typically, that obviously wouldn't be the same situation. But what I did want to show you is that if you create Gmail accounts and I'm not going to show you how in this video to create Gmail accounts, that's pretty simple. And you can figure that out without me having you walk through the steps. But if you do use Gmail accounts, you do need to make sure that you have this less secure app access turned on to allow IT. So right now, this is shut off and this is what yours will look like by default. To be real honest with you, this was very hard for me to find this setting. I actually had to get an air message inside my application and click on that air message to retrieve this. So if you look at this u R L my account dot google dot com, it even looks like it's a fake u R l like they're trying to garner your information. They're not the slash u stands for user. I'm assuming and slash five is the fifth Gmail account I have logged into on this box. So if we look at the u. R L s, I have here, I have a male slash u slash four that is the fourth account on this machine and slash five is the fifth account on this machine. I had to go in to the server account and turn on the option to allow less secure APS. If you don't do this and you are using Gmail, it will go ahead and block your messages because it thinks somebody's trying to spoof and account through your SMTP server. You'll notice immediately when I switch this on. Also, I got an email saying that I have allowed less secure APS for this email address so if you use Gmail to go ahead and set up some sample accounts on this and it's very easy to do, and I recommend it, you just need the username and password that you've created this account with to configure that SMTP you will need to go to this u R l and allow less secure access and just make sure it's the same mural that you've you're logged into. The correct one is I hover over here. You can see Pluralsight Brian Server as the email address that I have. Make sure you're in that correct app and click to allow less secure app apps.
The first part of the registration process is to gather the account information. We're going to copy one of our other forms and create a new page that will capture all of the account data and submit it back to our controller. As you can see here, we have thes standard information username, first name, last name, email, password and a confirmed password to get started. Let's create that Jsp page, and then we can work on the controller next.
Demo: Create Account UI
to create our account dot jsp page. Let's start by opening up our log in page and we're going to copy all of the source out of here since we have it all stylized and everything ready to apply that we wanna right-click on our JSP directory and say new GSP going-to call IT account and it will add the extension of dot jsp on there for us doing highlight all this code and paste that in there. And then we're gonna change a couple things inside of here. I'll make this full screen so we get a better view of IT. The very top changed the title to create account UI scroll down here. There's an H one change that create account as well. Then we can remove these too dibs for air messages with the log in. Now we're down to the form that will handle just our account creation. I want to start off by changing this to a model attribute. We could leave the method of post there of account, and that's going to tie to an account object on the back end. And yours may be read like minus here, and that's because we haven't created that account back in yet. We're going to hear in a second. I want to go ahead and change this to B username and it could be tied to that name of username. We'll copy that, lying a couple of times here and we'll have first name change that text, Aziz. Well, I am going to do mine Camel case, and I recommend you follow the exact same convention I am because it will work when we tie it to the being on the back end. So we'll have last name and do the same thing here. Last name. Now we need to also have an email filled tie that end email. We have our password we-can get rid of this. Remember me from the log in page and paste that down below. We'll give this a label of confirmed password Will change the name to matching password. The last thing we want to do on this page has changed that value from log in to just submit. I'm gonna make mine a capital s. We'll save this. Our account page is now set up for us to go ahead and back IT and will next work on supplying that account class so that that red error attributes on my model attribute could go away
to display the page we just created. We need a controller to serve up the view. We will start off by creating a get mapping that will simply serve up the page. Ah, side note. We could have just used a view controller and not needed to create a whole separate controller. But we're going to also submit back to this controller using a post. The signature of our post is also here like Argh IT. And we will code out the rest of the post for our submission of our form. Let's first add the get method to display our page and then the post to take those values back.
Demo: Create Account Controller
our controller class. We're going to actually put in the controller package that we have That's under com dot Pluralsight dot conference controller right-click and say New Java class. We'll call this account controller a man first annotate this as a controller, then inside of here, I'm going to paste in the method signature that I already have created. That is a git mapping import, both of those, and you can see here what it will do is there is a get mapping associated to the U. R L account, and this is just going to return back the JSP or the signature of account, which will have a view resolver that will return the account dot jsp page. Now. One thing we don't have in here yet, though, is the account class. So let's create that now we wanna right-click on our model and say new class. We'll call this account and hit enter. We wanna add our member variables inside of here and I'm going to add in the Java validation for these too. Actually validate our inputs as we add them into our project. Now, we're not going to do anything with the validation on here. You could honestly omit this if you want to, but I'm trying to show you all the pieces of this being a full fledged example. So we have private string username, and we can actually copy this and paste this because it's going to be the same thing for first name and last name. And then we're going to have the same for password and matching password. Well, actually, just put a private, string matching password that both of those will get sent into, and then finally, we'll have the email now. There are a lot of different ways to do this, and this is not a topic to cover in the security class, but rather thes spring NBC Course that I have or some other resource is that I've got made available through the spring fundamentals as well. You can create your own annotations to do this stuff. There's a bunch of different ways to apply some logic to this, for how you're class gets validated. But this will work for the example that we want. The last step we want to do in here is generate our getters and setters so well, right-click and say Generate, get her insider we-can choose all of those and click. OK, save this class. If we go back to account controller we-can now import our account class. Now this will display our account page for us. But we do have to do one thing to our security configuration. So let's go back to our conference security config and we want to add a permit all like we had for log in for account. We want everybody to be able to create the account. So let's save that everything is set up now to run our application we-can fire it up and ask for the account page and it will display IT. UI aren't doing anything with the Post yet, but let's start this to see what it does now inside of our application. If UI navigate to account, it will redirect us to our account page we've created. If we fill out this information and hit submit, there is not a post binding for it to go back to. So it's not going to do anything just yet, But we've got all the pieces set up for it to authenticate the call and allow us to pass through his anonymous and direct us to this controller, which will then return this JSP page. Let's add that post mapping on the back end now.
Now we're ready to add that post back to our controller. So let's go back into that file and I'll shut our server down to give us a little more real estate for full screen. I'm gonna put in the method signature here and import the classes that UI need to use now. And I'll close off this method here. It's gonna return us back to eventually the string redirect account. And if you're not familiar with what this is, it is a spring NBC technique Thio execute a redirect back to the page that you want to go to. I'm gonna pseudo code out a couple of things here in the comments just to show the layout of how you could actually process things inside of your application to add every single step in here would make our application be way too large. So one thing we could do is check for errors. Were going to actually do a lot of these steps. We'll check for errors in the binding results so you can look to see if result has any errors. The next thing that we should look for is we should check for the account to see if there is already one existing in this system, so should verify that the account and the user don't exist in our system. And then we should also verify that the email address is valid as well. And we could use a regular expression to do that or a couple other techniques to do that. So those steps in there and then from here, we need Thio also encrypt the new password coming in as well as we want Thio. Then create the new account. And then we're going to fire off an event for the account creation to have us verify IT. That is all of these steps that have to take place for us to go through and do this post. So let's save this and I'm gonna start our server back up, and now we can navigate to account and enter in some information. And once we hit submit it will go to our server and redirect us back to this page. So it has gone full trip from the get to the JSP page back to the post and then redirected back to this page. Let's now go ahead and look IT starting to flush out all those comments we put inside of our controller and fill in the pieces where we talked to the database.
Now that we've gathered our information, we need to start handling the business logic. If you haven't watched my other spring videos here on Pluralsight or just need a refresher, the service layer is where you want to place your business logic. In our case, we need to create an account and will also create a verification token and then eventually will be where we confirm the account as well.
Demo: Create Account Service
The first step in creating our service here is to create our account service interface. And I'm going to stop our server to give ourselves a little bit more real estate IT toe work with here. If I go down to our service package that we have created right-click and say new we-can click Java class, although we're gonna choose Interface and we'll call it the account service and click in her and this will give us are blank interface that weaken start putting those methods into, We're going to add three methods in here, a public account create, which takes in account as the method signature, a create verification token, which takes in an account and a string token and then, eventually, a confirm account, which will take in the string token as well. So let's save this interface. Then I'm gonna exit full screen for a minute here and right-click on our service package again and say New Java class, and this time it will be the Java class well, say account service impulse, and this will be annotated as a service and it implements the account service interface, and this should give us an error. And if we hover over that we-can choose to implement the methods, and we'll select all three. This gives us our basic signature of what we want to create for all of the's methods. So now we have our service in place. It's annotated as a service. We can access it through the interface. We need to tie that into our controller here in a minute. But since we're here, let's carry out the next step. And that is the repository is well, so this needs to talk to the database and a service will talked to a repository and the repository has the actual database code in there. So let's add those pieces as well. The repository will be in a separate interface in class, so we'll want toe create a new package. And we'll do that by going to com dot Pluralsight dot conference right-click ing and saying new class and we can type in repository dot account, repository and select interface, and that will create the account repository interface inside of here. We're gonna have one signature to start with, and that is the create account. I will be honest with you. The account repository is going to be theme or complex class that we have to deal with in this, because it's going to do all of the interaction that we have with the database. Now this is almost the same exact thing if you want, if you choose to use hibernate or J. P. A. I've used spring JBC to not add yet another dependency inside of here, and it's pretty straightforward. And generally people understand the database side of it and have toe work within existing data model, which, if you are working within existing data model hibernate can be a little bit more complex. So we'll go through the spring Jay to-be sea route and I'm gonna right-click on Repository and create a new class. And that will be the account repository in Pull. And this will be annotated as a repository, and it will implement the account repository interface and the same as we did with the service. If we have her over this, it will give us the option to implement the methods that we have so far, which is just the create. Now we-can inject the data source that we have and create a J D. B C template to inject that first account into our database. Let's go back to our account controller and start injecting in all. The resource is that we want to use inside of our application from the controller. Clear back to the repository. We'll start off here by saying at Otto Wired, want to put in a private account service? We'll put that in a variable account service, and then we'll also dio and at auto wired private password encoder. And this is how we could encrypt the password that we have in sight of our account object that gets passed in. Now that we have those two in there, we'll go down to our post and we-can encrypt that password. So I'll just say account dot set password and we'll say in code account dot get password. So we're going to encrypt that password that was passed in and reassigned that back out to our account and then down below Here, we can use that service that we just created SE Account is equal to account service dot create and pass in our account. Now you may be asking why I am returning account and assigning IT when we already have it, and that's because a lot of times on our back, and not always, but it's a good habit to get into on our back, and we may modify that object to return it. So we may assign a auto in committing filled out of the database or modify in some other way. And we want to return that back. Not always, but it's a good habit to get into. Now that we have that assigned on our account service, though, we can go to the actual service implementation. And inside of here we can auto wire in our repository that we just created. So kind of the same thing will say at Auto Wired will pass in a private account repository and assign that to an account repository variable. And instead of our create here, we-can call account repository dot create and pass in account as well and say that and now we have everything wired up by all the things that we need to do inside of our application are wired up as far-as. The Post is concerned to create the count. We still have a lot of work to dio, but it's wired from our controller to our repository tear so Now we're back to the repository to that we created. Now we-can start implementing thes e J D. B c called to actually assign that account into our database, where we can then work on the verification process. Now it's a little bit of which one is better to do first or the other. We have to create a database table too, right this account Thio, but already have the code here handy. So I am going thio auto wire in our data source. Well, just assign that to a private data source. We'll call that data source and that's already defined through our spring security configuration that we have set up. We're going to utilize the same one, and inside of this creates statement, I'm going to replace that with this J. D. B C template that I have already written, and I'll walk through what I'm doing here with you. UI create an instance of a J D B C template. Then we are going to execute an update statement. That's how you doing Insert that will be an insert into the accounts table. We're gonna go create that here in a second, and that has a column username, password, email, first name and last name, as you can see from that sequel statement and they were just using a simple, prepared statement approach where we use a var arcs to pass in the username, password, email, first name and last name. And when that's all done, we're going to return the account. Now, as I mentioned earlier, sometimes you will update that with things we actually haven't changed anything on account. We're just going to return back the one that we have back to that user. So this is all of the pieces from front to back from the U I to the controller to the service here, clear to the repository right into the database. Now I'm going to go ahead and switch over to the my sequel workbench to create this database table. Switching back to my my sequel editor. You can see that I've got the sequel in here to create a table named Accounts, and I've got in there a username, password, email, first name and last name, all with their respective sizes in a bar chart 50 100 150 50. And I've established that the primary key and here is the username column. So I'm gonna go ahead and highlight that sequel and execute IT, and it completed successfully. And then I'm gonna highlight that commits statement and execute that. So now our table is created. We-can switch back over to the I. D. E. We're actually gonna give this a test run and end its halfway through our confirmation process. But we don't really want to go too much further in case something isn't quite wired up, right? We're gonna have a lot of trouble shooting to do. So let's make sure that this piece is working. How we expected to so far. Let's start our server up that will take a second to run. And now, back in our app, we can go up to the address bar and type in account and put in some garbage data. We're going Thio Delete this record anyway. I will put in a valid email address just so you can see it go through to the database. It's not going past that yet and click submit. It's going to redirect back to this page. It was actually successful. Let's go back over to our my sequel workbench and look to see if that record completed and end to the database, If we go ahead and give ourselves some space down below here we could do a select statement from the accounts table and run that to see if our record was just inserted and you'll see that it waas We have our username of a STF the password which was encrypted using be crypt from our controller, the actual valid email address that we inserted in there and then a first name and last name of a STF that UI pasted in there as well. So everything is going end to end clear from our controller coming in and directing back to the account jsp page us gathering data submitting to the post, encrypting that password, passing it through our service and repository tear, which finally inserts it into our database. If you're not seeing this now, you want to stop and make sure that you don't have any errors in your console or anything else. But if you follow all these steps, you should be too here. Next thing we're gonna do is look at firing off the event that sends the actual email to you to confirm your account
Sending the Emaili
now that we have all the functionality to store the account the database, we will need to send an email to the user to confirm their account, and you might be tempted to do this in a synchronous method, and it can work. But it has the option to block your user and also make for a slow user experience. Instead, it's better to use an event model that has listeners disconnecting our app by firing often event. It can happen in an asynchronous way and not blocked the app while also enabling it to eventually deliver the email in a guaranteed fashion. Spring actually has an event mechanism set up that we could easily take advantage of in our app. Let's add this right after where we saved our account in our controller and encrypted our password. The first thing we need to dio is to add something to our palm file, but I'm going to stop our server and minimize that for a bit so that I have more work space to deal with here, and I open up our palm dot xml and towards the bottom of our dependencies after are unbound. I'd l'd app server going to add a dependency in here for spring boots starter mail. And what this does is it brings in all the dependencies that we need inside of our application to send emails from IT. The next step that we need to do is open up our application properties. So if we go to our source, main resource is application properties. This is where we can set up the configuration for our mail server to send out those emails. All right, the properties we need our thesis Spring male host and I am using a Gmail account. So it's smtp dot gmail dot com the spring male Port of 5 87 spring male username, which is Pluralsight Brian Server. For my instance, you're not going to be able to use that instance. But that's what I'm using for this sample account I set up and a password of fizz Buzz. 1234 That email address and password will be disabled by the time you're viewing this course. Unfortunately, and then the SMTP off said the true and the T TLS enabled also as true. I also want to show you one other thing as well. If you are getting an air message inside of your console. Depending on which version of the driver that you're using, you can switch that over. Thio Arqam dot my sequel dot c j dot j. D B c driver. Depending on the version of the database that you've used, that message is popping up, and all you have to do is replace your JBC driver up here with that. So now that we have those two pieces in here, let's move on to changing our controller to now fire often. Event. Before we modify our controller, though, let's go ahead and create the event that we're going to fire off inside of our application. We're gonna do that by right clicking on com dot Pluralsight dot conference and say New Java class, and we're going to place this underneath the util package and call IT dot on create account event hit. Enter here that will place that underneath the UTIL package. We wanna make this extend the application event from Spring and select that and it will import IT. And the last piece we need to do is to create a constructor that corresponds with the application event in structure and so we're going to call the parent constructor in this one that we have to find here. And it just takes an account object in, and we're gonna pass in a string, which is the app You're Ella's. Well, and we passed the account object into the super call, which is the event for which this object is being called upon. Before we exit out of this, though, let's make it so we can grab the two variables that we passed in here. We'll generate those. We're gonna do getters. We'll select both of them and click. OK, And now this event is set up and ready to go. So I'm going to save this. Let's go back over to our controller now, and we can start defining the event to be thrown inside of it down below here, where we have already got that pseudo could in here showing what we want to dio. We need a wire in one more object instead of here. So we're gonna say at Otto Wired and it is a private application event publisher and this is also supplied by spring as well. So it's the event publisher and this event publisher is what is supplied to you by spring to fire off events that you can tie into a published, subscribe or event event listener model inside of our app. So now that we have that there, we can literally come down here and create a new events. We take that event publisher and say dot publish event I want to import are on create account event and passing the account object and for the app your l we're going to pass in our war name or the URL that we have in the context of our app which in my case, is conference underscore war. If you have changed years to-be something different, you'll want to mirror that Here is well, it does matter because we're going to build the URL off of this. Now we have the first half of this done. You could run your application right now and it will fire off the event, but it is not going to listen for that event yet. So before we try and run that, let's set up the listener as well that will capture this event being fired
Processing the Email Event
firing often Event was actually pretty easy to do, and it may have surprised you how little code IT took to actually fire, often events, since the event publisher, an event model, is already available to you inside of a spring enabled application. I will say, though, that the event listener is where more of the heavy lifting takes place, and that's the portion we're going to do now. So let's exit full screen mode here for a minute. And in our util package that we created, we're going to now create our event listener. It's right-click and say New Java class. And let's name this account listener and this class will actually implement the application listener on the on create account event. So we want to dio implements application listener, and the object that it does this on is the on create account event. Now it's going to have some methods that it wants us to create as part of this object. So let's implement those. There's an on application event and this object will go through and allow us to do a couple of things. You can actually add whatever you want inside of here, but before we dive too far into this. I want to start off by registering. This is a component inside of spring, so we can actually just say at component. And this object will already be a spring bean and registered insight of spring to start listening for events. The on application event. Let's just make this guy call this dot confirm, create account and we will pass in the event. Now, we haven't created this method, so let's do that now. Well, just make this a private void method called confirm, create account. And this is going to take the on create account event as its method signature. I'm going to just copy that from up above into here. Now, let me just lay out the steps of what we need to do inside of here. We're going Thio, get the account, and that just comes out of the event. We are going thio, then create a verification token and this is on us. It's not something inside of spring. We're going to actually create a verification token. Build our message off of that. We're going to get the email properties and then inside of here, we're going to finally send our email. So these are the steps we need to go through to build out what this confirm create account is going to be. There's two other pieces we need to configure inside of here. We're gonna auto wire in our account service that we've created, and we're gonna auto wire in the Java Mel sender. The Java Mel sender is a class that's actually supplied to us from that spring boot mail piece that we added to our palm earlier. And those properties we added to our application dot properties has created this center for us. So it's already tied to our spring enabled properties to fire off these emails. So, at the top of our application, let's put a couple of things here. We want to add a private string server, u R l and we're just going to hard code in a string here. Now I will be the first one to admit that this should be passed in through a properties from our application properties or some dandy I look up or something else. But this example is already starting to get complex, and you can look up how to inject those properties from the spring fundamentals course or some other example. This is just to keep this sample smaller. Then what it was growing into. We're going to auto wire in our Java Mel center. So we'll say at Auto Wired and we want to pass in the private Java male sender and was assigned that to a variable Mel cinder and save that. And now we're going thio also pass in our account service. So I wanna auto wire in the account service and assign that to a variable account service. Now, we can use the account service to go out and create that verification token. And what we're gonna do with that is start off by saying account account is equal thio event dot Get account and that will get the confirm account message that was being fired off from that event and make that available for us to use. And then we're going to just use the random string functions Thio assign a token. So I want to say token is equal to you. You i d dot random you you I'd dot to string and that will generate that token for us. And now we can go out and save this to our database, and we have not implemented all this functionality yet, so we're going to carry this through all of the tears. As I mentioned, this does the heavier lifting for us. So we're going to say account service dot create verification token and that token we're going to pass in the account object instance and the string token that we have here and now let's go to our account service simple and look at what that is doing with this stuff, and that's nothing yet. So we need to go ahead and flush out the rest of the account repository interaction here before we call the Create verification token. On our account repository, though, let's create a verification token object. I want to do that by going to our model right-click and say, New Java class. We'll call this verification token inner and inside of here. We're going to add a handful of fields and one utility method as well. So let's first put in here a public static final ent and we'll call this expiration code and we'll set that equal to 60 times 24. And what we're looking for here is just that we're going to take and have 24 hours in a day and times at 60 minutes in an hour. That will help us in a calculation we're going to do down below. Then we want to pass in or store a string for the token. So we'll have private string token, private string username, and the last thing we're gonna have in here is a private date. We'll use the Java Util date and will name this field expiry date. And that's just the date in which this will expire as a token. Now let's right-click down below here and generate. Get her in centers and we will choose those three fields not thesis attic final end and generate those. And then I'm going to add one more method down below here, which is just a calculate expiry date which you pass in a set number of minutes, get the current time and then add to that an expiration number of minutes and return that back to the user. And this is just gonna help us set in our token as to when that object expires. So now we have our token set up. Let's go back to our account service. Simple and we can begin to flush that out. And now we can take advantage of that verification token that we just created. So we'll say verification token