📌 스프링 시큐리티로 로그인과 회원가입을 구현하면 기존에 사용하는 UserDTO에 더해서 인증처리를 도와줄 DTO 클래스를 하나 더 생성해서 사용하게됩니다.
UserDetails 라는 클래스를 이용하는데요, 이것은 스프링 시큐리티에서 제공하는 표준 인터페이스입니다. 이 클래스를 이용하면 쉽게 스프링 시큐리티 기능을 사용할 수 있습니다!!
그리고 어느정도 사용자에 따라 커스터마이징 해서 사용할 수 있다는 것도 장점인것 같습니다. 🙂
바로 구현해보겠습니다.
@Data
public class Userinfo {
private String id;
private String pw;
private String name;
private int status;
private String enabled;
private List<UserinfoAuth> securityAuthList;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserinfoAuth {
private String id;
private String auth;
}
기존 DTO 클래스에서 추가로 UserDetails 클래스를 이용해 클래스를 생성할건데,
클래스 명을 CustomUserDetails 라고 설정하고 진행해보겠습니다.
@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;
}
}
}
private static final long serialVersionUID = 1L;
스프링 시큐리티를 구현하는데 중요한 클래스이기 때문에 선언해주었습니다.
스프링 시큐리티의 버전이 변경될 때마다 클래스의 버전도 변경될 수 있기 때문입니다.
만약 serialVersionUID를 선언하지 않으면, 스프링 시큐리티의 버전이 변경될 때마다 역직렬화 과정에서 InvalidClassException이 발생할 수 있습니다.
📌 스프링 시큐리티에서 인증처리 클래스를 생성할 때 serialVersionUID를 선언하여, 클래스의 버전이 변경되어도 역직렬화 과정에서 오류가 발생하지 않도록 해주었습니다.
스프링 시큐리티는 인증된 사용자의 정보를 Authentication 객체에 저장합니다. Authentication 객체에는 getAuthorities() 메서드가 있는데, 이 메서드를 통해 GrantedAuthority 객체의 컬렉션을 가져옵니다.
📌 인증된 사용자의 권한을 저장하기 위해 사용됩니다.
method | return 타입 | return 값 |
---|---|---|
getAuthorities() | Collection<? extends GrantedAuthority> | 사용자의 권한 정보 |
getPassword() | String | 사용자의 비밀번호 정보 |
getUsername() | String | 사용자의 아이디 정보 |
isAccountNonExpired() | boolean | 사용자의 계정 유효 기간 정보 |
isAccountNonLocked() | boolean | 사용자의 계정 잠금 상태 |
isCredentialsNonExpired() | boolean | 사용자의 비밀번호 유효 기간 정보 |
isEnabled() | boolean | 사용자 계정의 활성화 상태 |
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 클래스로 인증 정보를 반환합니다.