“이 사용자가 이 URL에 접근할 수 있는가?”를 판단한다.

전체 흐름

*[Client 요청]
   ↓
Authorization: Bearer <Access Token>
   ↓
Security Filter Chain 진입
   ↓
	JWT Authentication Filter (인증) ← 수동 배치    
   └ Access Token 검증 (서명 + 만료)
   └ Claim 파싱 (sub, role, exp)
   └ Authentication 객체 생성 (UsernamePasswordAuthenticationToken)
   └ SecurityContextHolder에 저장
   ↓
	AuthorizationFilter(인가) ← Spring 자동 배치              
   └ SecurityContext에서 Authentication 조회
   └ 요청 URL / Method 기준 권한 판단
   └ 권한 없으면 → 403 Forbidden                                                                                         
   ↓
[Controller 진입]
   └ @AuthenticationPrincipal로 userId 사용 가능*                                                                         

SecurityConfig 설정 = AuthorizationFilter의 판단 기준

  .authorizeHttpRequests(auth -> auth                                                                                      
      .requestMatchers("/api/auth/**").permitAll()       // 규칙 1                                                         
      .requestMatchers("/api/admin/**").hasRole("ADMIN") // 규칙 2                                                         
      .anyRequest().authenticated()                       // 규칙 3                                                        
  )      

AuthorizationFilter 내부 동작

  *// 우리가 작성 안 해도 Spring이 이렇게 동작                                                                              
  public void doFilter(...) {                                                                                              
      // 1. 인증 정보 가져오기                                                                                             
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();                                        
                                                                                                                           
      // 2. 요청 URL 확인                                                                                                  
      String url = request.getRequestURI();                                                                                
                                                                                                                           
      // 3. 설정과 비교                                                                                                    
      if (url.startsWith("/api/auth/")) {                                                                                  
          // permitAll → 통과                                                                                              
      } else if (url.startsWith("/api/admin/")) {                                                                          
          if (auth.hasRole("ADMIN")) {                                                                                     
              // 통과                                                                                                      
          } else {                                                                                                         
              // 403 Forbidden                                                                                             
          }                                                                                                                
      } else {                                                                                                             
          if (auth != null) {                                                                                              
              // 통과                                                                                                      
          } else {                                                                                                         
              // 401 Unauthorized                                                                                          
          }                                                                                                                
      }                                                                                                                    
                                                                                                                           
      filterChain.doFilter(request, response);                                                                             
  }*     

인가 옵션 설정 예시

  *.authorizeHttpRequests(auth -> auth                                                                                      
      .requestMatchers("/public/**").permitAll()           // 누구나                                                       
      .requestMatchers("/user/**").hasRole("USER")         // USER 권한                                                    
      .requestMatchers("/admin/**").hasRole("ADMIN")       // ADMIN 권한                                                   
      .requestMatchers("/api/**").hasAnyRole("USER", "ADMIN")  // 둘 중 하나                                               
      .requestMatchers(HttpMethod.GET, "/posts/**").permitAll() // GET만 허용                                              
      .requestMatchers(HttpMethod.POST, "/posts/**").authenticated() // POST는 인증                                        
      .anyRequest().authenticated()                        // 나머지는 인증 필요                                           
  )*     

커스텀 인가가 필요한 경우

  *@PreAuthorize("hasRole('ADMIN')")                                                                                        
  public void deleteUser() { ... }                                                                                         
                                                                                                                           
  @PreAuthorize("#userId == authentication.principal")                                                                     
  public void updateProfile(Long userId) { ... }  // 본인만 수정 가능*