서론
근 3일동안 과제 테스트가 있어 실컷 요구사항에 맞춰 서비스코드 작업을 하고 단위 테스트 작업을 마쳤다.
요구사항 중 권한에 따른 제약이 있었다.
회원을 구분짓고 상품에 대한 수정,삭제,생성의 권한은 판매자만 있도록 설정하는것이였다.
이 요구사항을 보고 Spring Security의 Role을 이용해야겠다는 생각이 떠올라서 이전에 사이드 프로젝트에서 구현한 내용들을 바탕으로 Jwt와 Spring Security를 기반으로 인증 인가 작업을 진행했었고, 오늘 단위 테스트 작업을 마치고 API를 작업 후 통합 테스트를 진행 하는데 문제가 발생했다.
본론
API 작업 이후 Security Config 파일에 API의 Path와 Method를 기반으로 권한에 따른 접근을 처리했다.
authorizeRequests()
.antMatchers(HttpMethod.GET, "/product").permitAll() // product Get Method 인가 미확인
.antMatchers(HttpMethod.POST, "/product").hasAuthority("ROLE_SELLER") // product post 인가 확인
.antMatchers(HttpMethod.PATCH, "/product").hasAuthority("ROLE_SELLER") // product patch 인가 확인
.antMatchers(HttpMethod.DELETE, "/product").hasAuthority("ROLE_SELLER") // product delete 인가 확인
.antMatchers("/order").authenticated() // order All Method 인가 확인
.antMatchers("/**").permitAll() // permitAll : 다른 모든 요청들을 인증이나 권한 없이 허용
.and()
다음과 같이 상품 조회는 모두 접근을 가능하게 하였고, 생성 수정 삭제의 경우 권한을 확인하였다.
Security 설정을 한 이후 회원가입을 하여 AccessToken을 받아와 상품 생성을 해보았다.
이 문제가 발생해서.. 어떤 부분이 원인인지 파악을 위해
application.yml 파일에 Spring Security 로그 설정을 DEBUG로 변경 후 로그를 확인해보았다.
로그를 봐도.. 그냥 문제가 발생했다는 내용밖에 찍히질 않아서,
이번엔 /test url을 만들고, 체크를 해보기로 했다.
@GetMapping("/test")
public void test(@AuthenticationPrincipal Members viewer){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// 현재 사용자의 권한 확인
if (authentication != null) {
for (GrantedAuthority authority : authentication.getAuthorities()) {
String authorityName = authority.getAuthority();
System.out.println("사용자의 권한: " + authorityName);
// 원하는 권한과 비교
if ("ROLE_SELLER".equals(authorityName)) {
// 사용자가 "ROLE_SELLER" 권한을 가지고 있는 경우의 처리
}
}
}
}
이렇게 설정해놓고, Debug로 찍어보았다.
디버깅으로 찍어보니, 저 authorities 의 size가 0으로 찍히는 것이였다.
문제가 무엇인지 Role 부분을 확인하다 순간 Member Entity를 만들며 UserDetails를 implements하고 Override한 메서드들을 그냥 대충 null 처리하고 넘어갔던것이 불현듯 스쳐지나갔다.
바로 이부분이.. 저 authorities 즉 권한을 return 해주는 메서드였던것 이였다.
스프링 시큐리티에서 제공하는 UserDetails의 Role은 컬렉션으로 다대다 테이블을 구현해서 (다중 권한을 위해서 인 것 같다.) 사용을 하기 때문에 리턴 타입이 Collection인 것 같다.
하지만 나는 단일 권한만 부여하면 구현 가능한 요구사항이였기 때문에 애초에 Enum으로 단순 RoleType만 사용했기 때문에
다음과 같이 Arrays.asList로 감싸서 return을 해주었다.
이렇게 설정을 해준 이후 다시 PostMan으로 테스트를 진행해보았다.
이어 customer로 설정 후 403이 정상적으로 떨어지는지도 테스트를 해보았다.
결론
분명 과제를 막 받았을 때 나름 자신이 있었는데..
역시 막상 작업을 해보니 공부를 부족하게 한 부분에서 문제가 발생을 했다.
이번 일을 계기로 Spring Security 뿐 만 아니라, 정확히 이해하지 못한 부분에 대해서 더 공부를 하고 사용을 하도록.. 노력해보자..!ㅠㅠ
'💻Spring' 카테고리의 다른 글
Spring Boot에서 Batch, Scheduler 사용기 (0) | 2023.12.08 |
---|---|
[REST API] GET 메서드에서의 데이터 전달 (0) | 2023.09.25 |
Spring Security 401,403 Custom Response 적용하기 (0) | 2023.08.24 |
MySQL , JPA 에서의 Batch Insert 적용기 (0) | 2023.08.08 |
JPA 프록시 객체 equals의 Override (0) | 2023.08.08 |