본문 바로가기
개인공부/스프링 부트 3 백엔드 개발자 되기

스프링 부트 - 8장 스프링 시큐리티로 로그인/로그아웃, 회원 가입 구현하기

by 응가1414 2023. 7. 5.

8장 스프링 시큐리티로 로그인/로그아웃, 회원 가입 구현하기

사전 지식: 스프링 시큐리티

  • 스프링 시큐리티(spring security)는 스프링 기반의 애플리케이션 보안(인증, 인가, 권한)을 담당하는 스프링 하위 프레임 워크
  • 인증과 인가에 대한 개념을 알아야 한다.

인증과 인가

인증 (사용자의 신원을 입증하는 과정)

  • 예를 들어 사용자가 사이트에 로그인을 할 때 누구인지 확인하는 과정을 인증

인가 (authorization)

  • 인가는 인증과는 다르다.
  • 인가는 사이트의 특정 부분에 접근할 수 있는지에 권한을 확인하는 작업
  • 예를 들어
    • 관리자는 관리자 페이지에 들어갈 수 있지만 일반 사용자는 관리자 페이지에 들어갈 수 없다.
    • 권한을 확인하는 과정을 인가라고 한다.

스프링 시큐리티

  • 스프링 시큐리티는 스프링 기반 애플리케이션의 보안을 담당하는 스프링 하위 프레임워크입니다.
  • 보안 관련 옵션을 많이 제공
    • CSRF 공격, 세션 고정(session fixation)공격을 방어해주고, 요청 헤더도 보안 처리를 해준다.
    • CSRF 공격 : 사용자의 권한을 가지고 특정 동작을 수행하도록 유도하는 공격
    • session fixation : 사용자의 인증 정보를 탈취하거나 변조하는 공격

필터 기반으로 동작하는 스프링 시큐리티

  1. 스프링 시큐리티는 필터 기반으로 동작한다.

그림 201

  1. UsernamePasswordAuthenticationFilter : 아이디와 패스워드가 넘어오면 인증 요청을 위임하는 인증 관리자 역할
  2. FilterSecurityInterceptor : 권한 부여 처리를 위임해 접근 제어 결정을 쉽게 하는 접근 결정 관리자 역할

필터명설명

SecurityContextPersistenceFilter securityContextRepository에서 Security Context(접근 주체와 인증에 대한 정보를 담 고 있는 객체)를 가져오거나 저장하는 역할을 합니다.
LogoutFilter 설정된 로그아웃 URL로 오는 요청을 확인해 해당 사용자를 로그아웃 처리
UsernamePasswordAuthenticationFilter 인증 관리자업니다. 폼 기반 로그인을 할 때 사용되는 필터로 아이디, 패스워드 데이터를 파싱 해 인증 요청을 위임합니다. 인증이 성공하면 AuthenticationSuccessHandler를, 인증에 실패하면 AuthenticationFailureHandler를 실행합니다.
DefaultLoginPageGeneratingFilter 사용자가 로그인 페이지를 따로 지정하지 않았을 때 기본으로 설정하는 로그인 페이지 관련
BasicAuthenticationFilter 요청 헤더에 있는 아이디와 패스워드를 파싱해서 인증 요청을 위임합니다. 인증이 성공하면 AuthenticationSuccessHandler를, 인증에 실패하면 AuthenticationFailureHandler 를 실행합니다.
RequestCacheAwareFilter 로그인 성공 후, 관련 있는 캐시 요청이 있는지 확인하고 캐시 요청을 처리해줍니다. 예를 들어 로그인하지 않은 상태로 방문했던 페이지를 기억해 두었다가 로그인 이후에 그 페이지로 이동 시켜줍니다.
SecurityContextHolderAwareRequestFilter HttpservletRequest 정보를 감쌉니다. 필터 체인 상의 다음 필터들에게 부가 정보를 제공 되기 위해 사용합니다.
AnonymousAuthenticationFilter 필터가 호출되는 시점까지 인증되지 않았다면 익명 사용자 전용 객체인 Anonymous
SessionManagementFilter Authentication을 만들어 Security Context에 넣어줍니다.인증된 사용자와 관련된 세션 관련 작업을 진행합니다. 세션 변조 방지 전략을 설정하고, 유효 하지 않은 세션에 대한 처리를 하고, 세션 생성 전략을 세우는 등의 작업을 처리합니다.
ExceptionTranslationFilter 요청을 처리하는 중에 발생할 수 있는 예외를 위임하거나 전달합니다.
FilterSecurityInterceptor (인가 관련 설정) 접근 결정 관리자입니다. AccessDecisionManager로 권한 부여 처리를 위임함으로써 접근 제어 결정을 쉽게 해줍니다. 이 과정에서는 이미 사용자가 인증되어 있으므로 유효한 사용자인 지도 알 수 있습니다. 즉, 인가 관련 설정할 수 있습니다.

로그인 흐름도

  1. 사용자가 폼에 아이디와 패스워드를 입력하면, HTTPServletRequest에 아이디와 비밀번호 정보가 전달된다.
  2. 이때 AuthenticationFilter가 넘어온 아이디와 비밀번호의 유효성 검사를 한다.
  3. 유효성 검사가 끝나면 실제 구현체인 UsernamePasswordAuthenticationToken 을 만들어 넘긴다.
  4. 전달받은 인증용 객체인 UsernamePasswordAuthenticationToken을 AuthenticationManager에게 보낸다.
  5. UsernamePasswordAuthenticationToken을 AuthenticationProvider에게 보낸다.
  6. 사용자 아이디를 UserDetailService에 보낸다.
  7. UserDetailService는 사용자 아이디로 찾은 사용자의 정보를 UserDetails 객체로 만들어 AuthenticationProvider에게 전달
  8. DB에 있는 사용자 정보를 가져온다.
  9. 입력 정보와 UserDetails의 정보를 비교해 실제 인증 처리를 한다.
  10. ~10 까지 인증이 완료되면 인증 성공 여부에 따라 성공하면 AuthenticationSuccessHandler
  11. 실패하면 AuthenticationFailureHandler 핸들러를 실행한다.
  12. SecurityContexHolder에 Authentication를 저장한다.
  • 여기까지 스프링 시큐리티 폼 로그인의 인증 흐름을 알아 보았다
  • 스프링 시큐리티의 폼 로그인을 설정하는 것은 아니지만
  • 어떠한 흐름으로 로그인이 동작하는지 이해하면 스프링 시큐리티를 더장 이해 할수 있다.

회원 도메인 만들기

  1. 스프링 시큐리티를 사용해 인증, 인가 기능을 구현한다.
  2. 회원 정보를 저장할 테이블을 만들고 테이블과 연결할 도메인을 만든 다음
  3. 이 테이블과 연결할 회원 엔티티를 만들고
  4. 회원 엔티티와 연결되어 데이터를 조회하게 해줄 리포지터리를 만든 후
  5. 마지막으로 스프링 시큐리티에서 사용자 정보를 가져오는 서비스

User 엔티티 만들기

밑의 테이블을 토대로 엔티티를 만든다.

컬럼명자료형null 허용설명

id BIGINT N 기본키 일련번호
email (unique) VARCHAR(255) N   이메일
password VARCHAR(255) N   패스워드(암호화하여 저장)
created_at DATETIME N   생성일자
updated_at DATETIME N   수정일자

리포지토리 계층의 쿼리 메서드의 명명 규칙

메서드명설명쿼리

findByName() “name” 컬럼의 값 중 파라미터로 들어오는 값과 같 은 데이터 반환 WHERE name = ?1
findByNameAndAge() 첫 번째 값은 "name" 컬럼에서 조회하고, 두 번째 값은 "age" 컬럼에서 조회한 데이터 반환 WHERE name = ?1 AND age = ?2
findByNameOrAge() 파라미터로 들어오는 값 중 첫 번째 값이 “name" 컬 럼에서 조환되거나 두 번째 값이 "age"에서 조회되는 데이터 반환 WHERE name = ?1 OR age = ?2
findByAgeLessThan() "age" 컬럼의 값이 파라미터로 들어온 값보다 작은 데이터 반환 WHERE age < ?1
findByAgeGreaterThan() "age" 컬럼의 값이 파라미터로 들어온 값보다 큰 데이터 반환 WHERE age > ?1
findByNameIsNull() "name" 컬럼의 값이 null인 데이터 반환 WHERE name IS NULL

학습 마무리 인증, 인가를 간편하게 구현

  • 인증 : 보호된 리소스에 접근하는 것을 허용하기 이전에 등록된 사용자의 신원을 입증하는 과정
  • 인가 : 특정 부분에 접근할 수 있는지에 확인하는 작업
  • 스프링 시큐리티 : Spring Security 스프링 기반의 애플리케이션 보안( 인증, 인가, 권한)을 담당하는 스프링 하위 프레임워크
    • 스프링 시큐리티는 필터 기반으로 동작
    • 각 필터에서 인증, 인가와 관련된 작업을 처리한다.
    • 기본적으로 세션 & 쿠키 방식으로 인증을 처리한다.
    • 스프링 시큐리티에서 사용자의 정보를 가져오는 데 사용하는 UserDetailService를 사용합니다.
    • 이 클래스를 상속받은 뒤 loadUserByUsername()를 오버라이드하면 스프링 시큐리티에서 사용자의 정보를 가져올 때 오버라이드된 메서드를 사용한다.