Spring Security JdbcUserDetailsManager Example

0

In this article we will see how we can create user details using spring security. This will introduce you with the basic the classes that deal with the user and the authorities granted. We won’t deal with the authentication here.

Spring UserDetails API

Here is the class diagram that shows relationship between user details, authorities and the user details manager. We will be using spring provided JDBC user management service.

Create tables for user and authorities

Here are the tables that we need – users to store user details and authorities to store the authorities granted to the user.

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;

Register user details manager bean

We will register the datasource, password encoder and user details manager. We will also do the database setup here.

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>	
</beans>

Example to manage user

We encode the password, create User object using the username and encoded password and then create the user using the JDBC service. We then load the user and make sure password is matches.

CreateUserExample:

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.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 CreateUserExample {
    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);
        
        UserDetails userJoeLoaded = jdbcUserMngr.loadUserByUsername(username);
        System.out.println(userJoeLoaded);
        System.out.println("Password matches? " + encoder.matches(password, encodedPassword));
    }
}

Output:

Encrypted password: $2a$10$kPADSeahIjoEifxzfo4b9OFONpHRWwUcAx/RZzzAt3J3uihzXgAS6
[email protected]: Username: Joe; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: Order Create,Order View
Password matches? true

Download the source code

This was an example of creating user details using spring security.

You can download the source code: springSecurityUserPassword.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.