Spring Security 이용하여 로그인 처리 - 1편(로그인 페이지 틀)
Spring Security Dependency 추가하기
https://spring.io/guides/gs/securing-web/
Securing a Web Application
this guide is designed to get you productive as quickly as possible and using the latest Spring project releases and techniques as recommended by the Spring team
spring.io
위 링크에 접속 후 dependency 부분을 복사합니다.
- pom.xml
pom.xml 안에 dependency를 추가합니다.
추가 후 Maven으로 다시 로드를 합니다. (확실히 적용시켜 줍니다.)
Config 설정하기
config 패키지를 추가한 후 WebSecurityConfig 클래스를 생성합니다.
https://spring.io/guides/gs/securing-web/
Securing a Web Application
this guide is designed to get you productive as quickly as possible and using the latest Spring project releases and techniques as recommended by the Spring team
spring.io
위의 링크를 통해 Copy 클릭 후 코드를 복사합니다.
새로만든 WebSecurityConfig 클래스에 붙여넣습니다. (이때, 맨 윗줄의 패키지는 자신이 처음에 만든 패키지로 설정합니다.)
package com.example.layout.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((requests) -> requests
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
)
.formLogin((form) -> form
.loginPage("/login")
.permitAll()
)
.logout((logout) -> logout.permitAll());
return http.build();
}
}
MariaDB 설정하면서 user, password는 설정이 되어있기에 제거하였습니다.
/home 부분이 없기에 home 부분도 제거하였습니다.
HeidiSQL에 사용자 테이블 생성 및 연결하기
HeidiSQL 안에 id, username, password, enabled 4개 행을 추가하여 위와같이 생성합니다.
https://www.baeldung.com/spring-security-jdbc-authentication
4.3 부분을 복사합니다.
WebSecurityConfig 클래스 안에 @Bean 아래 부분에 붙여넣습니다.
- dataSource 처리하기
@Autowired 이용하여 dataSource 추가합니다.
- passwordEncoder 설정하기
맨 아래 부분에 추가한 후 .passwordEncoder로 넘겨줍니다.
- role 테이블 추가하기
권한을 나타내는 테이블로 id, name 행을 추가합니다.
※ 참고사항
1 대 1 매핑 : @oneToone
예) user - user_detail
1 대 다 매핑 : @oneTomany
예) user - board(게시글)
다 대 1 매핑 : @manyToone
예) board -user
다 대 다 매핑 : @manyTomany
예) user - role
- user_role 테이블 생성하기
user_id, role_id 행을 추가하고, 외래키까지 설정합니다.
위와같이 inner join 이용하여 테이블끼리 조인합니다.
WebSecurityConfig 중간점검 코드
package com.example.layout.config;
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.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import javax.sql.DataSource;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Autowired
private DataSource dataSource;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((requests) -> requests
.antMatchers("/", "/starter-template.css").permitAll()
.anyRequest().authenticated()
)
.formLogin((form) -> form
.loginPage("/login")
.permitAll()
)
.logout((logout) -> logout.permitAll());
return http.build();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder())
.usersByUsernameQuery("select username,password,enabled "
+ "from user "
+ "where username = ?")
.authoritiesByUsernameQuery("select username, name "
+ "from user_role ur inner join user u on ur.user_id = u.id "
+ "inner join role r on ur.role_id = r.id "
+ "where email = ?");
}
@Bean
static PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
모든 과정을 거치고 실행을 해보면 2가지 문제점이 있는데 다음과같이 해결합니다.
1) css 파일 접근권한이 없어 레이아웃이 정리가 안된 것처럼 보입니다.
starter-template.css 추가합니다.
2) passwordEncoder 부분을 public → static으로 선언합니다.
CSS파일 한꺼번에 정리하여 접근권한 부여하기
static 하위폴더에 css 폴더를 생성한 후 css 파일들을 넣습니다.
/starter-template.css → /css/** 수정합니다.
- common.html
/starter-template.css → /css/starter-template.css 수정합니다.
로그인 페이지 만들기
templates → account → login.html 생성합니다.
※ account 폴더 생성, login.html 생성합니다.
login.html은 index.html 파일을 그대로 복사한 후 조금씩 수정합니다.
https://getbootstrap.com/docs/4.6/examples/sign-in/
Signin Template · Bootstrap v4.6
getbootstrap.com
우클릭 후 "페이지 소스 보기" 클릭합니다.
위 부분을 복사합니다.
body 부분에 붙여넣습니다.
link 부분을 변경합니다.
- signin.css
static → css → signin.css 생성합니다.
signin.css 클릭합니다.
복사합니다.
붙여넣습니다.
WebSecurityConfig 클래스에 loginpage를 /login → /account/login 경로로 변경합니다.
AccountController 생성하기
controller → AccountController 클래스를 생성합니다.
- AccountController
package com.example.layout.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/account")
public class AccountController {
@GetMapping("/login")
public String login(){
return "account/login";
}
}
위 코드를 붙여넣습니다.
※ 이미지 보이게 하기
그림에 우클릭 후 "이미지 주소 복사" 클릭합니다.
- login.html
블록씌운 부분에 붙여넣습니다.
- login.html
이메일이 아닌 username 사용하므로 username으로 수정합니다.
Remember me는 주석처리합니다. (단축키 : ctrl + "/")
로그인 페이지 중간점검
정상적으로 실행되고 있음을 확인할 수 있습니다.
참고자료
https://www.youtube.com/watch?v=0JHIME7uGOk&list=PLPtc9qD1979DG675XufGs0-gBeb2mrona&index=9
Bootstrap
Powerful, extensible, and feature-packed frontend toolkit. Build and customize with Sass, utilize prebuilt grid system and components, and bring projects to life with powerful JavaScript plugins.
getbootstrap.com
Spring makes Java simple.
Level up your Java code and explore what Spring can do for you.
spring.io