Post Board를 익명 게시판에서 회원가입과 로그인이 가능한 게시판으로 변경하기
spring security jwt 회원가입 및 로그인 구현 중.. 이런저런 오류가 발생했다.
해당 에러는 회원가입 기능 중 postman에서 json 방식으로 username과 password를 넘겨주었는데 인식하지 못하고 null로 넘어가면서 발생했다.
requestDto 앞에 @RequestBody
애너테이션을 추가하였더니 해결되었다.
@PostMapping("/user/signup")
public ResponseEntity<String> signup(@Valid @RequestBody
UserRequestDto requestDto, BindingResult bindingResult) {}
다음은 로그인 시도 중 username과 password를 DB에 저장된 값으로 알맞게 넘겨주었음에도 JwtAuthenticationFilter에서 로그인 시도 후 성공으로 넘어가지 못하고 실패로 자꾸만 넘어가는 오류가 발생했다.
이 오류는 왜 로그인이 실패했는지, 어디에서 실패했는지를 알기 힘들어 해결 하는데 상당히 오래 걸렸는데 알고보니 별 거 아니었다.. 시큐리티에 대한 이해가 부족했던 것 같다.
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
log.info("로그인 시도");
try {
UserRequestDto requestDto = new ObjectMapper().readValue(request.getInputStream(), UserRequestDto.class);
return getAuthenticationManager().authenticate(
new UsernamePasswordAuthenticationToken(
requestDto.getUsername(),
requestDto.getPassword(),
null
)
);
} catch (IOException e) {
log.error(e.getMessage());
throw new RuntimeException(e.getMessage());
}
}
...
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed)
throws IOException, ServletException {
log.info("로그인 실패");
response.setStatus(401);
}
처음엔 우선 request dto에 postman에서 넘겨준 json 데이터가 제대로 들어가지 않았나 확인해보았는데 디버깅해보니 제대로 들어가있었다. 한참 헤메다 알게된 사실... 스프링 시큐리티에서는 사용자의 role을 필수값으로 넣어주거나 인증 로직을 수정하여 role을 비교하지 않도록 변경해주어야한다. 해당 웹페이지에 관리자 페이지를 만들지 않을 계획이라 role을 추가하지 않았는데 이 때문에 제대로 된 인증이 이루어지지 않아 로그인이 실패한 것 같다.
User 엔티티에 role을 추가하고 회원가입 시 자동으로 USER로 role이 저장되도록 변경한 뒤, UserDetailImpl 클래스에 아래의 코드를 추가하였다.
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
UserRoleEnum role = user.getRole();
String authority = role.getAuthority();
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(authority);
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(simpleGrantedAuthority);
return authorities;
}
잘 해결되었다!
비밀 댓글입니다.