
https://docs.spring.io/spring-security/reference/index.html

Spring Security를 사용하기 전에 아래 내용을 간단히 숙지하면 좋다.

Spring Security에서는 form을 통한 로그인 인증 방식을 제공하고 있다. 나는 통합된 프로젝트로 개발중이기 때문에 가장 간단해 보이는 form 로그인을 시도하게 되었다.
먼저 Spring Security 의존성을 추가해야 한다.
implementation 'org.springframework.boot:spring-boot-starter-security'
여기서 좀 당황했다; ?(°Д°≡°Д°)? 이전 프로젝트에서는 5.7.0-M2 이하 버전을 사용했기 때문에 WebSecurityConfigurerAdapter를 상속받아 메소드 오버라이딩을 하면 됐는데... WebSecurityConfigurerAdapter가 Deprecated 됐다ㅋ.ㅋ
component-based한 코드 작성을 위해서라고 한다.
자세한 내용은 아래문서 ⬇ ⬇ ⬇에서
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter

공식문서 훑어보고 서치해가며 어찌저찌 고칠 수 있었다. 휴;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
//해당 메서드의 리턴되는 오브젝트를 IOC로 등록해줌
@Bean
public BCryptPasswordEncoder encodePwd() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors().and()
//TODO: CorsConfigurationSource 만들어서 등록
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/boards/**").authenticated()
.anyRequest().permitAll()
)
.formLogin()
.loginPage("/login")
.usernameParameter("email")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/boards");
return http.build();
}
}
.antMatchers() 대신 사용하도록 되어있다.form 로그인은 Spring Security Session 기반 로그인이다. 인증된 사용자의 정보는 Security 내부의 자체적인 Session에서 관리된다.
public class PrincipalDetails implements UserDetails {
private User user;
public PrincipalDetails(User user) {
this.user = user;
}
//사용자 권한 반환
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collect = new ArrayList<>();
collect.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return user.getUserRole();
}
});
return collect;
}
@Override
public String getPassword() {
return user.getUserPassword();
}
@Override
public String getUsername() {
return user.getUserEmailId();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
loadUserByUsername 함수 실행@Service
public class PrincipalDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User userEntity = userRepository.findByUserEmailId(username);
if(userEntity != null) {
return new PrincipalDetails(userEntity);
}
return null;
}
}
<!-- loginForm -->
<form th:action="@{/login}" method="POST">
<p>로그인</p>
<input name="email" type="text" placeholder="이메일을 입력해주세요" required>
<input name="password" type="password" placeholder="비밀번호를 입력해주세요" required>
<button type="submit" th:text="로그인"></button>
</form>
필요한 태그는 위와 같다. input 태그의 name부분이 중요한데 꼭❗ 위와 같이 입력해야한다. 여기서 email은 SecurityConfig에서 .usernameParameter()로 미리 지정한 값이다(디폴트는 "username")
@Controller
public class UserController {
//로그인 페이지로 이동
@GetMapping({"", "/", "/login"})
public String loginPage() {
return "html/login";
}
}
단순히 로그인 페이지로 이동시켜주는 로직이다. POST요청은 직접 작성할 필요없이, Spring Security에서 알아서 처리해준다. 너무 편하다 ദ്ദി⑉¯ ꇴ ¯⑉ ) 굳 .!
