Spring security user authentication

0

In this article, we will see how to use Spring Security’s built-in JDBC support to authenticate users. The authentication manager, once successfully authenticated, returns fully populated Authentication object including granted authorities.

Spring Security Authentication APIs

  1. Password Encoder – We will use BCrypt strong hashing function to encrypt the password.
  2. Authentication request – We build an authentication request token based on username and password and then pass it to an authentication manager to authenticate the token.
  3. Authentication Implementation – We will use Spring Security provided out-of-the-box JDBC way of authenticating the request.
  4. Authentication provider – We will use the JDBC way of authenticating user. One can provide more than one provider so that the provider manager can iterate the authentication request through each one of the provider

We define the authentication manager and the provider in our context file.

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">

	<bean id="passwordEncoder"
		class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
	<jdbc:initialize-database data-source="dataSource"
		enabled="true">
		<jdbc:script location="classpath:db-schema.sql" />
	</jdbc:initialize-database>
	
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost/test" />
		<property name="username" value="root" />
		<property name="password" value="admin" />
	</bean>
	
	<bean id="jdbcUserDetailsManager"
		class="org.springframework.security.provisioning.JdbcUserDetailsManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>	
	
    <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <property name="userDetailsService">
            <ref bean="jdbcUserDetailsManager"/>
        </property>
        <property name="passwordEncoder">
            <ref bean="passwordEncoder"/>
        </property>
        <property name="hideUserNotFoundExceptions">
            <value>false</value>
        </property>
    </bean>	
    
	<bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
		<constructor-arg>
			<list>
				<ref bean="daoAuthenticationProvider"/>
			</list>
		</constructor-arg>
	</bean>    
</beans>

We create the necessary tables during the startup.

db-schema.sql:

drop table if exists `users`;
drop table if exists `authorities`;
CREATE TABLE `users` (
  `USERNAME` VARCHAR(50) BINARY NOT NULL,
  `PASSWORD` VARCHAR(500) NOT NULL,
  `ENABLED` boolean not null,
  PRIMARY KEY (`USERNAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `authorities` (
  `USERNAME` VARCHAR(20) NOT NULL, 
  `AUTHORITY` VARCHAR(20) NOT NULL)
  ENGINE=InnoDB;

We create the user. Next we authenticate the user.

        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password);
        AuthenticationManager authenticationManager = (AuthenticationManager) context.getBean("authenticationManager");
        Authentication result = authenticationManager.authenticate(authentication);

UserAuthenticationExample:

package com.javarticles.jdbc;

import java.sql.SQLException;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;

public class UserAuthenticationExample {
    public static void main(String[] args) throws SQLException {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        String username = "Joe";
        String password = "security_is_fun";
        
        PasswordEncoder encoder = (PasswordEncoder) context.getBean("passwordEncoder");
        String encodedPassword = encoder.encode(password);
        System.out.println("Encrypted password: " + encodedPassword);
        
        JdbcUserDetailsManager jdbcUserMngr = (JdbcUserDetailsManager) context.getBean("jdbcUserDetailsManager");
        List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("Order View", "Order Create");
        UserDetails userJoe = new User(username, encodedPassword, authorities);
        jdbcUserMngr.createUser(userJoe);
        
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password);
        AuthenticationManager authenticationManager = (AuthenticationManager) context.getBean("authenticationManager");
        Authentication result = authenticationManager.authenticate(authentication);
        System.out.println("Result: " + result);
    }
}

After authentication, the returned authentication object has all the details including the granted authorities.

Output:

Encrypted password: $2a$10$0fuu/Gzv5oRbTiedOgA9Yek6R1lHcjBdbCV.pRjWEH5ciV/QHE8u6
Result: org.springframew[email protected]aead065d: Principal: [email protected]: Username: Joe; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: Order Create,Order View; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: Order Create, Order View

Download the source code

This was an example about authenticating a user using spring security.

You can download the source code here: springSecurityAuthentication.zip

About Author

Ram's expertise lies in test driven development and re-factoring. He is passionate about open source technologies and loves blogging on various java and open-source technologies like spring. You can reach him at [email protected]

Comments are closed.