Spring Security는 HTML Form을 통해 제공되는 사용자 이름 및 암호를 지원합니다.
/private
)에 요청을 합니다.ExceptionTranslationFilter
는 AuthenticationEntryPoint를 사용하여 로그인 페이지로 리디렉션을 보냅니다.form이 제출 되면 UsernamePasswordAuthenticationFiter
로 인증합니다.
이 그림은 SecurityFilterChain
다이어그램을 기반으로 합니다.
UsernamePasswordAuthenticationToken
인스턴스에서 사용자 이름과 암호를 추출하여 인증합니다.SecurityContextHolder
가 지워집니다.Config 설정 후 로그인 페이지
Spring Security는 Config 클래스 설정 후 특정 경로에 대한 접근 권한이 없는 경우 자동으로 로그인 페이지로 리다이렉팅 되지 않고 오류 페이지가 발생합니다.
이 문제를 해결하기 위해 Config 클래스를 설정하면 로그인 페이지 설정도 진행해야 합니다.
login page
<hr>
<form action="/loginProc" method="post" name="loginForm">
<input id="username" type="text" name="username" placeholder="id"/>
<input id="password" type="password" name="password" placeholder="password"/>
<input type="submit" value="login"/>
</form>
/locginProc 경로로 Post 요청
Login Controller
@Controller
public class LoginController {
@GetMapping("/login")
public String loginP() {
return "login";
}
}
Security Config 로그인 페이지 설정 및 로그인 경로
package com.example.testsecurity.config;
import jakarta.servlet.FilterChain;
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.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/login", "/loginProc").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.requestMatchers("/my/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
);
http
.formLogin((auth) -> auth.loginPage("/login")
.loginProcessingUrl("/loginProc")
.permitAll()
);
http
.csrf(AbstractHttpConfigurer::disable); // 비활성화
/*csrf는 스프링 시큐리티에서 구현해두었다. 로그인 시 POST 요청 시 CSRF 토큰을 함께 전송해야 하기 때문에 학습과 테스트를 위해 비 활성화*/
return http.build();
}
}
http://localhost:8080/admin
로 페이지 요청시 권한이 없기 때문에 AuthorizationFilter
는 인증되지 않은 요청이 AccessDeniedException
을 뱉습니다.
인증되지 않았으므로 ExceptionTranslationFilter
는 AuthenticationEntryPoint
를 사용하여 로그인 페이지로 리디렉션을 보냅니다.
위에서 만든 login.html로 리디렉션 하고 화면을 렌더링 합니다.