[JAVA] Login function implementation by Spring Security (securityConfig)

Implementation of login authentication function using Spring Security (securityConfig)

procedure

  1. Add to pom.xml
  2. Creating a securityConfig class 3.UserDetailsServiceImpl: Create service class
  3. Create LoginUser domain
  4. Create Repository class for user

1. Add to pom.xml

Add the following two inside the tag

pom.xml



		<!-- Spring Security -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-springsecurity5</artifactId>
		</dependency>

2. Creating a securityConfig class

securityConfig.java



//import omitted

@Configuration //Class for configuration
@EnableWebSecurity //Take advantage of Spring Security's web features
public class SecurityConfig extends WebSecurityConfigurerAdapter {


	@Autowired
	private UserDetailsService memberDetailsService;

	/**
	 *By overriding this method
	 *"Security settings" for specific requests
	 *You can make settings related to the whole, such as settings to ignore.
	 *Specifically, disable the security settings for static resources.
	 * 
	 * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.WebSecurity)
	 */
	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring()
			.antMatchers( "/css/**"
						, "/img/**"
						, "/js/**"
						, "/fonts/**");
	}

	/**
	 *By overriding this method, authorization settings and login/You can make settings related to logout.
	 * 
	 * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
	 */
	@Override
	protected void configure(HttpSecurity http) throws Exception {

		http.authorizeRequests() //Authorization settings
			.antMatchers("/","/login","/excuteLogin","/login/register").permitAll() //「/Allow all users to pass such as
			.antMatchers().hasRole("ADMIN") // /admin/Paths starting with can only be accessed if you are logged in with ADMIN privileges("ROLE" when setting authority_Specify the character string excluding "")
            .antMatchers().hasRole("USER")
			//.antMatchers("/admin/**").hasRole("ADMIN") // /admin/Paths starting with can only be accessed if you are logged in with ADMIN privileges("ROLE" when setting authority_Specify the character string excluding "")
			//.antMatchers("/user/**").hasRole("USER") // /user/Paths starting with can only be accessed if you are logged in with USER privileges("ROLE" when setting authority_Specify the character string excluding "")
			.anyRequest().authenticated(); //Other paths require authentication

		http.formLogin() //Login settings
			.loginPage("/login") //Path to transition to login screen(If you specify a path that requires login authentication and you are not logged in, you will be transitioned to this path.)
			.loginProcessingUrl("/excuteLogin") //Path to transition when the login button is pressed(If you transition to here, you will be logged in automatically.)
			.failureUrl("/login?error=true") //Path to transition to login failure
			.defaultSuccessUrl("/", true) //1st argument:By default, the path to transition when login is successful
			                                        //2nd argument: true :Always transition to the path of the first argument after authentication
			                                        //         false:Even if you are not authenticated and you are skipped to the login screen once, when you log in, you will be transferred to the specified URL
			.usernameParameter("email") //Request parameter name of the user name used during authentication(This time I use my email address)
			.passwordParameter("password"); //Request parameter name of password used for authentication
		
		http.logout() //Logout settings
			.logoutRequestMatcher(new AntPathRequestMatcher("/logout**")) //Path to transition when logging out
			.logoutSuccessUrl("/login") //Path to transition after logout(Set the login screen here)
			.deleteCookies("JSESSIONID") //After logging out, delete the session ID stored in the cookie
			.invalidateHttpSession(true); // true:Disable session after logout false:Do not disable the session
		
	}

	/**
	 *Settings related to "authentication".<br>
	 *Settings of "User Details Service" to acquire authenticated users<br>
	 *"Password Encoder" settings used for password verification
	 * 
	 * @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder)
	 */
	@Override
	public void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(memberDetailsService)
			.passwordEncoder(new BCryptPasswordEncoder());
	}

    /**
     * <pre>
     *Returns an implementation that is hashed with the bcrypt algorithm.
     *By specifying this, when password hashing and match confirmation
     * @Autowired
	 * private PasswordEncoder passwordEncoder;
	 *If you write, it will be DI.
     * </pre>
     * @Implementation object to be hashed with the return bcrypt algorithm
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
    		return new BCryptPasswordEncoder();
    }
}

3. Create UserDetailsServiceImpl

A service class for acquiring user information and performing login authentication based on the email address entered from the browser. The source code is as follows.

UserDetailsServiceImpl.java




@Service
public class UserDetailsServiceImpl implements UserDetailsService {
	/**Repository for getting information from DB*/

	@Autowired
	private UserRepository userRepository;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.security.core.userdetails.UserDetailsService#
	 * loadUserByUsername(java.lang.String)Search from DB, configure and return login information.
	 */
	@Override
	public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
		User user = userRepository.findByMailAddress(email);
		if (user == null) {
			throw new UsernameNotFoundException("The email is not registered.");
		}
		//Example of authorization
		Collection<GrantedAuthority> authorityList = new ArrayList<>();
		authorityList.add(new SimpleGrantedAuthority("ROLE_USER")); //Grant user privileges
//			if(member.isAdmin()) {
//				authorityList.add(new SimpleGrantedAuthority("ROLE_ADMIN")); //Grant administrator privileges
//			}
		return new LoginUser(user, authorityList);
	}	
}

4. Create LoginUser domain

LoginUser.java



/**
 *Entity that stores administrator login information.
 *
 */
public class LoginUser extends User {


	private static final long serialVersionUID = 1L;
	/**User information*/
	private final com.example.domain.User user;

	/**
	 *In addition to normal administrator information, set authorization roles.
	 * 
	 * @param Administrator Administrator information
	 * @param authorityList List containing authority information
	 */
	public LoginUser(com.example.domain.User user, Collection<GrantedAuthority> authorityList) {
		super(user.getEmail(), user.getPassword(), authorityList);
		this.user = user;
	}

	public com.example.domain.User getUser() {
		return user;
	}
}

5. Creating a UserRepository

A repository for searching users by email address. It is necessary to create a domain class for user separately, but this time it is omitted.

UserRepository.java




public class UserRepository {
	
	@Autowired
	private NamedParameterJdbcTemplate template;
	
	private static final RowMapper<User> USER_ROW_MAPPER = (rs, i) -> {
		User user = new User();
		user.setId(rs.getInt("id"));
		user.setName(rs.getString("name"));
		user.setEmail(rs.getString("email"));
		user.setPassword(rs.getString("password"));
		user.setZipcode(rs.getString("zipcode"));
		user.setAddress(rs.getString("address"));
		user.setTelephone(rs.getString("telephone"));

		return user;
	};
	
	/**
	 *Get 1 user information from your email address
	 * @param email
	 * @return List<User>
	 */
	public User findByMailAddress(String email) {
		String sql = "select id,name,email,password,zipcode,address,telephone from users where email = :email";
		
		SqlParameterSource param = new MapSqlParameterSource().addValue("email", email);
		
		List<User> userList = template.query(sql, param, USER_ROW_MAPPER);
		
		if(userList.size() == 0) {
			return null;
		}
		return userList.get(0);
	}

Note 1: When logging in with Spring Security implemented, the password information in the database must be hashed. See another article for password hashing when registering user information.

Recommended Posts

Login function implementation by Spring Security (securityConfig)
Login function with Spring Security
[Java / Spring Boot] Spring security ④ --Implementation of login process
Login function implementation with rails
Implemented authentication function with Spring Security ②
Implemented authentication function with Spring Security ③
Implemented authentication function with Spring Security ①
Part 1: Try using OAuth 2.0 Login supported by Spring Security 5 with Spring Boot
Login function
Implementation of Ruby on Rails login function (Session)
Part 2: Understand (roughly) the process flow of OAuth 2.0 Login supported by Spring Security 5
DM function implementation
Try to implement login function with Spring Boot
[JQuery] Implementation procedure of AutoComplete function [Java / Spring]
Create login / logout function with Spring Security according to Spring official guide [For beginners]
Part 3: Understand (deeply) the process flow of OAuth 2.0 Login supported by Spring Security 5
Implementation of Ruby on Rails login function (devise edition)
About Spring Security authentication
Comment function (Ajax) implementation
Follow function (Ajax) implementation
Image preview function implementation
Spring Security causes 403 forbidden
Rails search function implementation
Implementation of pagination function
With Spring boot, password is hashed and member registration & Spring security is used to implement login function.
Implement login function in Rails simply by name and password (1)
Implement login function in Rails simply by name and password (2)
[Ruby on Rails] Implement login function by add_token_to_users with API
Login with HttpServletRequest # login in Spring Security of Servlet 3.x environment