[Spring Security] PasswordEncoder

2024. 6. 27. 20:36·Backend/Spring Security

일반적인 Spring Security 내부 흐름입니다. 우리는 InMemoryUserDetailsManager를 사용하는 대신에 직접 loadByUsername()을 오버라이딩하여 사용해보도록 하겠습니다. 

 

 

실습 - User 정보를 SQL 스크립트를 활용하여 수동 입력

Config - SecurityConfig

@Configuration
public class ProjectSecurityConfig {
    @Bean
    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests((requests) ->
                requests.requestMatchers("/myAccount", "/myBalance", "/myLoans", "/myCards").authenticated()
                        .requestMatchers("/notices", "/contact").permitAll()
        );
        http.formLogin(Customizer.withDefaults());
        http.httpBasic(Customizer.withDefaults());

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() { 
        return NoOpPasswordEncoder.getInstance();
    }
}

 

Repository - CustomerRepository

public interface CustomerRepository extends JpaRepository<Customer, Long> {
    List<Customer> findByEmail(String email);
}

 

Model - Customer

@Entity
@Getter
public class Customer {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    private String email;
    private String pwd;
    private String role;
}

 

Service - BankUserDetails

BankUserDetails는 UserDetailsService의 실질적인 구현체가 되고, 다른 UserDetailsManager의 영향을 받지 않게 됩니다. 

@RequiredArgsConstructor
@Service
public class BankUserDetails implements UserDetailsService {
    private final CustomerRepository customerRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        String userName, password = null;
        List<GrantedAuthority> authorities = null;
        List<Customer> customers = customerRepository.findByEmail(username);
        if(customers.isEmpty()) {
            throw new UsernameNotFoundException("User details not found for the user : " + username);
        } else {
            userName = customers.get(0).getEmail();
            password = customers.get(0).getPwd();
            authorities = new ArrayList<>();
            authorities.add(new SimpleGrantedAuthority(customers.get(0).getRole()));
        }
        return new User(userName, password, authorities);
    }
}

 

 

새로운 유저 등록을 허용하는 새 REST API 구축

SecurityConfig에서 permitAll()을 해주고, 다시 POST 요청을 보내도 에러가 발생합니다. 그 이유는 Spring Security 에서 제공하는 CSRF 보안 때문입니다. 기본 설정은 어떤 POST 요청이든 간에 DB나 백엔드 내부의 데이터를 수정하고자 하는 것이면 막도록 되어 있습니다. 일단 테스트를 위해 CSRF를 해제하겠습니다.

http.csrf(AbstractHttpConfigurer::disable)

 

 

그 결과, 정상적으로 유저 정보를 받아올 수 있었습니다. 

 

 

 

 

실습 - Bcrypt PasswordEncoder를 사용한 새로운 유저 등록 (보안 강화)

passwordEncoder에서 기존에 넘겨주던 NoOpPasswordEncoder가 아닌 BCryptPasswordEncoder를 념겨주도록 코드를 수정해줍니다. 

@Bean
    public PasswordEncoder passwordEncoder() { 
        return new BCryptPasswordEncoder();
    }

 

Postman을 통해 유저 자격 증명을 POST로 전송합니다. 

결과 !! 

NoOpPasswordEncoder를 이용한 방법은 문자열 그대로 저장되기 때문에 보안에 취약합니다. 하지만 BCryptPasswordEncoder의 경우 해싱 알고리즘을 이용한 방법으로 저장되기 때문에 상대적으로 안전한 모습을 볼 수 있습니다. 

 

 

 

'Backend/Spring Security' 카테고리의 다른 글
  • CSRF 공격 시나리오 및 방어 방법
  • [Spring Security] 유저 정의와 관리
  • [Spring Security] OAuth 2.0 개념과 이해
  • [Spring Security] 내부 흐름 - 2
kimdozzi
kimdozzi
끝까지 포기하지 않으면, 내가 다 이겨!
  • kimdozzi
    도브로
    kimdozzi
  • 전체
    오늘
    어제
    • 분류 전체보기 (132)
      • Problem Solving (49)
        • Baekjoon (29)
        • Programmers (0)
        • LeetCode (17)
        • 삼성 유형 (2)
      • Computer Science (27)
        • Operating System (2)
        • Algorithms (13)
        • Network (6)
        • DataBase (6)
      • Backend (33)
        • JavaScript (0)
        • TypeScript (6)
        • Java (7)
        • Spring Boot (7)
        • Spring Security (6)
        • JPA (2)
        • Mybatis (1)
        • Junit5 (1)
        • Redis (3)
      • DevOps (14)
        • Git, Github (5)
        • docker (4)
        • AWS (3)
        • nginx (2)
      • etc (6)
        • IntelliJ (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 티스토리
    • 설정
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    TypeScript
    python
    점 업데이트
    AWS
    티스토리챌린지
    백준
    Bucket
    docker
    알고리즘
    구간 업데이트
    imos법
    누적합
    파이썬
    CORS
    segment tree
    인터페이스
    오프라인 쿼리
    오블완
    구간합
    도커
    interface
    S3
    세그먼트 트리
    타입스크립트
    인덱스 시그니처
    컨테이너
    온라인 쿼리
    PrefixSum
    docker image
    인덱서블 타입
    삼성기출
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
kimdozzi
[Spring Security] PasswordEncoder
상단으로

티스토리툴바