[Spring] Spring-Security / UserDetails와 UserDetailsService 커스터마이징

yunSeok·2023년 11월 13일
0

Spring Security

목록 보기
2/2

📌 스프링 시큐리티로 로그인과 회원가입을 구현하면 기존에 사용하는 UserDTO에 더해서 인증처리를 도와줄 DTO 클래스를 하나 더 생성해서 사용하게됩니다.

UserDetails 라는 클래스를 이용하는데요, 이것은 스프링 시큐리티에서 제공하는 표준 인터페이스입니다. 이 클래스를 이용하면 쉽게 스프링 시큐리티 기능을 사용할 수 있습니다!!

그리고 어느정도 사용자에 따라 커스터마이징 해서 사용할 수 있다는 것도 장점인것 같습니다. 🙂

구현 예제!!

바로 구현해보겠습니다.

기존 DTO

Userinfo class

@Data
public class Userinfo {

   private String id;
   private String pw;
   private String name;
   private int status;
   private String enabled;
   
   private List<UserinfoAuth> securityAuthList;
  
}

UserinfoAuth class

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserinfoAuth {
	private String id;
	private String auth;
}

인증처리 DTO 생성

기존 DTO 클래스에서 추가로 UserDetails 클래스를 이용해 클래스를 생성할건데,
클래스 명을 CustomUserDetails 라고 설정하고 진행해보겠습니다.

CustomUserDetails class

@Data
public class CustomUserDetails implements UserDetails {
   private static final long serialVersionUID = 1L;  
   
   private String id;
   private String pw;
   private String name;
   private int status;
   private String enabled;
   
   // 인증된 사용자의 권한 정보가 저장될 필드
   private List<GrantedAuthority> userinfoAuthList;

   // 기존에 사용중인 Userinfo 객체의 값을 현재 클래스의 필드에 저장
   public CustomUserDetails(Userinfo userinfo) {
      this.id = userinfo.getId();
      this.pw = userinfo.getPw();
      this.name = userinfo.getName();
      this.status = userinfo.getStatus();
      this.enabled = userinfo.getEnabled();

      // 사용자의 권한을 GrantedAuthority 객체로 생성하여 저장
      this.userinfoAuthList= new ArrayList<GrantedAuthority>();  

      for (UserinfoAuth auth : userinfo.getSecurityAuthList()) {  
    	  userinfoAuthList.add(new SimpleGrantedAuthority(auth.getAuth()));
      }
   }

   // 인증된 사용자의 권한 정보를 반환
   @Override  
   public Collection<? extends GrantedAuthority> getAuthorities() {  
      return userinfoAuthList;
   }

   // 인증된 사용자의 비밀번호를 반환
   @Override  
   public String getPassword() { 
      return pw;
   }

   // 인증된 사용자의 아이디를 반환
   @Override  
   public String getUsername() {  
      return id;
   }

   // 인증 사용자의 계정 유효 기간 정보를 반환
   // false: 기간 만료 
   @Override  
   public boolean isAccountNonExpired() {  
      return true;
   }

   // 인증 사용자의 계정 잠금 상태를 반환
   // false: 잠금 상태
   @Override  
   public boolean isAccountNonLocked() {  
      return true;
   }

   // 인증 사용자의 비밀번호 유효 기간 상태를 반환
   // false: 기간 만료
   @Override
   public boolean isCredentialsNonExpired() {  
      return true;
   }

   // 인증 사용자의 활성화 상태를 반환
   // false: 비활성화 상태
   // enabled.equals("1") 의 값은 개인이 설정한 값으로 커스터마이징해주세요.
   @Override
   public boolean isEnabled() { 
	   if (enabled.equals("1")) {
			return false;
		} else {
			return true;
		}
   }
}

✅ serialVersionUID

private static final long serialVersionUID = 1L;

스프링 시큐리티를 구현하는데 중요한 클래스이기 때문에 선언해주었습니다.
스프링 시큐리티의 버전이 변경될 때마다 클래스의 버전도 변경될 수 있기 때문입니다.
만약 serialVersionUID를 선언하지 않으면, 스프링 시큐리티의 버전이 변경될 때마다 역직렬화 과정에서 InvalidClassException이 발생할 수 있습니다.

📌 스프링 시큐리티에서 인증처리 클래스를 생성할 때 serialVersionUID를 선언하여, 클래스의 버전이 변경되어도 역직렬화 과정에서 오류가 발생하지 않도록 해주었습니다.

✅ GrantedAuthority

스프링 시큐리티는 인증된 사용자의 정보를 Authentication 객체에 저장합니다. Authentication 객체에는 getAuthorities() 메서드가 있는데, 이 메서드를 통해 GrantedAuthority 객체의 컬렉션을 가져옵니다.

📌 인증된 사용자의 권한을 저장하기 위해 사용됩니다.


✅ method 종류

methodreturn 타입return 값
getAuthorities()Collection<? extends GrantedAuthority>사용자의 권한 정보
getPassword()String사용자의 비밀번호 정보
getUsername()String사용자의 아이디 정보
isAccountNonExpired()boolean사용자의 계정 유효 기간 정보
isAccountNonLocked()boolean사용자의 계정 잠금 상태
isCredentialsNonExpired()boolean사용자의 비밀번호 유효 기간 정보
isEnabled()boolean사용자 계정의 활성화 상태

CustomUserDetailsService class

UserDetailsService 인터페이스를 이용해 인증된 사용자 정보와 권한을 반환하는 클래스를 생성해줄겁니다.
클래스 명을 CustomUserDetailsService 라고 설정하고 진행하겠습니다!!

@Service
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {

	private final UserinfoDAO userinfoDAO;
	
	@Override
	public UserDetails userById(String id) throws UsernameNotFoundException {
		Userinfo userinfo=userinfoDAO.selectUserinfoLogin(id);
		
		if(userinfo == null) {
			throw new UsernameNotFoundException(id);
		}
		return new CustomUserDetails(userinfo);
	}
}

📌 매개변수로 아이디를 전달받아 사용자 정보를 검색하여 검색된 사용자 정보를 이용해,
사용자 정보와 권한을 저장한 UserDetails 객체를 반환하여 인증 처리되도록 해줍니다.

유저 정보가 있다면 CustomUserDetails 클래스로 인증 정보를 반환합니다.

0개의 댓글