Spring Security
Coverage
In this first part, I’m going to cover integrating Spring Security into a web application to authenticate users stored in a MySQL database.
Introduction
I’ve developed a project named Passport with which I plan to utilize in any project requiring users. Rather than constantly having to re-write the storage and access faculties, I can import the UserService and go from there. This works great in a controlled environment, so I decided to test it by creating a new project using Spring Security to authenticate against the user store. I frequently use Spring Security, and figured it’d save me the hassle of writing session code for web apps.
Fail
The problem I ran into is that Spring Security cannot be configured to use a specific method in a specific class to authenticate users. I need a new way to access the database to verify user’s identity, while still finding value in Passport.
Answer
The solution is easy. In accessing a MySQL data store, Spring Security can be configured to use specific queries. Even better, to ensure password privacy, it can use a hashing algorithm (sha) to manipulate the password stored.
First, here is the entire security-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http: www.springframework.org schema beans"
xmlns:xsi="http: www.w3.org 2001 XMLSchema-instance"
xmlns:context="http: www.springframework.org schema context"
xmlns:p="http: www.springframework.org schema p"
xmlns:security="http: www.springframework.org schema security"
xsi:schemaLocation="http: www.springframework.org schema beans
http:= www.springframework.org schema beans spring-beans-3.1.xsd
http:= www.springframework.org schema context
http:= www.springframework.org schema context spring-context-3.1.xsd
http:= www.springframework.org schema security
http:= www.springframework.org schema security spring-security-3.1.xsd">
<!-- Import the dynamic properties -->
<context:property-placeholder location="WEB-INF connections.properties" />
<!-- Scan for annotated methods -->
<security:global-method-security secured-annotations="enabled" />
<security:http auto-config="true">
<!-- Restrict URLs based on role -->
<security:intercept-url pattern=" secured" access="IS_AUTHENTICATED_FULLY" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:password-encoder hash="sha" />
<security:jdbc-user-service data-source-ref="myDataSource"
users-by-username-query="select= username, password, true from users where username=" />
</security:authentication-provider>
</security:authentication-manager>
<!-- MySql -->
<bean id= "myDataSource" class= " org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name= " driverClassName" value= " com.mysql.jdbc.Driver" />
<property name= " url" value= " ${datasource.url}" />
<property name= " username" value= " ${datasource.user}" />
<property name= " password" value= " ${datasource.pw}" />
</bean>
</beans>
As you will hopefully notice, I’m importing the volatile datastore attributes through the PropertyPlaceholderConfigurer, accessing the values with ${}. This allows for easy changes when used in different environments.
Secondly, the security:password-encoder property defines the hashing algorithm used for the password. Other options include plaintext, sha-256, md4, and md5.
Lastly, two queries are specified to be used by Spring Security — users-by-username-query and authorities-by-username-query. The first is obvious. The latter authorities by username, which is use to authenticate roles for users. This is very important, as authentication is primarily based against a user’s roles.
Solution
So, once we try to go to any URLs beneath /secured, we will need to be authenticated. Spring will generate the login page for us, and prevent access without a successful login.
Next, how to access the user’s information in Java.
