
| 개념 | 설명 |
|---|---|
| 인증 (Authentication) | "누군가?"를 확인하는 절차 – 로그인을 통해 사용자 신원을 확인 |
| 권한 (Authorization) | "권한이 있는가?"를 확인 – 특정 리소스/기능 접근 여부 결정 |
AuthenticationManager)Authentication 저장Principal, @AuthenticationPrincipal)@PreAuthorize, hasRole() 등으로 제어| 구성 요소 | 설명 |
|---|---|
UserDetails | 사용자 정보 객체 |
UserDetailsService | 사용자 정보 조회 로직 |
AuthenticationManager | 인증 처리기 |
SecurityFilterChain | 보안 필터 정의 |
GrantedAuthority | 권한 정보 (ex: ROLE_ADMIN) |
SecurityContextHolder | 현재 로그인 정보 보관소 |
| 인증 방식 | 설명 |
|---|---|
| 폼 로그인 | 아이디/비밀번호 입력 (전통적인 방식) |
| JWT 토큰 | 토큰 기반 인증 (무상태 인증, REST API에 적합) |
| OAuth2 | 구글, 카카오 등 소셜 로그인 |
| Session 기반 인증 | 로그인 시 세션 생성 → 서버에서 상태 관리 |
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(username, password);
Authentication authentication = authManager.authenticate(authToken);
// 인증 성공 시 SecuritContext에 저장
SecurityContextHolder.getContext().setAuthentication(authentication);
서비스에서:
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) {
// 관리자만 접근 가능
}
또는 컨트롤러에서:
@GetMapping("/admin")
@Secured("ROLE_ADMIN")
public String adminPage() {
return "admin";
}
| 항목 | @PreAuthorize | @Secured |
|---|---|---|
| 표현 방식 | SpEL (표현식) 사용 | 단순 문자열만 지원 |
| 유연성 | 매우 높음 (조건문, 파라미터 참조 가능) | 낮음 (역할 체크만 가능) |
| 위치 추천 | 서비스 계층 (권한 제어 핵심) | 컨트롤러에 많이 쓰임 |
| 스프링 설정 필요 | @EnableMethodSecurity(prePostEnabled = true) | @EnableMethodSecurity(securedEnabled = true) |
| 실무 사용률 | ✅ 많이 씀 | 서포트용, 제한적 |
🔹 @Secured (권한 이름만 확인 가능)
@Secured("ROLE_ADMIN")
@GetMapping("/admin")
public String adminPage() {
return "admin";
}
✅ 간단하고 직관적
❌ "자기 자신만 수정 가능" 같은 조건은 표현 불가
🔹@PreAuthorize (SpEL 표현식 가능)
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin")
public String adminPage() {
return "admin";
}
@PreAuthorize("#userId == authentication.principal.id")
public void updateUser(Long userId) {
// 본인만 접근 가능
}
✅ userId 같은 파라미터 접근 가능
✅ 복잡한 조건 표현 가능
💥 실무에서는 이게 훨씬 많이 씀
// 인증된 사용자 정보 생성 시 부여된 권한
UserDetails user = User.builder()
.username("admin")
.password(passwordEncoder.encode("1234"))
.roles("ADMIN") // Spring이 내부적으로 "ROLE_ADMIN"으로 바꿈
.build();
// 권한 체크는 아래처럼
@PreAuthorize("hasRole('ADMIN')") // OK
@PreAuthorize("hasAuthority('ROLE_ADMIN')") // OK
@Secured("ROLE_ADMIN") // OK