html form 기반의 인증 과정이 어떻게 동작하는지 알아보자.

/private에 인증되지 않은(unauthenticated) 요청을 보낸다.FilterSecurityInterceptor는 인증되지 않은 요청을 AccessDeniedException 예외를 던짐으로써 거부되었음을 나타낸다. ExceptionTranslationFilter는 인증을 시작하도록 만들고 AuthenticationEtryPoint가 구성된 로그인 페이지로 리다이렉트를 보낸다. 대부분 AuthenticationEntryPoint는 LoginUrlAuthenticationEntryPoint의 인스턴스이다.username, password가 넘겨지고 UsernamePasswordAuthenticationFilter가 username과 password를 인증한다.

UsernamePasswordAuthenticationFilter는 HttpServletRequest에서 가져온 username과 password 인증의 하나인 UsernamepasswordAuthenticationToken을 만든다.UsernamePasswordAuthenticationToken은 인증하도록AuthenticationManger에게 전달된다. AuthenticationManger의 세부 정보는 사용자 정보가 저장되는 방식에 따라 달라진다.스프링 시큐리티 폼 로그인은 기본적으로 활성화되어 있다. 그러나 config 기반의 서블릿이 제고외는 즉시 폼 기반의 로그인은 명시적으로 제공해야 한다. 아래는 명시적으로 작성해야할 간단한 자바 config 예이다.
public SecurityFilterChain filterChain(HttpSecurity http) {
http
.formLogin(withDefaults());
// ...
}
이 config에서 스프링 시큐리티는 기본 로그인 페이지를 렌더링한다. 커스텀 로그인 페이지도 사용할 수 있다.
아래는 커스텀 로그인 폼을 제공하는 예이다.
public SecurityFilterChain filterChain(HttpSecurity http) {
http
.formLogin(form -> form
.loginPage("/login")
.permitAll()
);
// ...
}
로그인 페이지를 스프링 시큐리티 config에서 지정했다면 페이지를 렌더링해야 한다. 아래는 /login의 html 로그인 폼을 Thymeleaf 템플릿 엔진으로 구현한 예이다.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<title>Please Log In</title>
</head>
<body>
<h1>Please Log In</h1>
<div th:if="${param.error}">
Invalid username and password.</div>
<div th:if="${param.logout}">
You have been logged out.</div>
<form th:action="@{/login}" method="post">
<div>
<input type="text" name="username" placeholder="Username"/>
</div>
<div>
<input type="password" name="password" placeholder="Password"/>
</div>
<input type="submit" value="Log in" />
</form>
</body>
</html>
기본 HTML form의 몇가지 핵심 사항
/login으로 POST 해야한다.만약 Spring MVC를 사용한다면 controller에 GET /login와 템플릿을 매핑할 수 있도록 생성해야 한다.
@Controller
class LoginController {
@GetMapping("/login")
String login() {
return "login"; // page
}
}