Username/Password
가장 일반적으로 사용되는 인증 방식으로
아이디와 패스워드를 사용해 로그인하는 방식이라고 볼 수 있다.
스프링 시큐리티는 HttpServletRequest에서
Username과 Password를 읽기 위해 아래와 같은 방식을 지원한다.
- Form
- Basic
- Digest
Form
우선 로그인하지 않은 사용자가 인증이 필요한 리소스에 요청한 경우
로그인 페이지로 리다이렉트 되는 과정을 먼저 살펴보겠다.
우선 인증되지 않은 사용자가 인증이 필요한 리소스에 요청을 보내면
AuthorizationFilter가 AccessDeniedException 예외를 던진다.
인증되지 않은 사용자이기 때문에 ExceptionTranslationFilter가 인증을 시작하고
AuthenticationEntryPoint를 이용하여 로그인 페이지로 리다이렉트 시킨다.
리다이렉트 된 사용자는 로그인 페이지를 요청하고
로그인 컨트롤러가 로그인 페이지를 응답한다.
사용자가 로그인 페이지에서 Username과 Password를 보내면
UsernamePasswordAuthenticationFilter가 이를 통해 인증을 시작한다.
이후의 과정은 이전에 살펴본 내용과 유사하다.
public SecurityFilterChain filterChain(HttpSecurity http) {
http
.formLogin(withDefaults());
// ...
}
스프링 시큐리티는 기본적으로 이러한 Form 로그인 방식이 활성화되어 있지만
위의 코드와 같이 서블릿 기반 구성이 제공된다면
Form 로그인 방식을 명시적으로 반드시 지정해야 한다.
public SecurityFilterChain filterChain(HttpSecurity http) {
http
.formLogin(form -> form
.loginPage("/login") //로그인 페이지 지정
.permitAll() //로그인 페이지의 접근권한 지정
);
}
위와 같이 직접 커스텀한 로그인 페이지를 지정해 줄 수도 있다.
로그인 페이지에서 Username과 Password를 보낼 때는 Post 메서드를 이용해서 보내야 한다.
(이때 요청을 보낼 때 파라미터의 이름을 username과 password로 보내야 한다.)
@Controller
class LoginController {
@GetMapping("/login")
String login() {
return "login";
}
}
커스텀 로그인 페이지를 설정했다면 스프링 MVC 컨트롤러에서는
Get 컨트롤러에 자신이 지정한 페이지(/login)를 매핑해줘야 한다.
Basic
Form 방식에서는 인증되지 않은 사용자의 요청에 대해 로그인 페이지로 리다이렉트 했다면
Basic 방식에서는 인증되지 않은 사용자에게 로그인을 다시 요청한다.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
http
// ...
.httpBasic(withDefaults());
return http.build();
}
이 방식도 마찬가지로 스프링 시큐리티에서 기본적으로 활성화되어 있지만
서블릿 기반 설정을 적용한다면 위와 같이 명시적으로 적어줘야 한다.
Digest
크레덴셜이 일반 텍스트 형태로 전송되지 않게 Basic 방식의 문제점을 해결하려는 방법이지만
암호의 저장 방식이 보안상 좋지 않기 때문에 사용하는 것을 권장하지 않는다.
'Back-End > Security' 카테고리의 다른 글
JWT 로컬 로그인 구현하기 - 1편 (0) | 2023.09.21 |
---|---|
[스프링 시큐리티] 공식문서로 배워보기 : Username/Password - 2 (0) | 2023.08.15 |
[스프링 시큐리티] 공식문서로 배워보기 : 인증 아키텍처 (0) | 2023.08.14 |
[스프링 시큐리티] 공식문서로 배워보기 : 의존성 추가 (0) | 2023.08.11 |
OAuth 2.0 동작 방식 (0) | 2023.07.17 |