[Spring] Spring Security (Part.2) 보안설정방법(XML, Java Config, Annotation)
- -
Spring Security 보안설정방법
Spring Security에서는 권한 (authority) 혹은 역할 (role)을 표현할 때 일반적으로 "ROLE_" 접두어를 사용하는 것을 참조
1) XML 방식
① XML 방식의 특징
● 장점
- 선언적 설정 : 선언적이므로 어플리케이션의 흐름에 대한 세부적인 제어 없이도 보안 설정을 할 수 있습니다.
- 분리성 : Java 코드와 완전히 분리되어 있으므로, 보안 설정 변경이 프로그램 로직에 영향을 미치지 않습니다.
- 설정 변경 용이 : XML파일은 코드의 컴파일 없이 수정이 가능합니다.
● 단점
- 떨어지는 가독성
- 타입의 안정성이 없어, 실행시에만 오타 및 잘못된 값을 발견할 수 있습니다.
→ 오래된 방식으로 Spring Security 5 이전의 버전에서 주로 사용
② XML 방식 사용법
1. 의존성 추가
● Maven의 경우
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
● Gradle의 경우
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
}
2. Web.xml에 보안필터 추가
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3. spring-security.xml 설정
/admin/**으로 시작하는 URL은 "ROLE_ADMIN" 권한을 가진 사용자만 접근 가능하도록 설정
예시
<http auto-config="true">
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<form-login
login-page="/login"
default-target-url="/home"
authentication-failure-url="/login?error" />
<logout logout-success-url="/login?logout" />
</http>
2) Java Configuration 방식
① Java Configuration 방식의 특징
● 장점
- 잘못된 구성이나 오타 등의 문제는 컴파일 시점에 대부분 감지
- XML보다는 직관적
- Spring 프레임워크의 일부로 통합되어 있어, 다른 Spring 기능과의 통합이 간편
● 단점
- XML에 비해 더 많은 코드를 필요
② Java Configuration 방식 사용법
1. 의존성 추가
● Maven의 경우
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
● Gradle의 경우
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
}
2. Configuration 클래스 생성
////예시입니다//////
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class WebSecurity {
private static final String[] WHITE_LIST = {
"/users/**",
"/**"
};
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// CSRF protection
.csrf(csrf -> csrf.disable())
// Frame Options
.headers(headers -> headers.frameOptions(frameOptions -> frameOptions.disable()))
// Authorization
.authorizeHttpRequests(authorize -> authorize
.requestMatchers(WHITE_LIST).permitAll()
.requestMatchers(PathRequest.toH2Console()).permitAll());
return http.build();
}
}
※ antMatchers, mvcMatchers, WebSecurityConfigurerAdapter 등 Spring security 관련 코드들이 deprecated되었으므로,
위와 같이 사용하면 됩니다.
3) Annotation 방식
① Annotation 방식의 특징
● 장점
- 해당 로직이나 기능 위에 직접 어노테이션을 적용하여 보안 정책을 알기 쉽습니다.
- XML이나 Java Config와 비교할 때 보안 설정을 위한 추가적인 코드나 설정이 크게 줄어듭니다.
● 단점
- 큰 프로젝트에서는 어노테이션 기반의 보안 설정이 여러 코드 부분에 흩어져 있을 수 있어,
전체 보안 구성을 파악하기 어려울 수 있습니다. - 개발자가 실수로 중요한 로직에 보안 어노테이션을 누락할 위험이 있습니다.
② Annotation 방식 사용법
1. 의존성 추가
● Maven의 경우
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
● Gradle의 경우
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
}
2. Config클래스 생성
@Configuration
@EnableWebSecurity
//Spring Security를 사용하여 웹 보안을 활성화하겠다는 것
@EnableGlobalMethodSecurity(prePostEnabled = true)
// 메서드 수준에서의 보안 설정을 활성화하려 할 때 사용
// 서비스 또는 컨트롤러의 메서드에 직접 보안 어노테이션을 추가하여,
// 특정 권한을 가진 사용자만이 해당 메서드를 실행할 수 있도록 할 수 있습니다.
public class SecurityConfig {
// ...
}
3. @PreAuthorize, @PostAuthorize, @Secured로 보안 설정
● @PreAuthorize
메서드를 호출하기 전에 특정 조건을 만족하는지 검사하는 어노테이션
SpEL (Spring Expression Language) 표현식을 사용하여 복잡한 권한 체크를 수행할 수 있습니다.
@PreAuthorize("hasRole('ROLE_ADMIN')")
// hasRole로 Admin 권한이 있는지 확인합니다.
public void adminMethod() {
// ... 로직
}
* @PreAuthorize 권한과 조건이 있는 경우
@PreAuthorize("hasRole('ROLE_USER') and #user.id == authentication.principal.id")
//만약 권한뿐 아니라 특정 아이디만 가능하게 조건을 걸 때
public void userMethod(User user) {
// ... 로직
}
* @PreAuthorize 권한이 여러개 필요한 경우
@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_MANAGER', 'ROLE_USER')")
//여러 권한이 필요한 경우, hasAnyRole로 권한 검증
public void multiRoleAccessMethod() {
// ... 로직
}
● @PostAuthorize
메서드가 실행된 후에 반환 값을 기반으로 특정 조건을 만족하는지 검사합니다.
SpEL 표현식을 사용하여 반환 값에 기반한 검사를 수행할 수 있습니다.
@PostAuthorize("returnObject.ownerId == authentication.principal.id")
// return한 id값으로 권한 확인
public Document getDocument(Long documentId) {
// ... 로직
return document;
}
● @Secured
주어진 권한들을 가진 사용자만 메서드에 접근할 수 있게 합니다.
@Secured는 @PreAuthorize보다 단순하며, SpEL 표현식을 사용할 수 없습니다.
@Secured("ROLE_ADMIN")
public void adminMethod() {
// ... 로직
}
'Spring' 카테고리의 다른 글
[Spring] Spring Security (Part.1) - 개념, 인증(Authentication), 권한 부여(Authorization)에 대한 설명 및 작동순서 (0) | 2023.07.25 |
---|---|
[Spring] Spring Scheduler 이용하여 Slack 자동 알림 구현하기 (Slack 연동) (0) | 2023.07.20 |
[Spring] Batch와 Scheduler (0) | 2023.07.19 |
[Spring] Pageable과 PageRequest 개념과 비교 (0) | 2023.07.19 |
[Spring] Spring MVC 구조 (0) | 2023.06.30 |
소중한 공감 감사합니다