금년도에 들어서면서 신규 프로젝트를 맡게되었습니다.

해당 프로젝트에서 역할은 Backend 영역으로 REST API 프로젝트에 대한 환경설정 및 서비스 개발입니다.

우선 해당 프로젝트는 Front 영역과의 인증 부분에서 JWT 방식을 이용했습니다. 그리고 추가로 Spring Security를 통한 보안성을 강화했습니다. 이렇게 기본적인 구성과 함께 Test API를 배포했습니다. 이때는 사용자 권한에 대해서 기본적으로 ROLE_USER, ROLE_ADMIN을 부여하였습니다. Spring Security에서 기본적으로 권한의 prefix가 `ROLE_`입니다. 그렇기에 Test API에서도 사용자 정보에서 권한정보값을 앞에서와 같이 지정하였습니다. 그러나 해당 프로젝트에서 권한 설정값은 앞의 규칙을 준수하지 않았습니다. 그렇기에 권한에 있어 prefix의 설정값을 변경해줄 필요가 있었습니다. 이 부분에 대해 알아보고 해결한 내용을 정리해보려합니다.

 

 

1. loadUserByUsername 재정의를 통해 해당 프로젝트에서 쓰이는 권한 값을 UserDetails interface를 implement한 AuthenticatedUser에 넣습니다.

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    AuthenticatedUser user = authMapper.selectSecurityUserInfo(username);

    if (user != null) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority(user.getThrzGrpId()));

        user.setAuthorities(authorities);
    }

    return user;
}

 

2. 정상적인 로그인시 JWT를 통해 사용자 정보가 담긴 Token값을 반환하고 해당 Token은 로그인 외 타 API를 호출 할 때 인증값으로 보내며, 서버에서 해당 사용자의 권한을 알 수 있습니다.

이때, SecurityConfig에서 JWT에 대한 Filter를 부여해서 정상적인 토큰인지 확인을 했습니다.

이후 해당 Token을 Request Header Authorization에 추가하고 특정 컨트롤러에 @PreAuthorize를 추가함으로써 정상 로그인 된 사용자의 권한을 체크하는 로직을 세웠습니다. 그러나 정상적으로 권한이 담겼음을 확인하였는데도 권한여부에서 false가 떨어졌습니다. 확인 결과 Spring Security에서 기본적으로 권한에 대해 prefix가 존재하면 해당 값은 `ROLE_`인걸 확인했습니다.(RoleVoter.class에서 확인 가능.)

// 시큐리티 컨텍스트 객체를 얻습니다.
SecurityContext context = SecurityContextHolder.getContext();

// 인증 객체를 얻습니다.
Authentication authentication = context.getAuthentication();

// 로그인한 사용자정보를 가진 객체를 얻습니다.
Principal principal = authentication.getPrincipal();

// 사용자가  가진 모든 롤 정보를 얻습니다.
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

 

3. 해당 prefix를 원하는 값으로 변경하는 과정은 매우 쉽습니다.

SecurityConfig에서 아래와 같이 GrantedAuthorityDefaults를 정의해주면 됩니다. 해당 값 설정 후 정상 로그인 후 해당 계정에 대한 권한 접근 가능여부 확인 결과 true를 확인 할 수 있었습니다.

@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
    return new GrantedAuthorityDefaults("TEST_");
}

 

알고보면 별거 아닌 내용이였지만, 지금까지 프로젝트 중에 권한에 있어서 ROLE_와 같이 prefix를 변경하는 일은 없었기에 해결하는 과정에서 조금 어려움은 있었지만 뜻깊은 과정이었습니다.

+ Recent posts