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);
    }
}

✨ 핵심 흐름 요약

  1. 로그인 요청 (아이디/비밀번호) → 인증 (Authentication)
  2. 인증 성공 → JWT 토큰 발급
  3. 이후 요청에 토큰 포함 → 필터에서 토큰 인증 및 권한 체크인가 (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
반응형