ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Springboot] 인증(Authentication)과 인가(Authorization) 구분하기!
    Server/Spring Boot 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
    반응형

    댓글

Designed by Tistory.