Integrating Spring Security pt 1

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.