티스토리 뷰
반응형
Spring Boot + Spring Security 환경에서 표준 방식으로 로그인 기능을 구현하는 방법을 설명합니다.
1. 개발 환경
| 항목 | 버전 |
|---|---|
| Java | 17 이상 |
| Spring Boot | 3.x |
| Spring Security | 6.x |
| DB | MariaDB / MySQL |
| Build Tool | Gradle |
2. 로그인 구조
Client Browser
↓
HTTPS 요청
↓
Spring Security Filter
↓
AuthenticationManager
↓
UserDetailsService
↓
DB 사용자 조회
↓
BCrypt 비밀번호 검증
↓
인증 성공 / 실패
3. 의존성 추가
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
testImplementation 'org.springframework.security:spring-security-test'
}
4. 사용자 테이블 생성
users 테이블
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role VARCHAR(50) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
5. 비밀번호 암호화 방식
Spring Security에서는 기본적으로 BCryptPasswordEncoder 사용을 권장합니다.
- 단방향 해시
- Salt 자동 적용
- Rainbow Table 공격 방어
- 권장 Cost Factor 적용 가능
암호화 예제
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
회원가입 시 암호화 저장
String encodedPassword = passwordEncoder.encode(rawPassword);
6. Entity 생성
User Entity
@Entity
@Table(name = "users")
@Getter
@Setter
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String role;
}
7. Repository 생성
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}
8. UserDetailsService 구현
Spring Security 인증 과정에서 사용자 정보를 조회하는 핵심 클래스입니다.
@Service
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() ->
new UsernameNotFoundException("사용자 없음"));
return org.springframework.security.core.userdetails.User
.builder()
.username(user.getUsername())
.password(user.getPassword())
.roles(user.getRole())
.build();
}
}
9. Security 설정
SecurityConfig.java
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http)
throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers(
"/",
"/login",
"/join"
).permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login")
.loginProcessingUrl("/login-process")
.defaultSuccessUrl("/main", true)
.failureUrl("/login?error=true")
.permitAll()
)
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/")
);
return http.build();
}
}
10. 로그인 Controller
@Controller
public class LoginController {
@GetMapping("/login")
public String loginPage() {
return "login";
}
@GetMapping("/main")
public String mainPage() {
return "main";
}
}
반응형
11. 로그인 화면 구현
login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
</head>
<body>
<h2>로그인</h2>
<form method="post" action="/login-process">
<div>
<input type="text"
name="username"
placeholder="아이디">
</div>
<div>
<input type="password"
name="password"
placeholder="비밀번호">
</div>
<button type="submit">로그인</button>
</form>
</body>
</html>
12. HTTPS 통신 암호화
로그인 기능에서는 반드시 HTTPS 사용이 권장됩니다. 비밀번호는 TLS 암호화 채널을 통해 전송되어야 합니다.
HTTPS 적용 이유
- 비밀번호 평문 탈취 방지
- 세션 하이재킹 방어
- MITM 공격 방지
- 쿠키 탈취 방지
application.yml 설정
server:
ssl:
enabled: true
key-store: classpath:keystore.p12
key-store-password: password
key-store-type: PKCS12
13. 세션 보안 설정
권장 설정
http
.sessionManagement(session -> session
.sessionFixation().migrateSession()
.maximumSessions(1)
);
- 세션 고정 공격(Session Fixation) 방어
- 중복 로그인 제한
14. CSRF 방어
운영 환경에서는 CSRF 비활성화보다 활성화를 권장합니다.
기본 사용 예제
http.csrf(Customizer.withDefaults());
15. 보안 권장 사항
| 항목 | 설명 |
|---|---|
| BCrypt 사용 | 비밀번호 단방향 암호화 |
| HTTPS 사용 | 통신 구간 암호화 |
| CSRF 방어 | 위조 요청 방어 |
| 세션 고정 방어 | 인증 세션 탈취 방어 |
| XSS 방어 | 출력값 Escape 처리 |
| 로그인 실패 제한 | Brute Force 공격 방어 |
| 보안 헤더 적용 | CSP, HSTS, X-Frame-Options |
16. 보안 헤더 적용
http
.headers(headers -> headers
.httpStrictTransportSecurity(hsts ->
hsts.includeSubDomains(true)
)
.frameOptions(frame ->
frame.sameOrigin()
)
);
17. 로그인 성공 흐름
1. 사용자가 ID/PW 입력
2. HTTPS 전송
3. Spring Security 인증 처리
4. BCrypt 해시 비교
5. 인증 성공
6. SecurityContext 저장
7. Session 생성
8. 메인 페이지 이동
참고 공식 문서
- Spring Boot Official Docs
https://spring.io/projects/spring-boot - Spring Security Reference
https://docs.spring.io/spring-security/reference/index.html
#SpringBoot
#SpringSecurity
#SpringBootLogin
#JavaLogin
#SpringBootSecurity
#HTTPS
#BCrypt
#SpringAuthentication
#LoginSecurity
#CSRF
#SessionSecurity
#JavaWebSecurity
#SpringBootTutorial
#OAuth2
#JWT
'Java' 카테고리의 다른 글
| java substring 함수(문자열 자르기) 사용법 및 예제 코드 (0) | 2026.05.15 |
|---|---|
| JAVA Session Life Cycle 세션 생명주기 내용 정리 (0) | 2026.05.11 |
| JAVA 함수 실행시간 측정 currentTimeMillis(), nanoTime() 사용법 (0) | 2026.05.10 |
| facebook graph api로 게시글 가져오기 (1) | 2019.09.23 |
| 구글, 파파고 번역 API 성능 비교 (1) | 2019.09.18 |
| google translate api v3 사용법 (1) | 2019.09.16 |
| java spring pwa fcm web push 구현 (2) | 2019.09.10 |
| Object 클래스에 대해 (0) | 2018.11.04 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 데이터베이스
- 아두이노
- C
- html
- c#
- 문제풀이
- OpenCV
- Class
- 배열
- 문자열
- 알고리즘
- 클래스
- 리스트
- 파일처리
- String
- 블루투스
- 파이썬
- 정보처리기사
- DB연동
- 자바
- C언어
- C++ 클래스
- Java
- 안드로이드
- 상속
- MySQL
- C++
- Android
- 자료구조
- 벡터
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
글 보관함
반응형
