인프런/스프링 시큐리티 완전 정복 [6.x 개정판]

4) 인증프로세스 - 폼 인증,폼 인증 필터, HTTP Basic 인증

backend dev 2024. 10. 8.

폼 인증

 

• HTTP 기반의 폼 로그인 인증 메커니즘을 활성화하는 API 로서

사용자 인증을 위한 사용자 정의 로그인 페이지를 쉽게 구현할 수 있다

 

• 기본적으로 스프링 시큐리티가 제공하는 기본 로그인 페이지를 사용하며

사용자 이름과 비밀번호 필드가 포함된 간단한 로그인 양식을 제공한다

 

• 사용자는 웹 폼을 통해 자격 증명(사용자 이름과 비밀번호)을 제공하고

Spring Security는 HttpServletRequest에서 이 값을 읽어 온다

 

 

 

클라이언트가 아직 접근 인증을 받지 못했다면 접근 예외가 발생하고 예외 처리 필터로 인해 인증이 시작되면서 로그인 페이지로 리다이렉트 된다.

 

formLogin() API

[메소드를 API라고 칭하는 이유는 이 메서드들이 Spring Security의 내부 기능에 접근할 수 있는 인터페이스 역할을 하기 때문인거같다. 내가 아는 일반적인 API는 아님.]

 

FormLoginConfigurer 설정 클래스를 통해 여러 API 들을 설정할 수 있다

 

• 내부적으로 UsernamePasswordAuthenticationFilter 가 생성되어 폼 방식의 인증 처리를 담당하게 된다

 

 

 

예시코드

package com.example.security_inflearn;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.IOException;


@EnableWebSecurity
@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, HttpSecurity httpSecurity) throws Exception{
        http.authorizeHttpRequests(auth-> auth.anyRequest().authenticated())
                .formLogin(form -> form  // formLoginConfigurer를 받아서 설정
                        .loginPage("/loginPage")
                        .loginProcessingUrl("/loginProc")
                        .defaultSuccessUrl("/",true)
                        .failureUrl("/failed")
                        .usernameParameter("userId") // form 형식에서 넘어오는 유저아이디 input 파라미터이름 설정
                        .passwordParameter("passwd")
                        .successHandler(new AuthenticationSuccessHandler() { // 성공 핸들러 익명클래스 구현
                            @Override
                            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                                System.out.println("authentication = " + authentication);
                                response.sendRedirect("/home");
                            }
                        })// 익명클래스 구현시 람다로도 가능하다. 실패 핸들러는 Authentication 대신 예외가 넘어온다.
                        .failureHandler(((request, response, exception) -> {
                            System.out.println("exception = " + exception);
                            response.sendRedirect("/login");
                        }))
                        .permitAll()
                );

        return http.build();
    }

    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
        UserDetails user = User.withUsername("user")
                .password("{noop}1234")
                .authorities("ROLE_USER")
                .build();
        UserDetails user2 = User.withUsername("user2")
                .password("{noop}1234")
                .authorities("ROLE_USER")
                .build();
        UserDetails user3 = User.withUsername("user3")
                .password("{noop}1234")
                .authorities("ROLE_USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }

}

 

테스트용 API추가

@GetMapping("/home")
public String home() {
    return "home";
}

@GetMapping("/loginPage")
public String loginPage() {
    return "loginPage";
}

 

localhost:8080 접근시 설정한 로그인 페이지 url로 request 되는것을 확인가능

 

.loginPage() 설정을 주석처리하고 다시 로그인해보면 [ spring security 기본 로그인폼 페이지를 사용하면]

설정한 로그인처리 url를 request하는것을 확인가능

form에서 전달되는 파라미터명이 설정한대로 넘어오는것을 확인가능

로그인 후 요청되는 url이 .defaultSuccessUrl("/",true)의 설정을 따르는것을 확인가능

[현재 성공핸들러,실패핸들러 설정을 주석처리해둠 ]

 

usernameParameter() ,passwordParameter() 설정한대로 spring security가 파라미터 명 설정을 해준다.

 

 

defaultSuccessUrl("/",false)

다음과 같이 두번째 매개변수를 false 로 둔다면

인증 성공시 인증 요청된 페이지로 돌아가게 된다.

 

[인증 전에 보안이 필요한 페이지를 방문하다가 인증에 성공한 경우이면 이전 위치로 리다이렉트 됨]

 

로그인하기전에 http://localhost:8080/home 해당 url 요청하면 로그인페이지로 이동되는데 그때 로그인을 성공하게 되면 

다음과 같이 요청한 url로 리다이렉트 되게된다.

 

.failureUrl("/failed")

실패시 설정한 url로 request된다.

 

 

하지만 

.successHandler(new AuthenticationSuccessHandler() { // 성공 핸들러 익명클래스 구현
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        System.out.println("authentication = " + authentication);
        response.sendRedirect("/home");
    }
})// 익명클래스 구현시 람다로도 가능하다. 실패 핸들러는 Authentication 대신 예외가 넘어온다.
.failureHandler(((request, response, exception) -> {
    System.out.println("exception = " + exception);
    response.sendRedirect("/login");
}))

성공 핸들러, 실패 핸들러를 설정한다면

 

.defaultSuccessUrl("/",false)
.failureUrl("/failed")

위의 설정은 무시된다. [ 핸들러 설정이 우선시 된다.]

 

성공핸들러로 인해 /home으로 리다이렉트된 모습
로그인 실패시, 실패 핸들러로 인해 /login으로 리다이렉트 된다.

 

authentication = UsernamePasswordAuthenticationToken [Principal=org.springframework.security.core.userdetails.User [Username=user, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, CredentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[ROLE_USER]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=E04F2616029E67A0A8A40CACBD4920FE], Granted Authorities=[ROLE_USER]]
exception = org.springframework.security.authentication.BadCredentialsException: 자격 증명에 실패하였습니다.

성공했을때 authentication 객체를 출력해본 결과와

실패시 exception 객체를 출력해본 결과이다.

 

 

public final class FormLoginConfigurer<H extends HttpSecurityBuilder<H>> extends
       AbstractAuthenticationFilterConfigurer<H, FormLoginConfigurer<H>, UsernamePasswordAuthenticationFilter> {

해당 클래스를 이용해서 formLogin 설정을 진행하는것이다.

 


 

폼 인증 필터 - UsernamePasswordAuthenticationFilter

 

• 스프링 시큐리티는 AbstractAuthenticationProcessingFilter 클래스를 사용자의 자격 증명을 인증하는 기본 필터로 사용 한다

 

UsernamePasswordAuthenticationFilterAbstractAuthenticationProcessingFilter 를 확장한 클래스로서 HttpServletRequest 에서 제출된 사용자 이름과 비밀번호로부터 인증을 수행한다

 

• 인증 프로세스가 초기화 될 때 로그인 페이지와 로그아웃 페이지 생성을 위한 DefaultLoginPageGeneratingFilterDefaultLogoutPageGeneratingFilter 가 초기화 된다

 

AbstractAuthenticationProcessingFilter 를 이용하여 인증처리를 진행한다. [ login같은]

 

그때 AbstractAuthenticationProcessingFilter의

스프링 security 기본제공 구현체인 UsernamePasswordAuthenticationFilter가 사용될수도있고

사용자가 등록한 CustomAuthenticationFilter가 사용될 수 있다. 

 

Filter를 적용할지 말지 RequestMatcher를 통해 url 검증을 진행해서 filter를 적용해야하는 request라면 인증 진행

필터는 아이디,패스워드를 UsernamePasswordAuthenticationToken에  저장하고 Token을 AuthenticationManager로 전달하고 그걸로 인증 진행 

인증에 성공했어도 UsernamePasswordAuthenticationToken를 다시 만들어서

UserDetails [또는 User]  , Authorities를 담아준다.

[인증에 성공한 사용자에 대한 정보, 권한등을 담아주는 작업 ] 

 

인증에 성공한 사용자 정보,인증정보를 담고있는 UsernamePasswordAuthenticationToken객체를

SecurityContext에 설정[저장]한다.

[UsernamePasswordAuthenticationToken는 Authentication의 구현체이다.]

 

SecurityContext에 대해 [ claude]

 

SecurityContext는 Spring Security의 핵심 컴포넌트 중 하나입니다. 이에 대해 자세히 설명드리겠습니다:

1. 정의:
   SecurityContext는 현재 애플리케이션의 보안 컨텍스트에 대한 정보를 보유합니다. 주로 현재 인증된 사용자의 세부 정보를 저장합니다.

2. 주요 역할:
   - 현재 인증된 사용자의 정보(Authentication 객체)를 저장합니다.
   - 애플리케이션 전반에 걸쳐 현재 사용자의 보안 정보에 접근할 수 있게 해줍니다.

3. 저장 정보:
   - 주로 Authentication 객체를 저장합니다. 이 객체는 사용자의 인증 정보, 권한 등을 포함합니다.

4. 사용 방법:
   - SecurityContextHolder를 통해 접근할 수 있습니다.
   - 예: `SecurityContextHolder.getContext().getAuthentication()`

5. 생명주기:
   - 기본적으로 ThreadLocal에 저장되어 요청별로 관리됩니다.
   - HTTP 요청이 처리되는 동안 유지되며, 요청 처리가 완료되면 정리됩니다.

6. 보안 중요성:
   - 현재 사용자의 보안 정보를 안전하게 보관하고 접근할 수 있게 해주는 중요한 메커니즘입니다.

7. 사용 예시:
   java

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
String username = authentication.getName();


   
8. 커스터마이징:
   - SecurityContextHolder의 전략을 변경하여 SecurityContext의 저장 방식을 커스터마이즈할 수 있습니다.

9. 멀티스레드 환경:
   - 기본적으로 ThreadLocal을 사용하므로 멀티스레드 환경에서 안전합니다.

10. 인증 후 처리:
    - 성공적인 인증 후, AuthenticationManager는 새로운 Authentication 객체를 SecurityContext에 설정합니다.

SecurityContext는 Spring Security의 핵심 개념 중 하나로, 애플리케이션의 보안 상태를 관리하고 현재 인증된 사용자의 정보를 안전하게 보관하는 중요한 역할을 합니다. 이를 통해 애플리케이션의 어느 부분에서든 현재 사용자의 인증 정보와 권한을 쉽게 확인하고 사용할 수 있습니다.


 

그리고

세션에 SecurityContext가 저장된다.

 


Spring Security의 인증 과정[ claude]


1. 인증 요청 시작:
   - 사용자가 로그인 폼을 통해 아이디와 비밀번호를 제출합니다.

2. UsernamePasswordAuthenticationToken 생성:
   - 제출된 아이디와 비밀번호로 UsernamePasswordAuthenticationToken 객체가 생성됩니다.
   - 이 시점에서 토큰은 아직 인증되지 않은 상태입니다.

3. AuthenticationManager에 의한 인증:
   - 생성된 토큰은 AuthenticationManager에 전달됩니다.
   - AuthenticationManager는 등록된 AuthenticationProvider들을 통해 인증을 시도합니다.

4. 인증 성공 시:
   - 인증이 성공하면, 완전히 인증된 UsernamePasswordAuthenticationToken이 생성됩니다.
   - 이 토큰에는 사용자의 권한 정보 등이 포함됩니다.

5. SecurityContextHolder를 통한 SecurityContext 설정:
   - 인증된 토큰은 새로운 SecurityContext에 저장됩니다.
   - SecurityContextHolder.getContext().setAuthentication(authenticatedToken)을 통해 설정됩니다.
   - 이로써 현재 스레드에서 인증된 사용자 정보를 사용할 수 있게 됩니다.

6. SessionAuthenticationStrategy 적용:
   - 세션 관련 보안 정책을 적용합니다.
   - 예를 들어, 동시 세션 제어, 세션 고정 보호 등을 처리합니다.

7. RememberMeServices 처리: -> 로그인 화면에 로그인정보 기억하기 체크박스 같은거 
   - "Remember Me" 기능이 활성화되어 있다면, RememberMeServices가 호출됩니다.
   - 사용자의 인증 정보를 쿠키나 데이터베이스에 저장하여 다음 방문 시 자동 로그인을 지원합니다.

8. ApplicationEventPublisher를 통한 이벤트 발행:
   - 인증 성공 이벤트(InteractiveAuthenticationSuccessEvent)를 발행합니다.
   - 이를 통해 다른 컴포넌트들이 인증 성공을 인지하고 필요한 작업을 수행할 수 있습니다.

9. AuthenticationSuccessHandler 실행:
   - 인증 성공 후의 추가적인 처리를 담당합니다.
   - 예를 들어, 성공 페이지로의 리다이렉션, 로그 기록 등을 수행할 수 있습니다.

10. SecurityContext의 저장:
    - 인증이 완료된 SecurityContext는 일반적으로 HTTP 세션에 저장됩니다.
    - 이는 SecurityContextPersistenceFilter에 의해 관리됩니다.

11. 응답 반환:
    - 인증 과정이 모두 완료되면, 클라이언트에게 적절한 응답이 반환됩니다.
    - 일반적으로 성공 페이지로 리다이렉션되거나, JWT 토큰 등이 반환될 수 있습니다.

이 과정에서 각 컴포넌트의 역할은 다음과 같습니다:

- UsernamePasswordAuthenticationToken: 사용자의 인증 정보를 캡슐화합니다.
- SecurityContextHolder: 현재 보안 컨텍스트에 대한 액세스를 제공합니다.
- SecurityContext: 현재 인증된 사용자의 세부 정보를 보유합니다.
- SessionAuthenticationStrategy: 세션 관련 보안 정책을 적용합니다.
- RememberMeServices: "자동 로그인" 기능을 관리합니다.
- ApplicationEventPublisher: 인증 관련 이벤트를 시스템의 다른 부분에 알립니다.
- AuthenticationSuccessHandler: 인증 성공 후의 로직을 처리합니다.

이 과정은 Spring Security의 유연성을 보여주며, 각 단계를 필요에 따라 커스터마이즈할 수 있습니다.


HTTP Basic 인증

 

  HTTP 는 액세스 제어와 인증을 위한 프레임워크를 제공하며 가장 일반적인 인증 방식은 "Basic" 인증 방식이다

 

• RFC 7235 표준이며 인증 프로토콜은 HTTP 인증 헤더에 기술되어 있다

 

 

1. 클라이언트는 인증정보 없이 서버로 접속을 시도한다

 

2. 서버가 클라이언트에게 인증요구를 보낼 때 401 Unauthorized 응답과 함께 WWW-Authenticate 헤더를 기술해서 realm(보안영역) 과 Basic 인증방법을 보냄

 

3. 클라이언트가 서버로 접속할 때 Base64 로 username 과 password 를 인코딩하고 Authorization 헤더에 담아서 요청함

 

4. 성공적으로 완료되면 정상적인 상태 코드를 반환한다

 

Basic 인증 방법

Basic 인증은 HTTP에서 사용되는 가장 간단한 인증 방식 중 하나입니다.

이 방식의 작동 원리는 다음과 같습니다:

 

a. 사용자 이름과 비밀번호를 콜론(:)으로 결합합니다.

예: "username:password"

 

b. 이 문자열을 Base64로 인코딩합니다.

 

c. 인코딩된 문자열을 Authorization 헤더에 "Basic " 접두사와 함께 추가합니다.

예를 들어, Authorization 헤더는 다음과 같이 보일 수 있습니다

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

 

Realm (보안 영역)

Realm은 보호되는 리소스의 범위를 나타내는 문자열입니다.

이는 사용자에게 어떤 영역에 대한 인증을 요구하고 있는지 알려주는 역할을 합니다.

예를 들어, "관리자 영역" 또는 "사용자 프로필"과 같이 지정될 수 있습니다.

클라이언트는 이 realm 정보를 보고 어떤 자격 증명을 사용해야 할지 결정할 수 있습니다.

 

httpBasic() API

 

HttpBasicConfigurer 설정 클래스를 통해 여러 API 들을 설정할 수 있다

 

• 내부적으로 BasicAuthenticationFilter 가 생성되어 기본 인증 방식의 인증 처리를 담당하게 된다

 

 

 

@EnableWebSecurity
@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, HttpSecurity httpSecurity) throws Exception{
        http.authorizeHttpRequests(auth-> auth.anyRequest().authenticated())
                .httpBasic(Customizer.withDefaults());
        return http.build();
    }

 

.formLogin()없애고 httpBasic()만 있다면

 

다음과 같은 프롬프트 창으로 로그인을 요청한다.

 

[claude]

HTTP Basic 인증은 가장 단순한 형태의 웹 인증 방식 중 하나입니다.

주요 특징:

  1. 간단한 구현: 사용자 이름과 비밀번호를 base64로 인코딩하여 HTTP 헤더에 포함시킵니다.
  2. stateless: 서버에 세션을 유지하지 않습니다.
  3. 모든 요청에 인증 정보 포함: 클라이언트는 매 요청마다 인증 정보를 보내야 합니다.
  4. 보안 취약점: HTTPS를 사용하지 않으면 중간자 공격에 취약할 수 있습니다.

formLogin() 없이 httpBasic()만 존재한다면 프롬프트창으로 로그인을 시킨다.

 

httpBasic()또한 없다면 

 

  • 기본 인증 메커니즘 없음: 특정한 인증 방식이 구성되지 않습니다.
  • 접근 거부: 보호된 리소스에 접근하려고 하면, 기본적으로 403 Forbidden 오류가 발생합니다.
  • 로그인 방법 부재: 사용자가 인증할 수 있는 표준 메커니즘(로그인 폼이나 HTTP Basic 인증)이 제공되지 않습니다.
  • 보안 필터 체인: Spring Security의 다른 보안 필터들은 여전히 작동하지만, 사용자 인증을 처리할 특정 메커니즘이 없습니다.

httpBasic()또한 없다면 거부창만 뜬다.

 

httpBasic()또한 없다면  기본 인증방식또한 없으니 인증 받을 방법이 없다.

 

 

httpBasic() 추가 후 로그인 성공시

요청 헤더에 다음과 같은 정보를 같이 보낸다.

 

 

httpBasic() 추가 후 로그인 실패시

응답 헤더에 다음과 같은 정보가 추가된다.

앞에 Basic은 Basic 인증방식을 의미한다.

 

[claude]

 

  • WWW-Authenticate 헤더:
    • 이는 HTTP 응답 헤더입니다.
    • 서버가 클라이언트에게 인증이 필요하다는 것을 알리는 데 사용됩니다.
    • 주로 401 Unauthorized 응답과 함께 전송됩니다.
    • 이 헤더는 클라이언트에게 어떤 인증 방식을 사용해야 하는지 알려줍니다.
  • Basic realm:
    • WWW-Authenticate 헤더의 값으로 사용됩니다.
    • "Basic"은 HTTP Basic 인증 방식을 나타냅니다.
    • "realm"은 보호 영역을 식별하는 문자열입니다.

 

예시:

WWW-Authenticate: Basic realm="My Secure Site"

이 헤더의 의미:

  • 서버가 HTTP Basic 인증을 요구하고 있음
  • 보호 영역의 이름은 "My Secure Site"

realm의 역할:

  1. 사용자에게 표시: 많은 브라우저에서 인증 프롬프트에 이 realm 문자열을 표시합니다.
  2. 인증 범위 구분: 다른 realm은 별도의 인증을 요구할 수 있습니다.
  3. 비밀번호 관리: 브라우저가 realm별로 다른 비밀번호를 저장할 수 있게 합니다.

 

AuthenticationEntryPoint 만들어보기

@EnableWebSecurity
@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, HttpSecurity httpSecurity) throws Exception{
        http.authorizeHttpRequests(auth-> auth.anyRequest().authenticated())
                .httpBasic(basic -> basic.authenticationEntryPoint(new CustomAuthenticationEntryPoint()));
        return http.build();
    }
  1. AuthenticationEntryPoint  주요 목적:
    • 인증되지 않은 사용자가 보안이 설정된 리소스에 접근하려고 할 때 어떻게 반응할지를 결정합니다.
  2. AuthenticationEntryPoint  핵심 기능:
    • 인증 예외가 발생했을 때 클라이언트에게 적절한 응답을 보내는 역할을 합니다.
    • 주로 401 (Unauthorized) 응답을 생성하고, 클라이언트에게 인증 방법을 알려줍니다.
  3. 인터페이스 정의:
public interface AuthenticationEntryPoint {
    void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException;
}
 
  1. 사용 예시:
    • 기본 로그인 페이지로 리다이렉트
    • WWW-Authenticate 헤더를 포함한 401 응답 반환
    • JSON 형식의 오류 메시지 반환 (RESTful API의 경우)

 

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.setHeader("WWW-Authenticate", "Basic realm=security");
        response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
    }
}

Spring에 들어가는 BasicAuthenticationEntryPoint 의 commence를 참고해서 만듬

 

 

WWW-Authenticate 헤더가 있어야 인증을 시도한다.

 

[claude]

 

  • 이 헤더는 서버가 클라이언트에게 인증이 필요하다는 것을 알리는 데 사용됩니다.
  • 주로 401 Unauthorized 응답과 함께 전송됩니다.
  • HTTP 표준에 따르면, 서버는 인증이 필요한 경우 WWW-Authenticate 헤더를 포함해야 합니다.
  • 이는 클라이언트에게 명확한 지침을 제공하고 상호운용성을 보장하기 위함입니다.

WWW-Authenticate 헤더가 반드시 있어야만 인증을 시도할 수 있는 것은 아닙니다. 그러나 이 헤더는 클라이언트에게 필요한 인증 방식에 대한 중요한 정보를 제공하며, 표준화된 방식으로 인증 요구사항을 전달합니다. 헤더가 없는 경우에도 인증은 가능하지만, 클라이언트가 적절한 인증 방식을 추측해야 할 수 있으며, 이는 잠재적으로 문제를 일으킬 수 있습니다.

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.setHeader("WW-Authenticate", "Basic realm=security");
        response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
    }
}

 

이런식으로 헤더명을 바꾸면 로그인 프롬프트가 보이지않고 401 에러만 발생한다.

 

AuthenticationEntryPoint 인터페이스는 인증되지 않은 사용자가 인증이 필요한 요청 엔드포인트로 접근하려 할 때,

예외를 핸들링 할 수 있도록 하는것인데 그떄 

response.setHeader("WWW-Authenticate", "Basic realm=security");

로 응답 헤더값을 채움으로서 클라이언트가 basic 인증방식이고 realm이 security이라는것을 알게한다.

또한 

response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());

응답 코드와 응답메시지를 통해 인증되지않은 사용자의 접근이라는것을 알린다.

 

[claude]

HTTP Basic Authentication 프로세스는 다음과 같이 진행됩니다:

  1. 초기 요청:
    • 인증되지 않은 클라이언트가 보호된 리소스에 접근을 시도합니다.
  2. 서버 응답:
    • 서버는 401 Unauthorized 상태 코드와 함께 'WWW-Authenticate' 헤더를 포함한 응답을 보냅니다.
    • 예: WWW-Authenticate: Basic realm="security"
  3. 브라우저 동작:
    • 브라우저는 'WWW-Authenticate' 헤더를 인식하고, 이에 대응하여 로그인 프롬프트를 표시합니다.
    • 이 프롬프트는 브라우저에 내장된 기능으로, 운영체제나 브라우저 종류에 따라 모양이 다를 수 있습니다.
  4. 사용자 입력:
    • 사용자는 프롬프트에 username과 password를 입력합니다.
  5. 재요청:
    • 브라우저는 사용자가 입력한 정보를 Base64로 인코딩하여 'Authorization' 헤더에 포함시켜 서버에 재요청을 보냅니다.
    • 예: Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
  6. 인증 처리:
    • 서버는 'Authorization' 헤더를 디코딩하여 인증을 수행합니다.
    • 인증이 성공하면 요청한 리소스에 대한 접근을 허용합니다.

댓글