Server/Spring Boot
[Springboot] 인증(Authentication)과 인가(Authorization) 구분하기!
hoonylab
2025. 4. 21. 17:42
728x90
반응형
✅ 인증(Authentication)과 인가(Authorization)의 차이
📌 비유로 쉽게 이해하기
회사 건물에 출입하는 상황을 떠올려 봅시다.
- 인증(Authentication): 당신이 누구인지 확인하는 것
👉 출입문에서 사원증을 찍고 "나는 홍길동입니다" 라고 밝히는 단계입니다.
즉, 아이디와 비밀번호로 본인을 증명하는 것입니다. - 인가(Authorization): 당신이 무엇을 할 수 있는지 확인하는 것
👉 사원증을 찍었더니 5층까지는 출입 가능, 9층은 출입 불가라고 나옵니다.
즉, 인증된 사용자가 어떤 권한(Role)을 가지고 있는지에 따라 접근 제한됩니다.
🛠 Spring Boot에서 로그인과 토큰을 활용한 인증/인가 구현
📍 사용 기술
- Spring Boot
- Spring Security
- JWT (Json Web Token)
- H2 DB (테스트용)
1️⃣ 인증 단계: 로그인 API (JWT 토큰 발급)
@RestController
@RequiredArgsConstructor
public class AuthController {
private final AuthenticationManager authenticationManager;
private final JwtTokenProvider jwtTokenProvider;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())
);
String token = jwtTokenProvider.generateToken(authentication);
return ResponseEntity.ok(new JwtResponse(token));
}
}
✅ 이 단계에서 아이디/비밀번호가 유효한지 확인 → 인증 완료 → JWT 토큰 발급
2️⃣ 인가 단계: 토큰으로 요청 시 권한 확인
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN") // 인가 설정
.anyRequest().authenticated()
)
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
✅ 이 설정으로 /admin/** 경로는 ADMIN 권한이 있어야 접근 가능. 토큰이 없거나 권한이 없으면 403 Forbidden
반환.
📂 예시: 토큰 필터에서 인증 처리
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtTokenProvider jwtTokenProvider;
public JwtAuthenticationFilter(JwtTokenProvider provider) {
this.jwtTokenProvider = provider;
}
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String token = jwtTokenProvider.resolveToken(request);
if (token != null && jwtTokenProvider.validateToken(token)) {
Authentication auth = jwtTokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(request, response);
}
}
✨ 핵심 흐름 요약
- 로그인 요청 (아이디/비밀번호) → 인증 (Authentication)
- 인증 성공 → JWT 토큰 발급
- 이후 요청에 토큰 포함 → 필터에서 토큰 인증 및 권한 체크 → 인가 (Authorization)
✅ 인증 실패와 인가 실패의 HTTP 상태 코드 차이
📌 401 Unauthorized - 인증 실패
- 의미: "누군지 모르겠다"
- 상황 예시:
- 토큰 없음
- 로그인 정보(ID/PW) 틀림
- 토큰이 만료되었거나 위조됨
🔒 Spring Security에서 인증(Authentication) 실패 시 기본적으로 401
을 반환합니다.
📌 403 Forbidden - 인가 실패
- 의미: "누군지는 알겠지만, 권한이 없다"
- 상황 예시:
USER
권한 사용자가/admin
페이지에 접근하려 할 때- 토큰은 유효하지만 권한(Role)이 부족한 경우
🚫 인가(Authorization) 실패 시에는 403
이 반환됩니다.
🧠 정리 표
상황 | 상태 코드 | 의미 |
---|---|---|
인증 실패 | 401 Unauthorized |
로그인이 필요합니다 |
인가 실패 | 403 Forbidden |
당신은 접근 권한이 없습니다 |
💡 참고
Spring Boot에서는 아래 두 클래스를 통해 각각을 세밀하게 처리할 수 있습니다.
AuthenticationEntryPoint
→ 인증 실패 (401)AccessDeniedHandler
→ 인가 실패 (403)
필요에 따라 에러 메시지, 응답 포맷(JSON 등)을 커스터마이징할 수 있습니다.
💡 마무리
인증과 인가는 보안 시스템의 핵심입니다.
이를 명확히 이해하고 Spring Security와 JWT로 잘 구현하면, 안전하고 확장성 있는 백엔드 서비스를 만들 수 있습니다.
728x90
반응형