Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- SQLD
- github
- 오블완
- 코딩
- AJAX
- icon
- SQL
- vscode
- 기업설명회
- error
- JavaScript
- 웹개발
- java
- Eclipse
- HTML
- ChatGPT
- jQuery
- 배포
- jsp
- myBatis
- 깃허브
- restapi
- 자바
- bootstrap
- 이클립스
- 티스토리챌린지
- 스파르타코딩클럽
- spring
- Firebase
- CSS
Archives
- Today
- Total
푸들푸들
[Error] Spring Security 적용 본문
공지글 수정 페이지는 글 작성자 본인만 접근이 가능해야함.
수정 버튼이 본인에게만 노출되게 적용해놨으나,
일정한 패턴의 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()이 더 안전한 이유:
- getDetails()는 인증 정보가 아닌 부가 정보 포함
- getDetails()에는 세션 ID, IP 주소 등의 정보가 포함될 수 있으므로, 이를 직접 활용하는 것은 보안상 위험할 수 있음.
- IP 주소 등은 변경 가능하고 신뢰할 수 없는 정보일 수도 있음.
- getPrincipal()은 사용자 인증 정보에 초점
- getPrincipal()은 UserDetails 객체를 반환하므로, 이를 사용하면 인증된 사용자의 신뢰할 수 있는 정보를 안전하게 가져올 수 있음.
- 사용자 정보 검증 및 활용이 쉬움
- getPrincipal()을 사용하면 UserDetails 인터페이스를 통해 사용자 권한을 검증하거나 필요한 정보를 가져오기 용이함.
- 반면, getDetails()는 특정 인증 방식에 따라 다르게 구현될 수 있으므로, 예상치 못한 값이 포함될 가능성이 있음.
- 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 |