[Java / Spring Boot] Spring security ④ --Implementation of login process

In Spring, let's check the ID and password entered on the login screen with the DB, and easily create a function that prohibits access to a specific URL with user privileges ~ ♪ Last time, we prohibited direct links, implemented a login function, and translated error messages into Japanese. This time, since version 2 of Spring Boot, password encryption has become mandatory, so we will implement ** password encryption ** ^^

Password encrypted and stored in database

Password encoder bean definition

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

Password decryption at login

SecurityConfig.java


package com.example.demo;

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //Data source
    @Autowired
    private DataSource dataSource;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    //SQL statement to get user ID and password
    private static final String USER_SQL = "SELECT"
            + "    user_id,"
            + "    password,"
            + "    true"
            + " FROM"
            + "    m_user"
            + " WHERE"
            + "    user_id = ?";

    //SQL statement to get the user's role
    private static final String ROLE_SQL = "SELECT"
            + "    user_id,"
            + "    role"
            + " FROM"
            + "    m_user"
            + " WHERE"
            + "    user_id = ?";

    @Override
    public void configure(WebSecurity web) throws Exception {

        //No security is applied to access to static resources
        web.ignoring().antMatchers("/webjars/∗∗", "/css/∗∗");
    }

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

        //Login-free page settings
        http
            .authorizeRequests()
                .antMatchers("/webjars/**").permitAll() //Permission to webjars
                .antMatchers("/css/**").permitAll() //Permission to css
                .antMatchers("/login").permitAll() //Direct link OK for login page
                .antMatchers("/signup").permitAll() //Direct link OK for user registration screen
                .anyRequest().authenticated(); //Other than that, direct link is prohibited

        //Login process
        http
            .formLogin()
                .loginProcessingUrl("/login") //Login process path
                .loginPage("/login") //Specify login page
                .failureUrl("/login") //Transition destination when login fails
                .usernameParameter("userId") //Login page user ID
                .passwordParameter("password") //Login page password
                .defaultSuccessUrl("/home", true); //Transition destination after successful login

        //Disable CSRF measures (temporary)
        http.csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        //Get user information at the time of login process from DB
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery(USER_SQL)
                .authoritiesByUsernameQuery(ROLE_SQL)
                .passwordEncoder(passwordEncoder());
    }
}

Repository class

String password = passwordEncoder.encode(user.getPassword());

UserDaoJdbcImpl.java


package com.example.demo.login.domain.repository.jdbc;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Repository;

import com.example.demo.login.domain.model.User;
import com.example.demo.login.domain.repository.UserDao;

@Repository("UserDaoJdbcImpl")
public class UserDaoJdbcImpl implements UserDao {

    @Autowired
    JdbcTemplate jdbc;

    @Autowired
    PasswordEncoder passwordEncoder;

    //Get the number of User table.
    @Override
    public int count() throws DataAccessException {

        //Get all and count
        int count = jdbc.queryForObject("SELECT COUNT(*) FROM m_user", Integer.class);

        return count;
    }

    //Insert 1 data in User table.
    @Override
    public int insertOne(User user) throws DataAccessException {

        //Password encryption
        String password = passwordEncoder.encode(user.getPassword());

        //1 registration
        int rowNumber = jdbc.update("INSERT INTO m_user(user_id,"
                + " password,"
                + " user_name,"
                + " birthday,"
                + " age,"
                + " marriage,"
                + " role)"
                + " VALUES(?, ?, ?, ?, ?, ?, ?)",
                user.getUserId(),
                password,
                user.getUserName(),
                user.getBirthday(),
                user.getAge(),
                user.isMarriage(),
                user.getRole());

        return rowNumber;
    }

    //Get 1 data of User table
    @Override
    public User selectOne(String userId) throws DataAccessException {

        //Get 1
        Map<String, Object> map = jdbc.queryForMap("SELECT * FROM m_user"
                + " WHERE user_id = ?", userId);

        //Variable for returning results
        User user = new User();

        //Set the acquired data in the variable for returning the result
        user.setUserId((String) map.get("user_id")); //User ID
        user.setPassword((String) map.get("password")); //password
        user.setUserName((String) map.get("user_name")); //username
        user.setBirthday((Date) map.get("birthday")); //birthday
        user.setAge((Integer) map.get("age")); //age
        user.setMarriage((Boolean) map.get("marriage")); //Marriage status
        user.setRole((String) map.get("role")); //roll

        return user;
    }

    //Get all data in User table.
    @Override
    public List<User> selectMany() throws DataAccessException {

        // M_Get all data in USER table
        List<Map<String, Object>> getList = jdbc.queryForList("SELECT * FROM m_user");

        //Variable for returning results
        List<User> userList = new ArrayList<>();

        //Store the acquired data in the result return list
        for (Map<String, Object> map : getList) {

            //Create User instance
            User user = new User();

            //Set the acquired data in the User instance
            user.setUserId((String) map.get("user_id")); //User ID
            user.setPassword((String) map.get("password")); //password
            user.setUserName((String) map.get("user_name")); //username
            user.setBirthday((Date) map.get("birthday")); //birthday
            user.setAge((Integer) map.get("age")); //age
            user.setMarriage((Boolean) map.get("marriage")); //Marriage status
            user.setRole((String) map.get("role")); //roll

            //Add to List for returning results
            userList.add(user);
        }

        return userList;
    }

    //Update 1 User table.
    @Override
    public int updateOne(User user) throws DataAccessException {

        //Password encryption
        String password = passwordEncoder.encode(user.getPassword());

        //1 update
        int rowNumber = jdbc.update("UPDATE M_USER"
                + " SET"
                + " password = ?,"
                + " user_name = ?,"
                + " birthday = ?,"
                + " age = ?,"
                + " marriage = ?"
                + " WHERE user_id = ?",
                password,
                user.getUserName(),
                user.getBirthday(),
                user.getAge(),
                user.isMarriage(),
                user.getUserId());

        return rowNumber;
    }

    //Delete 1 User table.
    @Override
    public int deleteOne(String userId) throws DataAccessException {

        //Delete 1
        int rowNumber = jdbc.update("DELETE FROM m_user WHERE user_id = ?", userId);

        return rowNumber;
    }

    //Save the SQL acquisition result as CSV on the server
    @Override
    public void userCsvOut() throws DataAccessException {

        // M_SQL to get all data of USER table
        String sql = "SELECT * FROM m_user";

        //Generate ResultSetExtractor
        UserRowCallbackHandler handler = new UserRowCallbackHandler();

        //SQL execution & CSV output
        jdbc.query(sql, handler);
    }
}

Create sql to be executed at data startup

data.sql



/*User master data (ADMIN authority)*/
INSERT INTO m_user (user_id, password, user_name, birthday, age, marriage, role)
VALUES('[email protected]', '$2a$10$xRTXvpMWly0oGiu65WZlm.3YL95LGVV2ASFjDhe6WF4.Qji1huIPa', 'Yamada Jakumada', '1990-01-01', 28, false, 'ROLE_ADMIN');

/*User master data (general authority)*/
INSERT INTO m_user (user_id, password, user_name, birthday, age, marriage, role)
VALUES('[email protected]', '$2a$10$xRTXvpMWly0oGiu65WZlm.3YL95LGVV2ASFjDhe6WF4.Qji1huIPa', 'Sato sugar', '1999-01-01', 21, false, 'ROLE_GENERAL');

Start up and check the login screen!

pass1.png

pass2.png

Recommended Posts

[Java / Spring Boot] Spring security ④ --Implementation of login process
[Java / Spring Boot] Spring security ⑤ --Implementation of logout processing
Spring Boot + Java + GitHub authentication login
Login function implementation by Spring Security (securityConfig)
[FCM] Implementation of message transmission using FCM + Spring boot
[JQuery] Implementation procedure of AutoComplete function [Java / Spring]
Part 2: Understand (roughly) the process flow of OAuth 2.0 Login supported by Spring Security 5
Part 3: Understand (deeply) the process flow of OAuth 2.0 Login supported by Spring Security 5
SNS login with Spring Boot
[Java] Implementation of Faistel Network
[Java] Thymeleaf Basic (Spring Boot)
Login function with Spring Security
CICS-Run Java application-(4) Spring Boot application
Implementation of gzip in java
Try using Spring Boot Security
[Java] [Spring] Spring Boot 1.4-> 1.2 Downgrade Note
Implementation of tri-tree in Java
Login with HttpServletRequest # login in Spring Security of Servlet 3.x environment
Memorandum of understanding when Spring Boot 1.5.10 → Spring Boot 2.0.0
Spring Boot Tutorial Using Spring Security Authentication
Elastic Beanstalk (Java) + Spring Boot + https
Java --Jersey Framework vs Spring Boot
Going out of message (Spring boot)
[Java] Input to stdin of Process
[Spring Boot] Role of each class
[Java] LINE integration with Spring Boot
Implementation of like function in Java
I implemented an OAuth client with Spring Boot / Security (LINE login)
Part 4: Customize the behavior of OAuth 2.0 Login supported by Spring Security 5
Part 1: Try using OAuth 2.0 Login supported by Spring Security 5 with Spring Boot
Implementation of clone method for Java Record
Implementation of DBlayer in Java (RDB, MySQL)
How to read Body of Request multiple times with Spring Boot + Spring Security
After 3 months of Java and Spring training
Spring Boot @WebMvcTest test enables Spring Security default security
Spring Boot + Docker Java development environment construction
WebMvcConfigurer Memorandum of Understanding for Spring Boot 2.0 (Spring 5)
Spring Java
Features of spring framework for java developers
[Java] [Spring] Test the behavior of the logger
Achieve BASIC authentication with Spring Boot + Spring Security
Implementation of Ruby on Rails login function (Session)
Summary of what I learned about Spring Boot
Hash passwords with Spring Boot + Spring Security (with salt, with stretching)
Do you need a memory-aware implementation of Java?
The story of raising Spring Boot 1.5 series to 2.1 series
Try LDAP authentication with Spring Security (Spring Boot) + OpenLDAP
Let's check the feel of Spring Boot + Swagger 2.0
Various correspondence table of Spring Framework and Spring Boot
Try to implement login function with Spring Boot
When @Transactional of Spring Boot does not work
Java tips-Create a Spring Boot project in Gradle
[Java] Hello World with Java 14 x Spring Boot 2.3 x JUnit 5 ~
[Java] Article to add validation with Spring Boot 2.3.1.
LINE Bot x Java (Spring Boot) construction procedure
[Introduction to Spring Boot] Authentication function with Spring Security
[Verification] Comparison of Spring Boot vs Micronaut boot speed
Create Spring Cloud Config Server with security with Spring Boot 2.0
Challenge Spring Boot
Implementation of GKAccessPoint
Java check process