본문 바로가기

Language/Spring Security

기본 인증 - httpBasic()

728x90
  • HTTP는 액세스 제어와 인증을 위한 프레임워크를 제공하며 가장 일반적인 방식은 “Basic” 인증 방식
  • RFC 7235표준이며 인증 프로토콜은 HTTP 인증 헤더에 기술

  1. 클라이언트는 인증 정보 없이 서버로 접속 시도
  2. 서버가 클라이언트에게 인증 요구를 보낼 때 401 Unauthorized 응답과 함께 WWW-Authenticate 헤더를 기술하여 realm(보안영역)과 Basic 인증 방법을 보냄
  3. 클라이언트가 서버로 접속할 때 Base64로 username과 password를 인코딩하고 Authorization 헤더에 담아서 요청
  4. 성공적으로 완료되면 정상적인 상태 코드를 반환
  • 주의 사항
    • base-64 인코딩된 값은 디코딩이 가능하여 인증 정보가 노출
    • HTTP Basic 인증은 반드시 HTTPS와 같이 TLS 기술과 함께 사용

httpBasic() API

  • HttpBaiscConfigurer 설정 클래스를 통해 여러 API 설정 가능
  • 내부적으로 BasicAuthenticationFilter가 생성되어 기본 인증 방식의 인증 처리 담당
http.httpBasic(httpSecurityHttpBasicConfigurer -> httpSecurityHttpBasicConfigurer
        .realmName("security")
        .authenticationEntryPoint(
                (request, response, authException) -> {})
);
  • realmName()
    • HTTP 기본 영역을 설정
  • authenticationEntryPoint()
    • 인증 실패 시 호출되는 AuthenticationEntryPoint
    • 기본값은 “Realm” 영역으로 BasicAuthenticationEntryPoint 사용

테스트 코드

@EnableWebSecurity
@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http
                .authorizeHttpRequests( auth -> auth.anyRequest().authenticated())
                .httpBasic(basic -> basic
                        .authenticationEntryPoint(new CustomAuthenticationEntryPoint())
                );

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService(){
        UserDetails user = User.withUsername("user").password("{noop}1111").roles("USER").build();
        return  new InMemoryUserDetailsManager(user);
    }

}
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                         AuthenticationException authException) throws IOException {
        response.addHeader("WWW-Authenticate", "Basic realm=localhost");
        response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
    }
}
  • localhost:8080 접속
    • 서버 → 클라이언트 = Response → WWW-Authenticate 전송

  • 로그인 성공
    • 클라이언트 → 서버 = Request   Authorization 전송

 

728x90