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에서 알아서 처리해준다. 너무 편하다 ദ്ദി⑉¯ ꇴ ¯⑉ )
굳 .!