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
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" }
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.
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 public class SecurityConfig 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
Reference: | Spring boot with Spring Security and jdbc from our JCG partner Emmanouil Gkatziouras at the gkatzioura blog. |