Overview: What you'll learn
In this video you will learn how to add Spring Security to a fresh Spring Boot application step by step. Adding Spring Security to Spring Boot has a surprising and an interesting effect. You will learn what this effect is and you'll also understand why that's happening.
Starting point: simple Spring Boot web app
Alright, here's our starting point. It's a simple Spring Boot application with just the web dependency and I've added a simple API that you can use to test. Let me show you what I've got here. So this is my Spring Boot application open in IntelliJ. If you look at the pom.xml that is just the web dependency and of course the test dependency. Here is the main application class with the main method that you would expect from a Spring Boot app and here is this resource that I've added. It's called HomeResource. It just has a home method which is mapped to the root URL and it just responds a simple welcome text in an h1 tag. Now if I were to start the server and open localhost:8080 in a browser you should see the welcome message that that controller returns. All right, so this is mapped to the root URL. Accessing the root URL is going to show me that welcome message.
Adding Spring Security dependency
All right, so now how do I add Spring Security to this kind of a web application project? The way to add Spring Security to a Spring Boot project is by using a dependency called spring-boot-starter-security. Just like with a whole lot of Spring Boot dependencies this is a starter pack. It is a Maven dependency which pulls in all the necessary Spring Security dependencies and makes them available for you so you don't have to hunt down individual dependencies. You can do that of course, but this is the best and the most recommended way. So all you need to do is go to your pom.xml and I'm gonna stick this dependency here after the starter-web. I've got spring-boot-starter-security dependency. Now most of the Spring Boot starter dependencies don't typically have an effect just by adding it to the classpath. You also have to have some kind of configuration that goes with it in order to tell Spring Boot, 'Hey I have this dependency, take it and use it and do something with it.' However with Spring Security it's something different. All you need to do is add this to the classpath and Spring Security immediately starts working. What does it do?
Let me show you. Now if I were to start this application again with just the dependency added and no configuration done, and if I were to access the same route URL, notice what happens. There is a sign-in form. We didn't add this thing in here. How did this get here and what are you even logging in with? Who's to sign in? I can try something, let's say 'tests' and 'tests'. It doesn't work. It's even doing validation. It has a proper sign-in endpoint. It's checking to see if your credentials are valid and in my case where I've entered random values it tells us that they are bad credentials and it doesn't let me sign in. What's happening here?
Why Spring Security takes over: filters and servlets
Well, let me tell you. So you remember the picture in some of my previous videos where I talk about Spring Security being this watchman or security guard in front of your application which is basically intercepting all the requests and making sure that the person who is making the request is the right person who is allowed to be making those requests. This is kind of what Spring Security is doing. Just by adding Spring Security dependencies to the classpath it's kind of sitting in front and it's stopping you from accessing the application. How does this happen? How does Spring Security do this just by adding something to the classpath? How can Spring Security intercept and kind of take over the whole application like this? Well, the answer is using something called filters. If you're not familiar, filters are a very basic concept of servlet applications and Spring Boot and Spring Security and all of these Java web applications are servlet applications after all. So you have basic servlets, basics of the technology working underneath to provide all this kind of rich functionality and you have all these frameworks built on top of it so that you don't have to deal with the servlet layer. But what's actually doing all the job are those servlet technologies and filters are one of the core concepts associated with some of the technologies. Now how does it work? Think of a web app and you have a bunch of servlets here which are basically what do the work when a user makes a request. Right, so user makes a request to a URL and then there is a particular servlet that does the functionality and provides a response for that particular request. And the way it works is depending on the URL the right servlet is picked. The servlet container looks at the URL and says, 'Okay, this URL needs to be handled by the servlet,' and then it picks the right servlet that needs to do the job and then it executes a method on that servlet. This is how servlets work. But think of filters as kind of like cross-cutting concerns. Filters kind of stand right in the middle and they intercept every request and this gives you an opportunity to do something with every request. You can kind of think of it as cross-cutting pieces of functionality that you can use to log every request, for example, or check every request to see a particular header is there or not, you know, stuff like that. So while servlets are mapped to URLs, filters can be applied to all URLs. You can put a filter in there and say, 'Okay, this filter needs to intercept all URLs,' and then you have that filter allow or deny based on the request itself. Well guess what? Spring Security is doing exactly that. Spring Security is just putting in a filter there and saying, 'Okay now I'm going to sit here and examine all requests to allow or deny requests as per what I should be doing.'
Spring Security default behaviors
There are a bunch of things that Spring Security does by default. First of all, it adds mandatory authentication for all URLs. Let's say you have a Spring Boot application with a bunch of URLs; you throw Spring Security in there by default without any configuration, it makes sure that authentication is required for all those URLs. When I say 'all' there are a few things that it does skip authentication for; for example the error page. Spring Boot applications come with a '/error' by default. Well, Spring Security does not secure that because you don't typically need authentication to show error messages. But in general it adds authentication mandatory for all your APIs. It's the first thing that it does. Second, it adds a login form. We've seen that there is a '/login' route which brings up the login form. It adds that controller to your application. Next, it handles any login errors. It has this authentication logic where it extracts your user ID and password and then it validates and makes sure that that's correct. If it's not correct it shows a login message which we've just seen.
Generated default user and how to find credentials
You might be thinking, 'Hey hang on, what is a correct user ID and password because we haven't done anything?' It just added Spring Security. Is it getting the user ID and password from? Well, Spring Security is saying, 'Okay, now somebody has added me to the classpath. I make authentication mandatory by default but it turns out this developer has not given me a user ID and password to authenticate against. Now here's what I'm going to do: I'm going to create my own user ID and my own password,' which is exactly what Spring Security does. So this is the fourth thing that Spring Security does when you add it to the classpath: it's created a user ID and password. And that's the reason why it's showing up a login form for us and it's not allowing us to enter. But now how do I figure out what that user ID and password is? If you look at the console log over here you see this: it says 'Using generated security password.' So this is the password that it has generated, and by convention Spring Security creates a user called 'user'. So this is the user ID and password that Spring Security creates by default for our Spring Boot application just by adding that dependency. I'm going to copy this password, go back to the form, enter the user name 'user' and this password and click sign in. There you go, we are in. So this is the default behavior of Spring Security and just by adding Spring Security to the classpath we have achieved this functionality.
Customizing the default user via application.properties
You can of course customize this automatically created user though. So what you can do is go to your application.properties and you can add a couple of properties in here. So the first property is spring.security.user.name and then make it 'foo' and then again you can do spring.security.user.password. I said that as 'foo' as well. All right, so now you're basically telling Spring Security, 'Hey create the user with this name and this password.' That one default user that you're going to create, create this username and with this password. So when you start this application now Spring Security thinks, 'Oh good, now I want to do the default behavior of having authentication but I don't have to create my own user. Here is this one user that this developer has given for me,' so it's going to create that user instead of the default user. Now if you were to start the application look at the logs in the console, you will not see that 'created user with generated password' message anymore, right? It doesn't do that because it doesn't need to. It's just going to use your user ID and password that you entered in your application.properties. Now if you open the same URL and enter that username and password 'foo' and 'foo' there you are in again. So this is how you add Spring Security to your Spring Boot application. Now that the application property values, what we've managed to do is to override the default user that Spring Security created, but we obviously want more. We want Spring Security to refer to some kind of a list of users that we have in our system. In order to do that we need to configure the authentication mechanism and Spring Security. Click this video to learn how exactly to configure and override authentication in Spring Security. I'll see you there.
Postscript: closing music
see you there [Music]