현재 Spring Security를 이용하여 로그인 기능을 구현하고 있습니다.
스프링부트 프로젝트에서, Spring Security가 의존성으로 사용이 되는 상태에서 아무런 설정을 하지 않을 경우,
/login으로 접속 하면,
Spring Security에서 제공하는 기본 로그인 폼이 나오게 됩니다.
하지만 저는,
/login이라는 url로 접속을 하면
다음과 같이 제가 직접 정의한 로그인 폼이 나오도록 하고 싶습니다.
그래서 다음과 같이,
DefaultSecurityFilterChain을 정의하고 Bean으로 등록을 하였습니다.
@Bean
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
.. 나머지 부분 생략 ..
http.authorizeHttpRequests(
// 인증이 필요한 url, 인증 없이도 접근 가능한 url 을 설정하는 부분이다.
(requests) -> requests.
requestMatchers(urlsToBeAuthenticated).authenticated().
requestMatchers(urlsToBePermittedAll).permitAll()).
// 사용자가 web browser 를 통해 접근하려고 하면 폼 로그인 기반의 인증이 적용.
formLogin(formLogin -> formLogin
.loginPage("/login")
.usernameParameter("username") // 입력된 아이디는 username 이라는 이름의 파라미터로 넘어가서 처리되도록
.passwordParameter("password") // 입력된 비밀번호는 password 이라는 이름의 파라미터로 넘어가서 처리되도록
.successHandler(customAuthenticationSuccessHandler) // 로그인 성공 시 동작하는 로직을 정의하고 리다이렉션하는 부분
.failureHandler(customAuthenticationFailureHandler) // 로그인 실패 시 동작하는 로직을 정의하고 리다이렉션하는 부분
.permitAll())
.. 나머지 부분 생략 ..
return http.build();
}
위에서 formLogin설정 부분만을 보시면 됩니다.
formLogin설정을 통해서,
스프링 시큐리티의 로그인 기능이 invoke될 시에,
"/login"페이지로 리다이렉션이 되도록 하였습니다.
그리고 다음과 같이 LoginController를 정의하였습니다.
@Controller
@RequiredArgsConstructor
@Slf4j
public class LoginController {
private final CustomerRepository customerRepository;
private final PasswordEncoder passwordEncoder;
@GetMapping("/login")
public String loginForm(
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout,
Model model) {
log.info("login controller invoked!");
return "form/login";
}
즉 /login이라는 요청이 들어올 시,
resources/templates/form/login.html이라는 리소스가 서버쪽에서 렌더링이 되어서,
클라이언트에게 전달이 되도록 코드를 구현한 것입니다.
하지만 이렇게 하니
resources/templates/form/login.html 라는 자원을 찾지 못했다는,
Not Found Static File 에러가 발생하며
자꾸만 /error페이지로 리다이렉션이 되었습니다.
이 에러가 왜 발생하는가 하면,
Maven으로 빌드한 스프링 부트 프로젝트에서
정적 파일의 위치를 알아내기 위해서는 몇 가지 설정을 해줘야하는데, 그걸 생략했기 때문입니다.
Gradle로 스프링부트 프로젝트를 빌드하면
별다른 설정을 하지 않아도 resources/templates경로에 있는 정적인 리소스에 대한 접근이 가능하지만,
Maven에서는 이 정적 자원을 스프링부트 프로젝트에서 인식할 수 있도록 하기 위해 몇가지 단계를 거쳐야 합니다.
단계 1. pom.xml에 thymeleaf 의존성, 그리고 정적 자원 리소스 위치를 추가하기
// Thymeleaf의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
// 정적 자원의 리소스 위치 식별할 수 있게 하기
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
단계2. 타임리프 사용을 위한 타임리프 설정 객체를 Bean으로 등록
Configuration클래스에 다음과 같은 빈을 정의해 두어서
애플리케이션 시작 시에 스프링 컨테이너에서 Bean으로 관리되도록 하였습니다.
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("classpath:/templates/");
resolver.setSuffix(".html");
return resolver;
}
이렇게 두 단계만 거치면, Maven을 통해 빌드한 스프링부트 프로젝트에서
resources/templates에 위치한 정적 파일들을 인식할 수 있게 됩니다.
그래서, 특정한 static 파일을 찾지 못해서 /error로 리다이렉션 되는 오류를 더이상 접하지 않을 것입니다.
'Back-End > Spring' 카테고리의 다른 글
왜 Spring Security 의존성을 추가 하기만 해도 모든 엔드포인트에 인증과정이 요구되는가 (0) | 2024.10.22 |
---|---|
[디버깅] Spring Security 사용 중 템플릿에 CSS가 적용되지 않는 현상 (0) | 2024.07.18 |
데이터베이스의 엔티티(Entity)에 대한 고찰, 그리고 JPA의 @Entity 어노테이션 (0) | 2024.04.12 |
상황을 통해 이해하는 JPA 영속성 전이 및 CASCADE 옵션 (0) | 2024.04.10 |
Spring Data JPA에서의 Transaction 및 수정 작업 (0) | 2024.04.09 |