본문 바로가기

Study Information Technology

Spring Boot 애플리케이션에서 세밀한 권한 부여 구현하기

728x90
반응형

Spring Boot 애플리케이션에서 세밀한 권한 부여 구현하기

Overview
Spring Boot 애플리케이션에서 세밀한 권한 부여를 구현하는 것은 애플리케이션의 보안을 강화하고 사용자에게 맞춤형 접근 제어를 제공하는 중요한 작업입니다. 이 과정에서는 Spring Security를 활용하여 사용자의 권한에 따라 세밀한 접근 제어를 설정하는 방법을 살펴보겠습니다.


1. Spring Security 설정

먼저, Spring Security를 프로젝트에 추가합니다. build.gradle 또는 pom.xml 파일에 다음 의존성을 추가하세요.

Gradle:

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
}

Maven:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Spring Security는 기본적으로 모든 요청을 인증이 필요하다고 가정합니다. 세밀한 권한 부여를 위해 커스텀 보안 구성을 추가해야 합니다.

2. 사용자 정의 권한 설정

UserDetailsService를 구현하여 사용자의 세부 정보를 제공하는 클래스를 작성합니다. 이 클래스는 사용자 인증과 권한 부여에 필요한 정보를 제공하는 역할을 합니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class CustomUserDetailsService implements UserDetailsService {

@Autowired
private UserRepository userRepository; // 사용자 정보를 가져오는 리포지토리

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("사용자를 찾을 수 없습니다: " + username);
}
return new CustomUserDetails(user);
}
}

여기서 CustomUserDetails 클래스는 UserDetails 인터페이스를 구현하여 사용자 정보와 권한을 Spring Security에 제공합니다.

3. 권한에 따른 접근 제어

세밀한 권한 제어를 위해 @PreAuthorize 또는 @Secured 애너테이션을 활용할 수 있습니다. 예를 들어, 특정 메서드에 대해 권한을 제한할 수 있습니다.

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class MyController {

@GetMapping("/admin")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String adminEndpoint() {
return "관리자만 접근 가능합니다.";
}

@GetMapping("/user")
@PreAuthorize("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')")
public String userEndpoint() {
return "사용자 또는 관리자만 접근 가능합니다.";
}
}

@PreAuthorize 애너테이션은 SpEL(Spring Expression Language)을 사용하여 접근 제어를 구현합니다. 위의 예에서는 /admin 엔드포인트는 ROLE_ADMIN 권한을 가진 사용자만 접근할 수 있고, /user 엔드포인트는 ROLE_USER 또는 ROLE_ADMIN 권한을 가진 사용자만 접근할 수 있습니다.

4. 커스텀 권한 관리

커스텀 권한을 정의하여 세밀한 접근 제어를 구현할 수도 있습니다. 이 과정에서 사용자의 권한을 정의하는 @Secured 또는 @PreAuthorize를 활용하여 보다 복잡한 권한 체계를 설정할 수 있습니다.

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

@Component
public class AccessControlService {

public boolean hasAccessToResource(String resourceId) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// 커스텀 권한 검증 로직
return authentication.getAuthorities().stream()
.anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals("ROLE_ADMIN"));
}
}

이 코드 조각은 사용자가 특정 자원에 대한 접근 권한을 가지고 있는지를 확인하는 방법을 보여줍니다. SecurityContextHolder를 통해 현재 인증 정보를 얻고, 사용자 권한을 기반으로 접근 여부를 결정합니다.

5. 권한 부여 관련 오류 처리

권한 부여 오류를 처리하는 것도 중요합니다. 예를 들어, 접근 권한이 부족한 경우, Spring Security는 AccessDeniedException을 발생시킵니다.

import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {

@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "접근이 거부되었습니다.");
}
}

이 핸들러는 사용자가 권한이 없는 자원에 접근할 때 적절한 오류 메시지를 반환합니다. SC_FORBIDDEN 상태 코드와 함께 오류 메시지를 반환하여 사용자가 권한이 없음을 알립니다.

참고문서

728x90
반응형