• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

기본 DaoAuthenticationProvider사용시 인증객체 조회 에러

23.03.01 23:15 작성 23.03.01 23:15 수정 조회수 761

0

프로젝트를 다시 만들어 실습을 진행중에 있습니다.

이번 프로젝트에서는 CustomAuthenticationProvider를 생성하지 않고 기본으로 사용되는 DaoAuthenticationProvider를 사용할려고 CustomAuthenticationProvider를 등록하지 않았습니다.

그런데

@GetMapping("/denied")
public String accessDenied(@RequestParam(value = "exception", required = false) String exception, Model model) {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    Account account = (Account)authentication.getPrincipal();
    model.addAttribute("username", account.getUsername());
    model.addAttribute("exception", exception);

    return "user/login/denied";
}

이 컨트롤러에서 인증 객체 조회가 되지 않아 에러가 발생했습니다.

기존 프로젝트의 CustomAuthenticationProvider에서의 인증 로직이 끝나고 UsernamePasswordAuthenticationToken타입으로 인증객체가 return되고 이것이 SecurityContext에 저장되는 흐름과

현재 진행중 프로젝트의 DaoAuthenticationProvider에서 인증 로직이 끝나고UsernamePasswordAuthenticationToken타입으로 인증객체가 return되고 이것이 SecurityContext에 저장되는 흐름이 완전히 동일하다고 생각되어서

기존 프로젝트와 똑같이 컨트롤러에서 인증객체가 조회될 것이라고 생각했는데 그렇지 않습니다.

혹시 인증 흐름상에서 제가 놓치고 있는 부분이 있는건가요?

답변 1

답변을 작성해보세요.

0

네 일단 DaoAuthenticationProvider 가 실행이 되지 않아서 그런 것 같습니다.

왜 인지는 정확히 테스트 해 봐야 될 것 같습니다.

소스 공유 가능할까요?

조우현님의 프로필

조우현

질문자

2023.03.03

https://github.com/woohyeonjoe/test

그런데 제가 디버깅을 걸어봤을땐 DaoAuthenticationProvider가 작동하는 것으로 확인되였습니다. 그래서 로그인이 정상적으로 작동하였고 이후 로그아웃 코드에서 Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

해당 코드가 정상작동하여 인증객체 조회를 하여 로그아웃 처리가 되었습니다.

그런데 이상하게 denied 컨트롤러에서만 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 이 코드로 인증객체 조회가 불가능합니다.

현 프로젝트는 Mysql로 진행하였고, 로그인시 email/password로 로그인하게 변경하였습니다.

 

인증객체 조회가 안되는 것이 아니라 타입캐스팅이 잘못 되어 있었습니다.

@GetMapping("/denied")
public String accessDenied(@RequestParam(value = "exception", required = false) String exception, Model model) {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    Account account = (Account)authentication.getPrincipal();
    model.addAttribute("username", account.getUsername());
    model.addAttribute("exception", exception);

    return "user/login/denied";
}

위에 보시면 다음과 같은 코드가 있는데

Account account = (Account)authentication.getPrincipal();

principal 은 Account 가 아니라 AccountContext 로 저장되어 있습니다.

그래서

AccountContext account = (AccountContext)authentication.getPrincipal(); 

와 같이 AccountContext 로 캐스팅 하시면 됩니다.

다만 CustomAuthenticationProvider 에서는 아래와 같이

UsernamePasswordAuthenticationToken authenticationToken
        = new UsernamePasswordAuthenticationToken(accountContext.getAccount(), null, accountContext.getAuthorities());

principal 속성에 accountContext.getAccount() 를 직접 저장했기 때문에 오류가 발생하지 않았습니다.

DaoAuthenticationProvider 는 UserDetails 타입의 AccountContext 객체를 principal 에 저장하는 차이가 있다고 보시면 됩니다.

조우현님의 프로필

조우현

질문자

2023.03.07

답변 너무 감사합니다.

시큐리티 강의와 강사님의 질의응답으로 너무 많은 도움을 받고 있습니다.

다시 한번 감사드립니다.