34. 스프링 시큐리티(Spring Security)

박선규's avatar
Feb 13, 2024
34. 스프링 시큐리티(Spring Security)

서버 사이드 랜더링(SSR)

  • 서버 측에서 자바 코드를 해석해서 html에 입혀주는 과정이다.
  • 일반적으로 템플릿 엔진이라 한다.

스프링 시큐리티(Spring Security)

  • 스프링 기반 웹 애플리케이션의 인증과 권한을 담당하는 스프링의 하위 프레임워크이다.
  • 다양한 필터를 제공하여 요청에 대한 인증과 권한 부여 등 보안 관련 처리를 수행한다.
  • 핵심은 필터이다.
  • Request의 값을 보고 문지기의 역할을 한다. → 보안 유지
  • 스프링 시큐리티의 흐름
    • notion image
      👉
      그림 설명!! 톰캣 → 시큐리티 필터(보안문지기 역할을 함) → 디스패처 서블릿 → 컨트롤러 → 레파지토리 → 데이터베이스
       
      톰캣의 필터는 DI가 안 된다. 이로 인해 DB에 접근이 불가능하다.
      하지만! DI해서 DB에 접근이 되도록 하려면 톰캣의 필터를 스프링 내부로 끌어당긴다.

시큐리티(Security)가 하는 일 순서

  • 전체적인 흐름 설명
      1. 사용자가 로그인 요청을 보냅니다.
      1. 스프링 시큐리티는 이 요청을 가로채어 사용자가 제공한 인증 정보(예: 사용자 이름과 비밀번호)를 검증합니다.
      1. 인증이 성공하면, 스프링 시큐리티는 보안 컨텍스트에 사용자의 정보를 저장하고, 인증된 사용자로써의 권한을 부여합니다.
      1. 이 정보는 주로 세션에 저장되어 후속 요청에서 사용됩니다. 스프링 시큐리티는 세션에 저장된 인증 정보를 이용해 요청이 들어올 때마다 사용자를 식별하고 권한을 확인합니다.
      1. 새로운 요청이 들어오면, 스프링 시큐리티는 이 요청에 대한 인증 헤더, 쿠키 또는 다른 인증 수단을 확인하여 보안 컨텍스트를 복원하고, 사용자를 인증합니다.
      1. 만약 인증에 실패하면, 해당 요청은 보호된 자원에 접근할 수 없게 됩니다.
  • 코드로 흐름 설명
      1. Password 검증 → getPassword() → 비교 → 해시로 변환해서 비교 (해시로 변환은 Bcrpt를 이용해서 해시로 변환 한다)
      1. 이때 비교한 Password 값이 동일하다면? Session을 만든다. (Session 에 UserDetails 를 저장한다)
      시큐리티 세션이 저장되는 장소
      시큐리티 세션이 저장되는 장소
      👉
      하지만 위에 적힌 코드의 흐름은 Spring에서 직접 해준다. 그렇게 되면 흐름은! Session → SPRING_SECURITY_CONTEXT → SecuriryContext 객체 → Authentication → MyLoginUser(UserDetails) → User 이렇게 흘러 간다!
 
이렇게 사용하는 경우 Mustache(머스태치, 템플릿엔진)에서 값을 가져오기 위해서는 복잡해지는데 이런 경우 세션에 한 번 더 따로 저장을 해주는 것이 좋다! 아래는 따로 만들어준 세션 저장소의 모습이다. 참고하자! TIP) 인증이 필요한 주소들은 앞에 Entity 이름을 붙히지 않는다!
 

템플릿 엔진을 위해 세션 저장소에 따로 저장해준 코드

@GetMapping("/user/updateForm") public String updateForm(HttpServletRequest request, @AuthenticationPrincipal MyLoginUser myLoginUser) { User user = userRepository.findByUsername(myLoginUser.getUsername()); request.setAttribute("user", user); return "user/updateForm"; }
 
👉
만약! @AuthenticationPrincipal MyLoginUser myLoginUser 이걸 사용하지 않는다면? 쉽게 말해! Spring에서 해주는 역할을 내가 직접 구현을 한다면? 아래의 코드처럼 구현 해야 한다.
SecurityContext securityContext = (SecurityContext) session.getAttribute("SPRING_SECURITY_CONTEXT"); Authentication authentication = securityContext.getAuthentication(); MyLoginUser temp = (MyLoginUser) authentication.getPrincipal(); User user = temp.getUser(); System.out.println("직접 접근 : "+user.getUsername());

AOP (관점 지향 프로그래밍, Aspect Oriented Programming)

  • 애플리케이션의 공통적인 관심사를 모듈화하여 관리하는 프로그래밍 기법이다.

CSRF (사이트 간 요청 위조, Cross Site Request Forgery)

  • 웹사이트의 취약점을 이용하여 사용자가 의도하지 않은 요청을 보내게 만드는 공격 방법이다.
  • csrf 는 html 속성이 아니다.
  • “disable” 일 때는 임의적인 접근 (비정상적인 접근)이 가능하다.
  • 개발할 때는 끄는 게 좋다.

Hash (해시)

  • 데이터를 고정된 길이의 유일한 값으로 변환하는 함수이다.
  • “MD5”, “SHA-256”, “SHA-512” 등은 단방향 해시 함수로, 원본 데이터를 복구할 수 없는 방식으로 정보를 암호화한다.
  • “BCrypt”솔트를 사용하여 해시를 강화하는 알고리즘으로, 레인보우 테이블 공격을 방지하는 데 효과적이다.

레인보우 테이블 (Rainbow Table)

  • 해시된 값의 대규모 데이터베이스로, 사전에 계산된 해시들을 저장하여 암호를 무력화하려는 공격 방법이다.
  • 솔트(salt)는 각 비밀번호에 무작위 데이터를 추가하여, 레인보우 테이블로부터 비밀번호를 보호하는 데 사용한다.

스프링 시큐리티의 솔트 사용

  • 스프링 시큐리티는 비밀번호 저장 시 솔트를 사용하여 해시를 강화하고, 각 비밀번호마다 고유의 해시 값을 생성한다.
  • 비밀번호를 검증할 때는 제출된 비밀번호에 같은 솔트를 적용한 후 해시하여 저장된 해시 값과 비교한다.
  • 사용한 그림
    • notion image
      notion image
      notion image

어노테이션 배우기

@Configuration // 컴퍼넌트 스캔 (Controller, Service, Repository, Component, Configuration) @Bean // 이 어노테이션은 메서드가 스프링 컨테이너에 의해 관리되는 빈을 생성한다는 것을 나타냅니다. // 스프링의 IoC 컨테이너는 이 메서드를 호출하여 반환된 객체를 애플리케이션 컨텍스트에 등록합니다. // 제어의 역전(IoC)을 통해 객체의 생성과 관리를 스프링 프레임워크에 위임할 때 사용됩니다. // 반환된 객체는 스프링 IoC 컨테이너에 의해 관리되며, 필요한 곳에 주입될 수 있습니다. BCruptPasswordEncoder // 비밀번호를 암호화 해주는 함수 (해시) @Deprcated // 잘 사용하지 않는 코드? -> 디플리케이트가 되어 있으면 주변에 안 된 코드가 있는데 그 코드를 사용하면 된다.
👉
@Bean을 사용하는 이유! → 추상 의존을 하면 같이 일하는 것이 가능하다. 이때, 추상적인 것에 의존하는 것을 “전략 패턴”이라 한다. ”IoC”에 추상적인 것을 띄우면 편해진다.
OCP → 개방 폐쇄 원칙, 부모 타입으로 메모리에 띄워 놓으면 기존 코드를 수정할 필요가 없다.
메타어노테이션이란? → 어노테이션이 여러 개가 들어가 있는 경우 → 다른 곳에서 끌어 쓸 때 주로 사용
Share article
RSSPowered by inblog