스프링 시큐리티 스타터 설정
- 스프링 시큐리티를 사용하기 위해서는 먼저 스타터를 설정해야한다.
- 스타터를 설정하면 자동설정 클래스들이 동작한다.
시큐리티 커스터마이즈 하기
@Configuration
@EnableWebSecurity
public class TestWebMvcConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/", "/auth/**", "/js/**", "/image/**", "/webjars/**").permitAll();
http.authorizeRequests().anyRequest().authenticated();
// 시큐리티가 제공하는 기본 로그인 화면은 CSRF 토큰을 무조건 전달한다.
// 하지만 사용자 정의 로그인 화면에서는 CSRF 토큰을 전달하지 않는다.
http.csrf().disable();
// 사용자가 만든 로그인 화면을 띄운다.
http.formLogin().loginPage("/auth/login");
// 로그아웃 설정
http.logout().logoutUrl("/auth/logout").logoutSuccessUrl("/");
}
}
@EnableWebSecurity
어노테이션과 WebSecurityConfigurerAdapter
를 상속한 환경설정 클래스를 만들어 자동설정된 클래스들을 해제하고 커스터마이즈 할 수 있다.
- configure함수 안에 있는 메소드들을 통해 시큐리티 설정을 커스텀할 수 잇다.
DB와 연결하여 저장된 계정으로 로그인하기
@Getter
@Setter
public class UserDetailsImpl implements UserDetails {
private User user;
public UserDetailsImpl(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> roleList = new ArrayList<>();
roleList.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return "ROLE_" + user.getRole();
}
});
return roleList;
}
@Override
public String getPassword() {
return "{noop}" + user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
- UserDetails를 상속받아 오버라이드한 메소드를 설정하여 DB에 저장된 계정으로 로그인할 수 있다.
- 정확히는 다음 과정까지 거쳐야 완벽하게 로그인 할 수 있다.
- UserDetails는 입력받은 User객체가 정상 로그인 할 수 있는지 확인하는 클래스이다.
JPA와 연결하기
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User principal = userRepository.findByUsername(username).get();
return new UserDetailsImpl(principal);
}
}
- UserDetailsService를 상속받은 클래스를 활용한다.
- JPA를 사용하여 DB에 저장된 User객체를 받고, 받은 User객체를 UserDetails를 상속받은 클래스에 넣어주고 결과를 리턴받으면 된다.
완성
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
- 처음에 만들었던 설정 클래스에 다음과 같은 코드를 추가하여 로그인을 완성시켜 주면 된다.