스프링 시큐리티 - 로그인 기능
※순서
1. 스프링 시큐리티에 로그인 URL 등록하기___(SecurityConfig.java)
2. 회원 컨트롤러에 URL 매핑 추가하기______(UserController.java)
3. 로그인 화면 구현____________________(login_form.html)
4. 회원 리포지터리 수정하기_____________(UserRepository.java)
5. 권한 설정 파일 생성하기______________(UserRole.java)
6. UserSecurityService 서비스 생성하기
7. 스프링 시큐리티 설정 수정하기
8. 로그인 화면 수정하기
9. 로그아웃 기능 구현하기
1. 스프링 시큐리티에 로그인 URL 등록하기
SecurityConfig.java 에 다음 코드 추가
.formLogin((formLogin) -> formLogin
.loginPage("/user/login")
.defaultSuccessUrl("/"));
● .formLogin 메소드는 스프링 시큐리티의 로그인 설정을 담당하는 부분
● 로그인 페이지의 URL은 /user/login
● 로그인 성공 시에 이동할 페이지는 루트(/)
2. 회원 컨트롤러에 URL 매핑 추가하기
UserController.java 에 다음 코드 추가
@GetMapping("/user/login")
public String login() {
return "login_form";
}
3. 로그인 화면 구현
login_form.html
<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container my-3">
<form th:action="@{/user/login}" method="post">
<div th:if="${param.error}">
<div class="alert alert-danger">
사 용 자ID 또 는 비 밀 번 호 를 확 인 해 주 세 요.
</div>
</div>
<div class="mb-3">
<label for="username" class="form-label">사 용 자ID</label>
<input type="text" name="username" id="username" class="form-control">
</div>
<div class="mb-3">
<label for="password" class="form-label">비 밀 번 호</label>
<input type="password" name="password" id="password" class="formcontrol">
</div>
<button type="submit" class="btn btn-primary">로 그 인</button>
</form>
</div>
</html>
4. 회원 리포지터리 수정하기
userRepository.java
package com.mysite.sbb.user;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<SiteUser, Long> {
Optional<SiteUser> findByusername(String username);
}
사용자ID 를 조회하는 기능이 필요하므로 ID로 사용자 엔티티를 조회하는 findByusername 메소드가 필요
5. 권한 설정 파일 생성하기
UserRole.java
package com.mysite.sbb.user;
import lombok.Getter;
@Getter
public enum UserRole {
ADMIN("ROLE_ADMIN"),
USER("ROLE_USER");
UserRole(String value) {
this.value = value;
}
private String value;
}
ADMIN는 관리자, USER는 사용자를 의미한다. 그리고 ADMIN과 USER 상수는 값을 변경할 필요가 없으므로 @Getter만 사용하였다.
6. UserSecurityService 서비스 생성하기
UserSecurityService.java
package com.mysite.sbb.user;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Service
public class UserSecurityService implements UserDetailsService {
private final UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<SiteUser> _siteUser = this.userRepository.findByusername(username);
if (_siteUser.isEmpty()) {
throw new UsernameNotFoundException("사 용 자 를 찾 을 수 없 습 니 다.");
}
SiteUser siteUser = _siteUser.get();
List<GrantedAuthority> authorities = new ArrayList<>();
if ("admin".equals(username)) {
authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.getValue()));
} else {
authorities.add(new SimpleGrantedAuthority(UserRole.USER.getValue()));
}
return new User(siteUser.getUsername(), siteUser.getPassword(),authorities);
}
}
스프링 시큐리티가 로그인 시 사용할 UserSecurityService 는 스프링 시큐리티가 제공하는 UserDetailsService 인터페이스를 구현해야한다.
사용자명이 admin 일 경우 ADMIN 권한을 부여하고
그 외에는 USER 권한을 부여한다.
7. 스프링 시큐리티 설정 수정하기
SecurityConfig.java
(... 생 략 ...)
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration
.AuthenticationConfiguration;
(... 생 략 ...)
@Configuration
@EnableWebSecurity
public class SecurityConfig {
(... 생 략 ...)
@Bean
AuthenticationManager authenticationManager(AuthenticationConfiguration
authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
AuthenticationManager 는 사용자 인증 시 앞에서 작성한 UserSecurityService 와 PasswordEncoder 를 내부적으로 사용하여 인증과 권한 부여 프로세스를 처리한다.
8. 로그인 화면 수정하기
로그인 버튼에 th:href="@{/user/login}" 추가
sec:authorize="isAnonymous()" -> 로그인 버튼에 추가
sec:authorize="isAuthenticated()" -> 로그아웃 버튼에 추가
9. 로그아웃 기능 구현하기
SecurityConfig 파일에 다음 코드 추가
.logout((logout) -> logout
.logoutRequestMatcher(new AntPathRequestMatcher("/user/logout"))
.logoutSuccessUrl("/")
.invalidateHttpSession(true));