https://github.com/Team-Seollem/seollem-be/issues/20

포스트맨 테스트 결과

2023-02-06 23:21:27.348 WARN 16495 --- [nio-8080-exec-5] c.s.s.j.h.MemberAuthenticationEntryPoint : Unauthorized error happened: class java.lang.String cannot be cast to class java.util.List (java.lang.String and java.util.List are in module java.base of loader 'bootstrap')
private void setAuthenticationToContext(Map<String, Object> claims) {
  String username = (String) claims.get("username");
  List<GrantedAuthority> authorities =
      roleAuthorityUtils.createAuthorities((List) claims.get("roles")); // 이부분!
  Authentication authentication =
      new UsernamePasswordAuthenticationToken(username, null, authorities);
  SecurityContextHolder.getContext().setAuthentication(authentication);
}

해당 부분에 디버깅을 해보았다.

스크린샷 2023-02-07 오전 12.53.59.png

위 코드에서 66번 라인에서 예외가 발생하여 아래의 위치로 이동하는 것을 확인했다.

스크린샷 2023-02-07 오전 12.56.54.png

roleAuthorityUtils.createAuthorities((List) claims.get("roles")); 에서 claims.get(”roles”)의 결과가 “ROLE_USER” 인데 이를 (List) 로 캐스팅할 수 없어서 인 것 같다.

즉, claims 의 타입이 Map<String, Object> 인데 key 값인 “roles”로 Object 타입의 value 값을 가져왔는데 그것이 String 타입인 것이다. 그렇다면 Claims 를 생성할 때, value의 타입인 ObjectList 타입으로 넣어주면 되지 않을까?

그래서 Member 엔티티 클래스에서 다음과 같이 수정하였다.

//...

private List<String> roles; 

//...

public void setRoleList(String role){
  if(this.roles.isEmpty()){
    this.roles = new ArrayList<>();
    this.roles.add(role);
  }
  this.roles.add(role);
}

public List<String> getRoleList() {
  if (this.roles.isEmpty()) {
    return new ArrayList<>();
  }
  return roles;
}

그리고 MemberService 에서 다음과 같이 List를 Member 의 Role 으로 설정하도록 수정하였다.

public Member createMember(Member member, String authenticationCode) {
  verifyExistsEmail(member.getEmail());
  verifyValidAuthenicationCode(member.getEmail(), authenticationCode);
  member.setPassword(bCryptPasswordEncoder.encode(member.getPassword()));
  member.setRoleList("ROLE_USER");  // 수정한 부분!!
  Member savedMember = memberRepository.save(member);

  return savedMember;
}

다시 어플리케이션을 실행했더니, 다음과 같은 에러가 발생했다.

Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: member, for columns: [org.hibernate.mapping.Column(roles)]

즉, JPA 가 적용되어 있는 엔티티 클래스에서 컬렉션은 연관관계를 맺는 경우가 아니면 그냥 쓸 수 없었다.