Spring Security (사용자 인증/권한)

break 없는 while loop·2025년 4월 13일
post-thumbnail

Spring Security

Java에서 사용자 인증(Authentication)권한 인가(Authorization)를 위해 주로 사용되는 Framework

✅ 핵심 개념 먼저 정리

개념설명
인증 (Authentication)"누군가?"를 확인하는 절차 – 로그인을 통해 사용자 신원을 확인
권한 (Authorization)"권한이 있는가?"를 확인 – 특정 리소스/기능 접근 여부 결정

✅ Java/Spring에서 인증/권한 처리 흐름 요약

  1. 사용자 로그인 요청
  2. Spring Security Filter가 요청 가로챔
  3. 사용자 인증 (AuthenticationManager)
  4. 성공 시 SecurityContextHolderAuthentication 저장
  5. 이후 모든 요청에서 사용자 정보 자동 접근 가능 (Principal, @AuthenticationPrincipal)
  6. 권한은 @PreAuthorize, hasRole() 등으로 제어

✅ 대표 구성 요소 (Spring Security 기준)

구성 요소설명
UserDetails사용자 정보 객체
UserDetailsService사용자 정보 조회 로직
AuthenticationManager인증 처리기
SecurityFilterChain보안 필터 정의
GrantedAuthority권한 정보 (ex: ROLE_ADMIN)
SecurityContextHolder현재 로그인 정보 보관소

✅ 인증 방식 종류

인증 방식설명
폼 로그인아이디/비밀번호 입력 (전통적인 방식)
JWT 토큰토큰 기반 인증 (무상태 인증, REST API에 적합)
OAuth2구글, 카카오 등 소셜 로그인
Session 기반 인증로그인 시 세션 생성 → 서버에서 상태 관리

✅ 실전 코드 예 (JWT 방식 기준)

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 vs @Secured (Controller vs Service)

항목@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
profile
프로그래밍 지식 아카이브용

0개의 댓글