Spring Boot + Security + MySQL (2023) Hello World Example | CodeUsingJava








Spring Boot + Security + MySQL (2023) Hello World Example

In this tutorial we will be implementing Spring Boot Security in our application.
Spring Security is one of the most important framework used for making enterprise applications. It provides some of the important features which includes user authentication i.e.who you are and authorization i.e. are you authorized to fetch a particular request.
Springsecurity intro
The mysql default schema can be defined as follows- The username in the User class acts as a foreign key for the Authority class.
Mysql default schema
In this example, i would be implementing basics of Spring Security using a simple example where I would be using mysql default schema for the database configuration. Finally, as a result, a login form will be linked in our application.
  • This will be the standard directory layout for maven project structure-
    Springsecurity webconfigurer Project
    We need to start by creating a Maven pom.xml(Project Object Model) file. The pom.xml file contains the project configuration details.
    	<?xml version="1.0" encoding="UTF-8"?>
    	<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    		xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    		<modelVersion>4.0.0</modelVersion>
    		<parent>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-parent</artifactId>
    			<version>2.3.4.RELEASE</version>
    			<relativePath/> <!-- lookup parent from repository -->
    		</parent>
    		<groupId>com.codeusingjava</groupId>
    		<artifactId>WebSecurityDBConfigurer</artifactId>
    		<version>0.0.1-SNAPSHOT</version>
    		<name>websecurity</name>
    		<description>Spring boot security authentication project</description>
    	
    		<properties>
    			<java.version>1.8</java.version>
    		</properties>
    	
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-starter-security</artifactId>
    			</dependency> 
    			<dependency>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-starter-web</artifactId>
    			</dependency>
    	
    			<dependency>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-starter</artifactId>
    			</dependency>
    	
    			<dependency>
    				<groupId>mysql</groupId>
    				<artifactId>mysql-connector-java</artifactId>
    				<scope>runtime</scope>
    			</dependency>
    	
    			<dependency>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-starter-data-jpa</artifactId>
    			</dependency>
    	
    			<dependency>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-starter-test</artifactId>
    				<scope>test</scope>
    				<exclusions>
    					<exclusion>
    						<groupId>org.junit.vintage</groupId>
    						<artifactId>junit-vintage-engine</artifactId>
    					</exclusion>
    				</exclusions>
    			</dependency>
    		</dependencies>
    	
    		<build>
    			<plugins>
    				<plugin>
    					<groupId>org.springframework.boot</groupId>
    					<artifactId>spring-boot-maven-plugin</artifactId>
    				</plugin>
    			</plugins>
    		</build>
    	
    	</project>
    	
    
    The application.properties file is as follows:- All the database related configurations are done in this file.
    	spring.datasource.url=jdbc:mysql://localhost:3300/SecuritySchema?createDatabaseIfNotExist=true&autoReconnect=true&useSSL=false
    	spring.datasource.password=****
    	spring.datasource.username=root
    	spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    	spring.datasource.initialize=false
    	spring.jpa.hibernate.ddl-auto=create-drop
    
    
    Creating the schema file for the database configuration
    We use mysql default schema which defines about the users and their authorities assigned.
    	
    
    	CREATE TABLE UsersTable(
    		username VARCHAR(50) NOT NULL PRIMARY KEY,
    		PASSWORD VARCHAR(200) NOT NULL,
    		email VARCHAR(100) NOT NULL,
    		enabled BOOLEAN NOT NULL
    	);
    	
    	CREATE TABLE authorities (
    		username VARCHAR(50) NOT NULL,
    		authority VARCHAR(50) NOT NULL,
    		CONSTRAINT fk_authorities_users FOREIGN KEY(username) REFERENCES UsersTable(username)
    	);
    	
    	CREATE UNIQUE INDEX ix_auth_username ON authorities (username,authority);
    	
    
    Query to write inside data.sql INSERT into UsersTable(username,password,email,enabled) values ('user','{noop}user','[email protected]',true); INSERT into UsersTable(username,password,email,enabled) values ('admin','{noop}admin','[email protected]',true); INSERT into authorities values ('user','USER'); INSERT into authorities values ('admin','ADMIN');
    Creating the configuration class for spring security:-
    All the configurations related to HttpSecurity are done inside the configure method().
    For the process of authentication of user, AuthenticationManagerBuilder is used.
    As we are using mysql database to store users and their authorities, so we use jdbcAuthentication.
    WebSecurityConfigurerAdapter is a class which provides several methods by which httpSecurity and WebSecurity can be customised.
    PasswordEncoder specifies whether the password is to be stored in its original form or by the manner the password is to be encoded.
    	package com.codeusingjava.websecurity.config;
    
    	import org.springframework.beans.factory.annotation.Autowired;
    	import org.springframework.context.annotation.Bean;
    	import org.springframework.context.annotation.Configuration;
    	import org.springframework.security.authentication.AuthenticationManager;
    	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 org.springframework.security.crypto.factory.PasswordEncoderFactories;
    	import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
    	import org.springframework.security.crypto.password.PasswordEncoder;
    	
    	import javax.sql.DataSource;
    	
    	@Configuration
    	@EnableWebSecurity
    	public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    	
    		@Override
    		protected void configure(HttpSecurity http) throws Exception {
    			http.authorizeRequests()
    					.antMatchers("/api1/*").hasAnyRole("USER","ADMIN")
    					.anyRequest().authenticated()
    					.and()
    					.formLogin().permitAll()
    					.and()
    					.logout().permitAll();
    	
    			http.csrf().disable();
    		}
    	
    	
    		@Bean
    		public PasswordEncoder passwordEncoder() {
    			return (DelegatingPasswordEncoder) PasswordEncoderFactories.createDelegatingPasswordEncoder();
    		}
    	
    		@Autowired
    		private DataSource dataSource;
    	
    		@Override
    		@Bean
    		public AuthenticationManager authenticationManagerBean() throws Exception{
    		   return  super.authenticationManagerBean();
    		}
    	
    	 @Autowired
    		public void configure(AuthenticationManagerBuilder auth) throws Exception {
    			auth.jdbcAuthentication()
    			.dataSource(dataSource).passwordEncoder(passwordEncoder())
    			.usersByUsernameQuery("select username,password,enabled from users where username=?")
    			.authoritiesByUsernameQuery("select username,authority from authorities where username=?");
    		}
    	}
    
    Creating the basic controller class.
    Principal in spring security is used to get the details of currently logged in user.
    	package com.codeusingjava.controller;
    
    	import org.springframework.web.bind.annotation.GetMapping;
    	import org.springframework.web.bind.annotation.RequestParam;
    	import org.springframework.web.bind.annotation.RestController;
    	
    	import java.security.Principal;
    	
    	@RestController
    	public class HelloController {
    		
    		@GetMapping("/api1")
    		public String Welcome(@RequestParam(required = false,defaultValue = "Welcome User") String name, Principal principal) {
    			return name+" : You are logged in as "+principal.getName()+"";
    		}
    	}
    	
    
    Run the following Spring Boot class for starting our application.
    	package com.codeusingjava.websecurity;
    
    	import org.springframework.boot.SpringApplication;
    	import org.springframework.boot.autoconfigure.SpringBootApplication;
    	
    	@SpringBootApplication
    	public class WebsecurityApplication {
    	
    		public static void main(String[] args) {
    			SpringApplication.run(WebsecurityApplication.class, args);
    		}
    	
    	}
    
If we now run the application we get the output as follows:-
Springsecurity running application
We login here by the username and password which we inserted in our database. The next page would be shown only by entering correct username and password.
Here we are login by using username and password of User.
springsecurity output

springsecurity api1

Downloads-

Spring Boot + Security + MySQL Example