스프링 시큐리티
- 의미 : 스프링 기반의 애플리케이션 보안(인증, 인가, 권한)을 담당하는 스프링 하위 프레임워크로, 필터 기반으로 동작한다.
- CSRF 공격, 세션 고정 공격을 방어해주고, 요청 헤더도 보안 처리를 해주므로 개발자가 보안 관련 개발을 해야 하는 부담을 줄여준다.
Domain 패키지
@Table(name = "users")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity
public class User implements UserDetails{ //UserDetails를 상속받아 인증 객체로 사용
...
@Builder
public User(String email, String password, String auth){
this.email = email;
this.password = password;
}
...
}
▶ User 클래스가 상속한 UserDetails 클래스는 스프링 시큐리티에서 사용자의 인증 정보를 담아 두는 인터페이스,
스프링 시큐리티에서 해당 객체를 통해 인증 정보를 가져오려면 필수 오버라이드 메서드들을 여러 개 사용해야 한다.
Repository 패키지
public interface UserRepository extends JpaRepository<User, Long>{
Optional<User> findByEmail(String email); //email로 사용자 정보를 가져옴
}
▶ 이메일로 사용자를 식별할 수 있다.
▶ findByEmail() : FROM user WHERE email = #{email}
Service 패키지
@RequiredArgsConstructor
@Service
public class UserDetailService implements UserDetailsService{
private final UserRepository userRepository;
//사용자 이름(email)으로 사용자의 정보를 가져오는 메서드
@Override
public User loadUserByUsername(String email){
return userRepository.findByEmail(email).orElseThrow(() -> new IllegalArgumentException((email)));
}
}
▶ UserDetailsService 인터페이스 : 스프링 시큐리티에서 사용자 정보를 로드하기 위한 메서드를 정의한 인터페이스로, 이 인터페이스를 구현하려면 loadUserByUsername() 메서드를 반드시 구현해야 한다.
▶ loadUserByUsername() : 주어진 사용자 이름(또는 식별자)을 기반으로 사용자 정보를 로드하는 역할을 한다.
만약, 이 메서드를 오버라이딩 하지 않는다면 스프링 시큐리티가 'UserDetailsService'를 사용할 때 해당 메서드가 적절한 사용자 정보를 로드할 수 없게 되어, 사용자 인증 및 권한 부여와 관련된 동작이 제대로 이루어지지 않아 컴파일 오류가 발생하게 된다.
Config 패키지
@RequiredArgsConstructor
@Configuration
public class WebSecurityConfig{
private final UserDetailService userService;
//스프링 시큐리티 기능 비활성화
@Bean
public WebSecurityCustomizer configure(){
return (web) -> web.ignoring()
.requestMatchers(toH2Console())
.requestMatchers("/static/**");
}
//특정 HTTP 요청에 대한 웹 기반 보안 구성
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
return http
.authorizeHttpRequests() //인증, 인가 설정
.requestMatchers("/login", "/signup", "/user").permitAll()
.anyRequest().anthenticated()
.and()
.formLogin() //폼 기반 로그인 설정
.loginPage("/login")
.and()
.logout() //로그아웃 설정
.logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.and()
.csrf().disable() //csrf 비활성화
.build();
}
//인증 관리자 관련 설정
@Bean
public AuthenticationManager authenticationManager(HttpSecurity http,
BCryptPasswordEncoder bCryptpasswordEncoder, UserDetailService userDetailService) throws Exception{
return http.getSharedObject(AuthenticationManagerBuilder.class)
.userDetailsService(userServicie)
.passwordEncoder(bCryptPasswordEncoder)
.and()
.build();
}
//패스워드 인코더를 사용할 빈 등록
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
}
= 메서드 부가 설명
confugrure() | - static 하위 경로에 있는 리소스와 h2-console 하위 url 대상으로 스프링 시큐리티의 모든 기능(인증, 인가) 서비스를 적용하지 않음 |
filterChain() | - 특정 Http 요청에 대한 웹 기반 보안을 구성. - 인증, 인가 및 로그인, 로그아웃 관련 설정 |
authenticationManager() | - 인증 관리자 관련 설정 - 사용자 정보를 가져올 서비스를 재정의하거나, 인증 방법(JDBC 기반 인증) 등을 설정할 때 사용 |
= filterChain() 메서드 부가 설명
requestMatchers() | 특정 요청과 일치하는 url에 대한 액세스를 설정 |
permitAll() | 누구나 접근이 가능하게 설정. (/login, /signup, /user로 요청이 오면 인증,인가 없이 접근 가능 |
anyRequest() | 위에 설정한 url 이외의 요청에 대해서 설정 |
authenticated() | 별도의 인가는 필요하지 않지만 인증이 성공된 상태여야 접근 가능 |
loginPage() | 로그인 페이지 경로 설정 |
defaultSuccessUrl() | 로그인이 완료되었을 때 이동할 경로 설정 |
logoutSuccessUrl() | 로그아웃이 완료되었을 때 이동할 경로 여부 설정 |
invalidateHttpSession() | 로그아웃 이후에 세션을 전체 삭제할지 여부를 설정 |
'WEB > spring' 카테고리의 다른 글
Spring JAP_ @MappedSuperClass (0) | 2024.04.18 |
---|---|
Spring boot) 카카오톡 로그인 API 연동 (0) | 2024.01.31 |
Spring Security란? (1) (0) | 2024.01.18 |
페이스북 로그인 연동 (0) | 2023.12.22 |
관점 지향 프로그래밍과 객체 지향 프로그래밍을 합쳐서 간단하게 (0) | 2023.12.22 |