본문 바로가기
SpringBoot

[SpringSecurity] 예외 : InternalAuthenticationServiceException: A granted authority textual representation is required

by stonage 2023. 7. 1.

스프링 시큐리티의 로그인 기능에 대해서 공부하다가 다음과 같은 예외를 만났다.

InternalAuthenticationServiceException: A granted authority textual representation is required

 

 

 

 

직역하자면 내부 인증 서비스 예외가 발생하였고, 승인된 표현이 필요하다? 라는 의미인 것 같다. 구글링 해보니 로그인 서비스의 loadUserByUsername 메서드 내부에서 null 값이 들어와서 발생하는 예외라고 하였다. 발생한 위치는 해결한 방법 뒤에 기록해두겠다.

 

 

 

 

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    Optional<SiteUser> _siteUser = this.userRepository.findByusername(username);
    if (_siteUser.isEmpty()) {
        throw new UsernameNotFoundException("사용자를 찾을수 없습니다.");
    }
    SiteUser siteUser = _siteUser.get();
    List<GrantedAuthority> authorities = new ArrayList<>();
    if ("admin".equals(username)) {
        authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.getValue()));
    } 
    else {
        System.err.println(UserRole.USER.getValue());
        authorities.add(new SimpleGrantedAuthority(UserRole.USER.getValue())));
    }
    return new User(siteUser.getUsername(), siteUser.getPassword(), authorities);
}

 

 

우선 loadUserByUsername의 파라미터인 username을 로그로 찍어 콘솔창을 확인해보니 정상적으로 출력되는 것을 확인했다.

브라우저 상에 "사용자를 찾을 수 없습니다" 가 아닌 다른 문구가 뜬것과 로그를 loadUserByUsername의 return 문 바로 직전에 찍었을 때 콘솔 창에 로그가 기록되지 않은 것을 토대로 유저에게 롤을 부여하는 부분에서 에러가 발생했을 것이라 짐작했다.

따라서 UserRole.ADMIN.getValue()를 로그로 찍어보니 아니나 다를까 null 이 찍혔다. 그리고 UserRole 파일을 확인해보니  enum 파일인 UserRole의 생성자 부분에서 변수명을 다르게 쓴 것을 발견했다.  해당 변수명을 일치시켜주니 잘 작동한다.

 

A granted authority textual representation is required 예외 메시지를 만난다면 당황하지 말고 loadUserByUsername 메서드에 null이 들어가는 부분이 없는지 체크해보자.

 

 

 

 

 

 

에러 발생 위치 확인

 

내가 작성한 코드에는 사용자에게 부여할 수 있는 롤은 크게 ADMIN과 USER 두 개로 나눈 상태이고, loadUserByUsername에서는 특정 사용자의 아이디를 입력받아 DB에 해당 유저 정보가 있는지 확인하여 유저가 존재한다면 해당 유저가 갖는 롤을 부여하는 방식이다. 

if ("admin".equals(username)) {
    authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.getValue()));
}

 

여기서 SimpleGrantedAuthrity 생성자에 enum 파일인 UserRole의 ADMIN 의 value가 들어가는데

 

 

 

 

public final class SimpleGrantedAuthority implements GrantedAuthority {

	private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;

	private final String role;

	public SimpleGrantedAuthority(String role) {
		Assert.hasText(role, "A granted authority textual representation is required");
		this.role = role;
	}
    
    ...생략...
}

 

SimpleGrantedAuthrity에서 전달받은 role이 null 인지 혹은 비어있는지 여부를 Assert.hasText 메서드로 확인한다. 

 

 

 

 

public static void hasText(@Nullable String text, String message) {
    if (!StringUtils.hasText(text)) {
        throw new IllegalArgumentException(message);
    }
}
public abstract class StringUtils {

	//생략

    public static boolean hasText(@Nullable String str) {
            return (str != null && !str.isEmpty() && containsText(str));
            
    //생략
    
}

 

만약 전달받은 문자열(role)이 null 이거나 비어있으면 SimpleGrantedAuthority에서 전달받은

"A granted authority textual representation is required"

에러 메시지를 띄우는 것이다. 

'SpringBoot' 카테고리의 다른 글

[SpringBoot] 스프링 부트 Hello, World! 페이지 띄우기  (0) 2023.06.20