본문 바로가기
공부/Spring Security

UserDetails

by xladmt 2024. 12. 31.

사용자 관리를 위한 인터페이스 소개

  • UserDetailsService와 UserDetailsManager 인터페이스를 이용하여 사용자 관리를 수행함(CRUD 기능)
    • UserDetailsService는 사용자 이름으로 사용자를 검색함(Read)
    • UserDetailsManager는 사용자 추가, 수정, 삭제 작업을 수행함(Create, Update, Delete)
  • 두 인터페이스의 분리는 5대 객체 지향 프로그래밍 원칙(SOLID) 중 I에 해당하는 Interface Segregation Principle에 해당함
    • 인터페이스 분리 원칙 : 사용하지 않는 인터페이스에 강제로 의존해서는 안됨
  • 따라서, read와 write 관련 인터페이스를 분리햐두었기 때문에 프레임워크의 유연성이 향상됨
    • 사용자를 인증하는 기능한 필요하면 UserDetailsService 인터페이스만 구현하면 됨
    • 추가, 수정, 삭제 등 더 많은 기능을 제공해야 하면 UserDetailsManager를 함께 구현하면 됨

 

UserDetailsService

- 유저 정보를 조회하는 메소드만 존재함

- username을 파라미터로 받아 UserDetails 객체를 반환하는 loadUserByUsername 메소드

 

UserDetailsManager

- 사용자 생성, 수정, 삭제, 암호 변경, 사용자 존재 여부 확인 메소드를 제공함

- UserDetailsService를 extends 하고 있기 때문에 UserDetailsManager를 구현하면 클라이언트는 UserDetailsService까지 구현해야 함.

 

이용 권리의 집합, GrantedAuthority

  • 사용자는 사용자가 수행할 수 있는 작업을 나타내는 이용 권리의 집합을 가짐
    • 보통 권한이라고 표현함
    • 예시 : 메뉴 조회 권한, 데이터 수정 권한, 데이터 대량 업로드 권한 등
    • 사용자는 하나 이상의 권한을 가질 수 있으며 GrantedAuthority 라는 인터페이스를 통해 이를 구현할 수 있음.

 

사용자 관리를 위한 요소간 관계

  • UserDetailsService, UserDetailsManager, UserDetails, GrantedAuthority의 관계
    • UserDetailsService는 사용자 이름으로 조회한 사용자 세부 정보인 UserDetails를 반환함
    • 사용자는 하나 이상의 권한을 가질 수 있으며 이는 GrantedAuthority로 구현할 수 있음

 

  • UserDetails : 유저 정보(username, password)를 가지고 있는 인터페이스
  • GrantedAuthority : Collention 타입으로 UserDetails에 있음
  • UserDetailsService : username으로 userDetails을 반환함
  • UserDetailsManager : userDetailsService를 상속받으며 CRUD 가능

 

사용자 상세 정보, UserDetails

  • 스프링 시큐리티의 인증 흐름에서 사용자를 나타내는 방법은 필수로 숙지해야 함
  • 사용자에 따라 애플리케이션은 제공할 수 있는 기능을 제한하기도 함.
  • UserDetails 인터페이스를 기반으로 스프링 시큐리티에서는 사용자를 표현함
  • 인터페이스이기 때문에 애플리케이션 수준에서 UserDetails를 구현해야 함.

- 총 7개의 메소드가 존재함.

getAuthorities()  애플리케이션 사용자가 수행할 수 있는 작업을 GrantedAuthority 인스턴스의 컬렉션으로 반환
getPassword() 사용자의 암호 반환
getUsername() 사용자의 사용자ID 반환
isAccountNonExpired() 필요에 따라 사용자를 비활성화 할 수 있는 메소드(기본값으로 true를 반환함)
isAccountNonLocked() 필요에 따라 사용자를 비활성화 할 수 있는 메소드(기본값으로 true를 반환함)
isCredentialsNonExpired() 필요에 따라 사용자를 비활성화 할 수 있는 메소드(기본값으로 true를 반환함)
isEnabled() 필요에 따라 사용자를 비활성화 할 수 있는 메소드(기본값으로 true를 반환함)

> 사용자 비활성화 기능

  • 계정 만료, 계정 잠금, 자격 증명 만료, 계정 비활성화 기능을 통해 사용자를 애플리케이션 수준에서 제한할 수 있음
  • 4개의 메소드를 재정의하여 true/false를 반환하게 하여 사용자를 제한할 수 있음
    • 별도의 제한이 필요 없다면 true를 반환하게 하면 됨
    • default 메소드로 이미 true를 반환하고 있기 때문에 재정의를 하지 않으면 사용하지 않는 것으로 간주
    • 메소드 네이밍이 부정을 의미하는 ..non.. 이 붙어 있어서 헷갈릴 수 있기 때문에 주의가 필요함

 

GrantedAuthority

권한이란?

  • 사용자에게 허가된 작업을 권한(authority)이라고 함
    • 애플리케이션에서 사용자가 수행할 수 있는 작업을 의미함
    • 만약 권한이 없는 애플리케이션이라면 모든 사용자는 동등하다고 볼 수 있음
  • 권한이 존재하는 시스템
    • 백오피스 어드민에서 일반 사용자와 관리자를 구분해야 할 때
    • 일반 사용자 중에서 메뉴 A, B에 접근할 수 잇는 사용자와 메뉴 C, D에 접근할 수 있는 사용자를 구분해야 할 때
    • 조회만 수행할 수 있는 사용자와 수정도 함께 할 수 있는 사용자를 구분해야 할 때

=> 이러한 작업을 할 때 GrantedAuthority로 할 수 있음

 

GrantedAuthority 알아보기

  • GrantedAuthority는 UserDetails에서 사용되며 사용자에게 허가된 이용 권리를 나타냄
    • 권한이 하나도 없거나 여러 권한을 가질 수 있음
  • 인터페이스이기 때문에 권한 클래스를 직접 구현하거나 이미 만들어진 SimpleGrantedAuthority 등을 활용할 수 있음

 

예) GrantedAuthority를 활용하여 읽기(READ) 권한 만들기

람다 식을 이용하거나 SimpleGrantedAuthority 클래스를 이용하여 읽기(READ) 권한을 선언할 수 있음

GrantedAuthority authority1 = new SimpleGrantedAuthority("READ");
GrantedAuthority authority2 = () -> "READ";

 

User 엔티티와 UserDetails 활용

  • 일반적으로 사용자 정보는 데이터베이스에서 관리되기 때문에 영속성 엔티티를 표현하는 클래스가 필요함
    • 영속성 엔티티 클래스 뿐만 아니라 별도로 사용자를 표현하는 클래스도 필요함(다른 시스템으로 전송하거나 내부적으로 활용할 목적으로)
  • 사용자에 대한 영속성 엔티티는 다음과 같이 표현할 수 있음
    • Spring-data-jpa에 대한 의존성을 추가
    • @Entity 어노테이션 활용
    • 엔티티임을 표현하기 위해 @Id 어노테이션 활용

*User 엔티티 클래스에 UserDetails 인터페이스를 상속 받는다면 로직이 상당히 복잡해질 수 있음

- 두 책임( 책임 1. 데이터베이스 관련 영속성 엔티티, 책임 2. 스프링 시큐리티의 사용자 정보)이 혼합되어 있기 때

 

=> 해결을 위해서는 별도의 클래스를 구현해서 사용해야 함

  • 영속성 엔티티를 표현하는 UserEntity
  • 스프링 시큐리티의 사용자 정보를 표현하는 User

UserEntity
Spring Security의 User

 

'공부 > Spring Security' 카테고리의 다른 글

HTTP Basic 인증 방식  (0) 2025.01.01
PasswordEncoder 와 암호처리  (0) 2024.12.31
Spring Security 기본 구성  (0) 2024.12.29
Spring Security 시작  (0) 2024.12.29