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')
setAuthenticationToContext() 메서드에서 의심되는 부분을 찾았다.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);
}
해당 부분에 디버깅을 해보았다.

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

roleAuthorityUtils.createAuthorities((List) claims.get("roles")); 에서 claims.get(”roles”)의 결과가 “ROLE_USER” 인데 이를 (List) 로 캐스팅할 수 없어서 인 것 같다.
즉, claims 의 타입이 Map<String, Object> 인데 key 값인 “roles”로 Object 타입의 value 값을 가져왔는데 그것이 String 타입인 것이다. 그렇다면 Claims 를 생성할 때, value의 타입인 Object에 List 타입으로 넣어주면 되지 않을까?
그래서 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 가 적용되어 있는 엔티티 클래스에서 컬렉션은 연관관계를 맺는 경우가 아니면 그냥 쓸 수 없었다.