티스토리 뷰

Spring에서 테스트를 돌리는 중 Unauthorized(401)가 아닌 Forbidden(403)이 발생하는 문제가 생겼다.

@RestController
@RequiredArgsConstructor
public class PostController {

    private final PostService postService;

    @PreAuthorize("isAuthenticated()")
    @PostMapping("/api/bbs/{name}/posts")
    public void post(@PathVariable String name,
                     @Valid @RequestBody WritePost request,
                     @AuthenticationPrincipal ExternalUser externalUser) {
        postService.write(name, externalUser.getId(), request);
    }
}

위는 게시물을 작성할때 로그인 한 사용자만 가능하도록 한 기능이다.
로그인하지 않은 사용자가 접근하면 아래 Security Config안에 authenticationEntryPoint에서 정의 한 대로 Unauthorize관련 Exception이 발생해야 한다.

@EnableWebSecurity
public class ClientSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 생략..
                .and()
                .exceptionHandling()
                .accessDeniedHandler(dogpigAccessDeniedHandler())
                .authenticationEntryPoint(dogpigEntryPoint())
                // 생략...
    }
}
@RequiredArgsConstructor
public class DogpigEntryPoint implements AuthenticationEntryPoint {

    private final ObjectMapper objectMapper;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        String json = DogpigResponse.builder()
                .message("로그인이 필요합니다.")
                .httpStatus(UNAUTHORIZED)
                .build()
                .toJson(objectMapper);

        response.setContentType(APPLICATION_JSON_UTF8.toString());
        response.setStatus(UNAUTHORIZED.value());
        response.getWriter().write(json);
    }
}

곰곰히 쌀국수를 먹으며 생각했다.
스프링에서 '로그인하지 않은 사용자'가 아닌 '익명 사용자'로 판단하기 때문에 Forbidden이 발생한게 아닐까..?
그래서 Security 설정에 아래와 같이 anonymous를 off하도록 했다.

http.authorizeRequests()
    .anonymous().disable()
    ... 생략

그러고 나니 정상적으로 Unauthorize Exception이 잘 작동했다.

댓글
댓글쓰기 폼