Spring Security with Maven Tutorial
1. Introduction
In this post, we shall demonstrate how to use Maven dependencies for Spring Security for very specific use-cases. The latest versions of all the libraries we use can be found on the Maven Central.
Understanding how Maven dependencies work and are managed is important in a project for an effective build cycle and clear concepts about what versions match between various libraries we use in our project. This is due to the reason that we often repeat the set of dependencies in multiple projects and when we don’t understand why we’re using a specific library version, we are ought to do mistakes. Let’s understand the relationship between Spring Security and Spring Framework dependencies.
2. Spring Security with Maven
In this section, we will cover specific use-cases for managing Maven Dependencies. This is due to the reason that Spring Security involves a lot of features and not all dependencies are needed for every feature you might want to integrate in your application. These features includes (but not limited to):
- Registration process secured by Spring Security
- Password Encryption so that passwords are protected even if someone has the access to the Database
- Managing User roles and permissions so that every user has specific actions which he can perform in an application
- Retrieving user information from Spring Security in an application along with the roles and privileges assigned to the user
- Protected RESTful APIs so that access remains restricted
2.1 spring-security-web
Spring Security Web dependencies are used for providing features related to the web security of an application like:
- Restricted access to URLs in a Servlet Container environment
- Managing the Spring Secuirty filters related to web
To add the web support in Spring Security, here is the dependency which is needed:
spring-security-web
<properties> <org.springframework.security.version>3.2.3.RELEASE</org.springframework.security.version> <org.springframework.version>4.0.4.RELEASE</org.springframework.version> </properties> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${org.springframework.security.version}</version> </dependency>
Do note that we also defined the version of Spring Framework and Spring Security we use as a Maven property and reuse the same in all depenedencies we mention for these modules.
The main point to be noted that the Spring Framework and Spring Security doesn’t exactly match the version numbers as they follow a different schedule. This is important to note because, for example, Spring Security 3.1.x does not depend on Spring 3.1.x releases as Spring Security 3.1.x was released before Spring 3.1.
Finally, to understand all the JARs which are added to the project when we added this dependency, we can run a simple Maven command which allows us to see a complete Dependency Tree for a project when we add some dependencies to it. Here is a command which we can use:
Check Dependency Tree
mvn dependency:tree
When we run this command, it will show us the following Dependency Tree:
As clearly shown in the image above, spring-security-web
JAR also brings some other dependencies with it like spring-aop
, spring-beans
, spring-context
, spring-core
, spring-expression
and spring-web
. When we ran the command above, before presenting to us the Dependency Tree, maven first downloaded the JARs again to confirm if something has changed.
Finally, note that if one of the dependency needed another dependency to run, it was also downloaded and was shown as a sub-branch of the tree in the dependency tree above. The method of sub-branched representation of an indirect dependency clears out when some depndency brings another dependency into the dependency pool of the build system.
2.2 spring-security-core
Now, let’s look at the core dependencies which are needed for Spring Security implementations:
spring-security-core
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>${org.springframework.security.version}</version> </dependency>
With Spring Security Core dependencies, we’re ready to use functionalities like:
- Access Control
- Method-level Security
- Support for non-web applications as well
This is one of the most used dependencies in Spring Security Maven dependency family. Let’s look at the dependency tree for the spring-security-core
JAR now:
2.3 spring-security-config
If you use XML namespace definitions for benas related to Spring Security, spring-security-config Maven dependencies is required in the application.
spring-security-config
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${org.springframework.security.version}</version> <scope>runtime</scope> </dependency>
Due to the fact that this dependency is only used in XML namespace definitions, it is defined with runtime scope. Note that other config features like ACL, CAS, OpenID and LDAP have their own dependencies like: spring-security-acl, spring-security-cas, spring-security-openid, and spring-security-ldap. Even though the dependency has a runtime scope, its dependencies will be still be downloaded though, let’s look at its Dependency Tree here:
2.4 Problems with older Spring Security Dependencies
A main problem which arises with Spring Security JARs is that not all Spring Security JARs depends on the latest version of Spring Framework related dependencies but they actually need an older version of the dependencies. This is why, we need to explicitly define these JARs so that maven doesn’t report for version conflicts when it starts to collect dependencies and compile the code against them. Here are the required dependencies:
Explicit Dependencies
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${org.springframework.version}</version> </dependency>
This way, when we explicitly define some of the Spring dependencies in our own pom.xml file, we put that dependency at 0 depth and so, it will take priority with the mentioned version instead of implicit dependencies in the Spring framework dependency tree. Let’s look at the dependency tree here to clear this out:
When we look at the dependency tree here, we see the exact versions of the JARs which were added into the project due to being explicitly mentioned in the pom.xml
file.
Read more about Solving Dependency Conflicts in Maven here.
3. Snapshots and Milestones in Spring Security
Spring Security has Snapshot and Milestone releases available which are present in the Spring provided custom Maven repositories. Read this lesson to know how you can put these releases to use in your appplication.
The main difference between Release artifact and Snapshot artifacts is that Release artifact are specific and pre-planned releases which are made at a pre-decided point of time and are considered to be solid, stable, and perpetual in order to guarantee that builds which depend upon them are repeatable over time. The Central Maven repository stores release artifacts.
Snapshots capture projects where work is still in progress and are used during development. A Snapshot artifact has two parts: a version number such as “1.3.0” or “1.3” and a timestamp. For example, a snapshot artifact for spring-framework 1.3.0 might have the name spring-framework-1.3.0-20180323.19283-3.jar.
4. Conclusion
In this lesson, we discussed various Maven Dependencies with Spring Security along wth some major issues which are usually faced by beginners when they start to use Spring Security features. This lesson is a very good starting place to understand the required dependencies.
We also explained how important it is to specify the version of some specific JARs when using Spring Security with Spring Framework and how we can’t rely on the dependency versions which Spring Framework pick for these JARs. By specifying specific dependencies, all we do is make sure that Maven picks these explicit version specifications instead of Spring Framework dependency version so that version conflicts doesn’t occur.
Finally, we learned how we can show a dependency tree of a project by using a simple maven command and observe which dependencies of a project depends on what other dependencies.
Read a lot more lessons on Spring Framework here.
5. Download the Source Code
This was an example which shows how to use different Spring Security based dependencies in your project.
You can download the full source code of this example here: SpringSecurityMaven