[Spring Boot] Security Filter, Password encoder

우수빈·2023년 7월 3일
0

Spring Boot

목록 보기
6/10

Spring Security 5 버전부터 비밀번호는 반드시 암호화를 해야 함.
비밀번호를 암호화하지 않으면 HTTP 403(access denied, 접근 거부) 또는 HTTP 500(internal server, 내부 서버 오류)가 발생함.
비밀번호 인코더(Password encoder) 객체를 bean으로 생성해야 함.

@EnableMethodSecurity
@Configuration // 스프링 컨테이너에서 빈(bean)으로 생성, 관리 - 필요한 곳에 의존성 주입.
@EnableWebSecurity
public class Securityconfig {
	
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(); // 암호화하는 알고리즘 중 하나
    }

	// 코드 작성
}

로그인할 때 사용할 임시 사용자(메모리에 임시 저장) 생성

@Bean
    public UserDetailsService inMemoryUserDetailsService() {
        // 사용자 상세 정보, DB에 들어가는 user 정보, Entity 개념
        UserDetails user1 = User
                    .withUsername("user1") // 로그인할 때 사용할 사용자 이름 (id)
                    .password(passwordEncoder().encode("1111")) // 로그인할 때 사용할 비밀번호
                    .roles("USER") // 사용자 권한(USER, ADMIN, ...)
                    .build();
        
        UserDetails user2 = User
                .withUsername("user2")
                .password(passwordEncoder().encode("2222"))
                .roles("USER", "ADMIN")
                .build();
        
        UserDetails user3 = User
                .withUsername("user3")
                .password(passwordEncoder().encode("3333"))
                .roles("ADMIN")
                .build();
        
        return new InMemoryUserDetailsManager(user1, user2, user3);
    }

Security Filter 설정 bean
로그인, 로그아웃 설정
로그인 페이지 설정, 로그아웃 이후 이동할 페이지
페이지 접근 권한 - 로그인해야만 접근 가능한 페이지, 로그인 없이 접근 가능한 페이지.
CSRF 기능 활성화 하면, Ajax POST/PUT/DELETE 요청에서 CSRF토큰을 서버로 전송하지 않으면 403 에러가 발생.

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // -> CSRF 기능 비활성화
        http.csrf((csrf) -> csrf.disable());
        
        // 로그인 페이지 설정 - 스프링에서 제공하는 기본 로그인 페이지를 사용.
        http.formLogin(Customizer.withDefaults());
        
        // 로그아웃 이후 이동할 페이지
        http.logout((logout) -> logout.logoutSuccessUrl("/"));
        
        return http.build();
    }

다른 방법

http.authorizeHttpRequests((authRequest) -> authRequest // 접근 권한을 설정할 수 있는 객체
.requestMatchers("/post/create", "/post/detail", "/post/modify", "/post/update", "/post/delete", "/api/reply/**")
.hasRole("USER")
.permitAll()); 

.requestMatchers("...", "...") : 권한이 필요한 페이지들을 설정
.authenticated(): 인증이 끝났으면(아이디, 패스워드가 일치하면, 로그인 됐으면, hasRole과 같이 쓸 수 없음), 권한 여부에 상관 없이아이디-패스워드가 일치하면 위에 설정한 페이지들이 USER 권한 요구를 설정
.anyRequest():
.requestMatchers("/**").permitAll()): 위 페이지들 외 모든 페이지 권한없이 접근 전부 허용하겠다.

단점: 새로운 요청 경로, controller를 작성할 때마다 config 자바 코드를 수정해야 함.
-> controller 메서드를 작성할 때 애너테이션을 사용해서 접근 권한을 설정할 수도 있음.
(1) SecurityConfig 클래스에서 @EnableGlobalMethodSecurity 애너테이션 설정
(2) 각각의 controller 메서드에서 @PreAuthorize 또는 @PostAuthorize 애너테이션을 사용.

0개의 댓글