Spring boot with Spring Security and jdbc

Spring security Is a wonderful framework saving lots of time and effort from the developers. Also It is flexible enough to customize and bring it down to your needs.

Working with JDBC and Spring Security is pretty easy and many actions are automated. This would be a minimal showcase.

The gradle file contains dependencies such as spring-security, spring-jdbc and h2 database. Since there would be a series of articles bootRun will set a spring profile on startup, In our case the profile called simple.

group 'com.gkatzioura'
version '1.0-SNAPSHOT'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.0.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.thymeleaf:thymeleaf-spring4")
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.springframework:spring-jdbc")
    compile("com.h2database:h2:1.4.192")
    compile("org.slf4j:slf4j-api:1.6.6")
    compile("ch.qos.logback:logback-core:1.1.7")
    compile("ch.qos.logback:logback-classic:1.1.7")
    testCompile "junit:junit:4.11"
}

bootRun {
    systemProperty "spring.profiles.active", "simple"
}

Tables containing certain information must be created. Those tables will have the default name and column names that Spring security lookups in order to get information.

drop table if exists users;
create table users(id bigint auto_increment, username varchar(255), password varchar(255), enabled boolean);
insert into users(username,password,enabled) values('steve','steve',true);
insert into users(username,password,enabled) values('john','john',true);
drop table if exists authorities;
create table authorities(username  varchar(255),authority  varchar(255), UNIQUE(username,authority));
insert into authorities(username,authority) values('steve','admin');
insert into authorities(username,authority) values('john','superadmin');

Those sql statements will reside on resources/schema.sql.

First step is to create our Application class

package com.gkatzioura.spring.security;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Created by gkatzioura on 9/2/16.
 */
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

In order to get started quickly the database will be an h2 database.

package com.gkatzioura.spring.security.config;

import org.h2.jdbcx.JdbcDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.nio.file.Files;

/**
 * Created by gkatzioura on 9/2/16.
 */
@Configuration
public class DataSourceConfig {

    @Bean
    public DataSource createDataSource() {

        JdbcDataSource dataSource = new JdbcDataSource();
        dataSource.setURL("jdbc:h2:"+System.getProperty("java.io.tmpdir")+"/database");

        return dataSource;
    }

}

By specifying the h2 database I set the directory to be inside the temporary directory. Therefore once you restart your os the database will be gone.
As mentioned previously once the datasource bean has been initialized spring-jdbc will automatically lookup on the resource folder for a schema.sql file. In case the file exists spring-jdbc will try to execute the statements that the schema.sql contains.

Next step is to define our security configuration. We have to specify that our security will be based on jdbc. Also we must define the endpoints that will have to be secure. This security config bean will be bound to the simple profile.

package com.gkatzioura.spring.security.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import javax.sql.DataSource;

/**
 * Created by gkatzioura on 9/2/16.
 */
@EnableWebSecurity
@Profile("simple")
public class SimpleSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                .antMatchers("/public").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }
}

Last but not least we will add a controller with a secured endpoint and a non-secured endpoint

package com.gkatzioura.spring.security.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by gkatzioura on 9/2/16.
 */
@RestController
public class GreetController {

    private static final Logger LOGGER = LoggerFactory.getLogger(GreetController.class);

    @RequestMapping(path = "/public",method = RequestMethod.GET)
    public String sayFreeHi() {
        return "Greeting";
    }

    @RequestMapping(path = "/secured",method = RequestMethod.GET)
    public String saySecureHi() {
        return "Secured";
    }

}

Once you try to access the secured endpoint the default spring security login screen will be displayed.
Proceed with one of the users specified in the sql statements (for example username: steve password: steve). In case you want to logout just hit the /login?logout endpoint.

Run the application with a

gradle bootRun

and you are good to go.

You can find the source code on github

Advertisement

3 thoughts on “Spring boot with Spring Security and jdbc

  1. Hi Gkatziouras,

    I downloaded the code from Github & deployed on my local but when accessing the application then its gives me a popup of basic authorization. I tried all the 3 user name & password but none of the accepted. Please guide me how to login.

    Thanks in Advance.

    Dinesh

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.