푸들푸들

[Error] Spring Security 적용 본문

구디아카데미/Error

[Error] Spring Security 적용

COCO_develop 2025. 2. 5. 15:31

공지글 수정 페이지는 글 작성자 본인만 접근이 가능해야함.

수정 버튼이 본인에게만 노출되게 적용해놨으나,

일정한 패턴의 url을 사용하다보니 수정 링크가 추측이 가능함.

링크를 입력해서 접속할 시, 누구나 공지글 수정이 가능해짐.

-> 글 작성자가 아닌 사람의 해당글 수정페이지 접근을 막아야함.

 

@GetMapping("/board/modifyNotice")
public String modifyNotice(@RequestParam Integer boaNo, Model model) {
    Map<String, Object> board = boardService.getBoardOne(boaNo);
    // 글 작성자와 다른 사원 접근 막기
    int empNo = (int)board.get("empNo");
    CustomUserDetails details = (CustomUserDetails)SecurityContextHolder.getContext().getAuthentication().getDetails();
    int loginEmpNo = details.getEmpNo();
    log.debug("empNo ={}, loginEmpNo={}",empNo,loginEmpNo);
    if(loginEmpNo != empNo) {
        throw new IllegalArgumentException("인증되지 않은 회원입니다.");
    }

    model.addAttribute("b", board);

    List<BoardFile> boardFiles = boardService.getBoardFiles(boaNo);
    model.addAttribute("boardFiles", boardFiles);

    return "board/modifyNotice";
}

 

오류

: 잘못된 타입 캐스팅 - WebAuthenticationDetails는 Spring Security에서 인증 세부 정보를 담는 클래스이고, CustomUserDetails는 사용자 정의 사용자 세부 정보를 담는 클래스. 이 둘은 서로 다른 타입이므로 직접적으로 캐스팅할 수 없음.

CustomUserDetails details = (CustomUserDetails)SecurityContextHolder.getContext().getAuthentication().getDetails();

이 부분이 오류의 원인인듯

 

->

getDetails()를 getPrincipal()로 변경해봄

CustomUserDetails details = (CustomUserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

 

예외처리되어 잘 돌아간듯..?

이걸 다른 페이지로 가게 만들어야겠다 (return)

@GetMapping("/board/modify")
public String modifyBoard(@RequestParam Integer boaNo, Model model) {
    Map<String, Object> board = boardService.getBoardOne(boaNo);

    // 글 작성자와 다른 사원 접근 막기
    int empNo = (int)board.get("empNo");
    CustomUserDetails details = (CustomUserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    int loginEmpNo = details.getEmpNo();
    log.debug("empNo ={}, loginEmpNo={}",empNo,loginEmpNo);
    if(loginEmpNo != empNo) {
        return "redirect:/board/" + boaNo;
    }

    model.addAttribute("b", board);

    List<Category> categoryList = categoryService.getCategoryListFree();
    model.addAttribute("categoryList", categoryList);

    List<BoardFile> boardFiles = boardService.getBoardFiles(boaNo);
    model.addAttribute("boardFiles", boardFiles);

    return "board/modify";
}

 

해결!

 

 

 

 

chat GPT

getDetails() vs getPrincipal() 차이점

  • getPrincipal():
    • 주로 UserDetails 또는 사용자 객체를 반환합니다.
    • 인증된 사용자 정보(예: 사용자 ID, 권한 등)를 포함하고 있음.
    • 커스텀 UserDetails를 구현하면 여기에 중요한 사용자 정보를 담을 수 있음.
  • getDetails():
    • 주로 WebAuthenticationDetails 또는 기타 인증 관련 부가 정보를 반환함.
    • IP 주소, 세션 ID 등의 정보를 포함할 수 있음.
    • 특정 인증 방식(OAuth2, JWT 등)에 따라 다를 수 있음.

 

보안적인 이유

✅ getPrincipal()이 더 안전한 이유:

  1. getDetails()는 인증 정보가 아닌 부가 정보 포함
    • getDetails()에는 세션 ID, IP 주소 등의 정보가 포함될 수 있으므로, 이를 직접 활용하는 것은 보안상 위험할 수 있음.
    • IP 주소 등은 변경 가능하고 신뢰할 수 없는 정보일 수도 있음.
  2. getPrincipal()은 사용자 인증 정보에 초점
    • getPrincipal()은 UserDetails 객체를 반환하므로, 이를 사용하면 인증된 사용자의 신뢰할 수 있는 정보를 안전하게 가져올 수 있음.
  3. 사용자 정보 검증 및 활용이 쉬움
    • getPrincipal()을 사용하면 UserDetails 인터페이스를 통해 사용자 권한을 검증하거나 필요한 정보를 가져오기 용이함.
    • 반면, getDetails()는 특정 인증 방식에 따라 다르게 구현될 수 있으므로, 예상치 못한 값이 포함될 가능성이 있음.
  4. Null 가능성 및 예외 처리
    • getDetails()는 일부 인증 방식에서는 null이 될 수도 있어 예상치 못한 NullPointerException이 발생할 위험이 있음.
    • getPrincipal()은 기본적으로 인증된 사용자의 정보를 포함하므로, 안전하게 정보를 가져올 수 있음.

'구디아카데미 > Error' 카테고리의 다른 글

[Error] 모달 fetch 404  (0) 2025.01.23
[Error] 탭 변경 시 CSS 깨짐  (0) 2025.01.14
[Error] Jsp <script> ${} 오류  (1) 2025.01.14
[Error] 400 오류 - Spring Security  (0) 2025.01.13
[Error] 500 오류  (0) 2024.11.14