항해99 TIL - 29

강민범·2023년 11월 22일
0

BOARD 게시물을 작성한 USER 또는 ADMIN 권한을 가진 경우 게시글을 수정, 삭제 할 수 있도록 기능을 구현하라는 조건이 있었다.
ADMIN만 권한을 갖거나 게시물을 작성한 USER에게만 권한을 갖도록 구현하는것은 어렵지 않은데 두가지 조건을 다 충족시키는것이 고민이되었다.

고민한 해결책

처음에는 WebSecurityConfig 파일에서

	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		// CSRF 설정
		http.csrf((csrf) -> csrf.disable());

		// 기본 설정인 Session 방식은 사용하지 않고 JWT 방식을 사용하기 위한 설정
		http.sessionManagement((sessionManagement) ->
			sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
		);

		http.authorizeHttpRequests((authorizeHttpRequests) ->
			authorizeHttpRequests
				.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() // resources 접근 허용 설정
				.requestMatchers("/").permitAll() // 메인 페이지 요청 허가
				.requestMatchers("/signup").permitAll()
				.requestMatchers("/signin").permitAll()
                .requestMatchers(HttpMethod.PUT, "/boards/**").hasAnyAuthority(UserRoleEnum.Authority.ADMIN, UserRoleEnum.Authority.USER)
				.anyRequest().authenticated() // 그 외 모든 요청 인증처리
		);

.requestMatchers(HttpMethod.PUT, "/boards/**").hasAnyAuthority(UserRoleEnum.Authority.ADMIN, UserRoleEnum.Authority.USER)

위의 코드를 추가하면 되지 않을까 생각했다.뒤에 USER는 서비스에서 ID값을 비교하는 구문을 추가해주면 모든 USER가 아니라 게시글을 작성한 USER가 걸러질줄 알았지만 테스트한 결과 ADMIN도 권한이 없다는 에러가 나왔다.

두번째로 생각한것이

@PreAuthorize("hasAnyRole('ADMIN','USER')")

조건이 필요한 기능마다 컨트롤러에서 메서드위에 어노테이션을 붙여주는것이였다. 그럼 똑같이 USER가 모든 USER가 아닌 게시글의 작성자 ID와 동일한 경우 해당 USER만 권한을 가질것이라 생각했지만 이 어노테이션도 ADMIN조차 권한이 부여되지않았다.

그래서 마지막으로 생각한것이 Service에서 현재 로그인되어있는 유저의 role이 admin인 경우, 게시글 작성자의 id과 현재 로그인되어있는 유저의 id 값을 비교해서 권한을 주도록 하였다.

@Transactional
	public BoardResponseDto updateBoard(BoardRequestDto boardRequestDto, Long userId, Long id) {
		User user = userRepository.findById(userId).orElseThrow(() ->
			new EntityNotFoundException("존재하지않는 유저입니다.")
		);

		Board board = boardRepository.findById(id).orElseThrow(() ->
			new EntityNotFoundException("존재하지않는 보드입니다.")
		);

		if (UserRoleEnum.ADMIN.equals(user.getRole())) {
			board.update(boardRequestDto);
			return new BoardResponseDto(board);
		}

		if (userId != board.getUser().getId()) {
			throw new EntityNotFoundException("보드를 수정 할 수 있는 권한이 없습니다.");
		}
		board.update(boardRequestDto);
		return new BoardResponseDto(board);

	}
profile
개발자 성장일기

0개의 댓글