SPRING SECURITY: 사용자 정의 가능한 인증 및 액세스 제어 프레임워크
1. 로그인, 로그아웃, 역할 기반 접근 제어 기능을 제공하여 강력한 인증 및 권한을 부여할 수 있다.
2. SQL Injection, CSRF, XSS(크로스사이트 스크립팅) 등의 보안 위협을 방지해준다.
3. 다양한 인증 방식(JWT, OAuth2, SAML 등)과의 연동 가능하다.
4. Spring Security의 필터 체인으로 요청을 보호한다.
인증
사용자가 로그인을 하면 그 사용자의 신원을 확인해야한다. LDAP, OAUTH 2.0, JWT등 사용자의 신원을 인증하는 방식을 지원한다.
권한 부여
특정 URL이나 API에 대한 접근 권한을 제어한다.
예를 들면, 학교 반 선생님들이 학교 홈페이지에서 반 학생들의 정보를 볼 수 있는 페이지와, 반 학생들은 각자의 정보만 볼 수 있는 페이지대로 따로 페이지 별로 접근 가능한 권한을 부여하는 것이다.
이를 위헤 @PreAuthorize, @Secured, @RolesAllowed 어노테이션을 활용하여 역할 기반 접근 설정 가능하다.
비밀번호 암호화
PasswordEncoder 인터페이스를 제공하여 BCrypt, Argon2 등의 암호화 알고리즘 사용 가능하다.
세션 관리 및 보안
동시 세션 제어, 세션 고정 보호, 자동 로그아웃 등의 기능 제공한다.
CSRF(Cross-Site Request Forgery) 보호
CSRF(Cross-Site Request Forgery)
웹 애플리케이션에서 사용자의 인증된 세션을 악용하여 원하지 않는 요청을 실행하게 만드는 공격입니다.
즉, 사용자가 의도하지 않은 요청을 특정 웹사이트에 전송하도록 유도하는 방식입니다.
CSRF 공격의 원리
1 .사용자가 A 웹사이트(정상적인 사이트)에 로그인하여 세션을 유지한 상태.
2. 공격자가 B 웹사이트(악성 사이트)를 만들어 사용자가 클릭하도록 유도 (예: 이메일, 링크, 이미지 태그 등에 포함).
3. 사용자가 B 웹사이트에 접속하면, 브라우저는 A 웹사이트로 요청을 보냄 (이때, 기존의 로그인 세션과 쿠키가 자동으로 포함됨).
4. 공격자는 사용자의 계정으로 A 웹사이트에서 원하지 않는 작업을 수행할 수 있음.예: 계좌 이체, 비밀번호 변경, 게시글 작성 등.
기본적으로 CSRF 공격을 방어하는 기능이 활성화됨
필요에 따라 csrf().disable()로 비활성화 가능
CORS(Cross-Origin Resource Sharing) 설정
CORS(Cross-Origin Resource Sharing)
다른 도메인(origin)에서 요청을 보낼 때 발생할 수 있는 보안 문제를 해결하기 위한 정책입니다.
즉, 기본적으로 웹 브라우저는 보안상의 이유로 다른 도메인의 리소스 요청을 차단합니다
CORS 공격의 원리
1. 예를 들어, 사용자가 A 웹사이트 (http://example.com)에서 로그인한 상태.
2. 악성 사이트 B (http://attacker.com)가 A 사이트의 API를 호출하여 민감한 정보를 요청할 수 있음.
3. 브라우저는 기본적으로 CORS 정책을 통해 차단하지만, 서버에서 허용 설정을 잘못하면 공격자가 데이터를 탈취할 수 있음.
cors() 설정을 통해 다른 도메인의 요청을 허용하거나 차단 가능
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://example.com") // 특정 도메인 허용
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(true);
}
};
}
보안 필터 체인(Security Filter Chain)
여러 개의 보안 필터를 통해 인증과 권한 부여를 처리
SecurityFilterChain을 설정하여 특정 요청에 대한 보안 규칙을 정의 가능
Spring Security는 여러 개의 필터(Filter)로 구성된 체인 구조를 사용하여 보안 기능을 처리
동작 과정
- 사용자가 API 요청을 보냄 (예: 로그인 요청)
- 필터 체인(Filter Chain)이 요청을 순차적으로 처리
- 순서 (일반적인 Spring Security 필터 체인)
- SecurityContextPersistenceFilter → 보안 컨텍스트 유지
- UsernamePasswordAuthenticationFilter → 기본 로그인 인증
- BasicAuthenticationFilter → HTTP Basic 인증 처리
- BearerTokenAuthenticationFilter → JWT 인증 처리
- ExceptionTranslationFilter → 인증/권한 오류 처리
- FilterSecurityInterceptor → 최종 접근 제어 결정
- 순서 (일반적인 Spring Security 필터 체인)
- 인증이 완료되면, Security Context에 인증된 사용자 정보가 저장됨
- 이후의 요청에서는 해당 정보(Security Context)를 참조하여 권한을 확인하고 처리
Spring Security의 필터 체인은 SecurityFilterChain을 통해 직접 설정할 수도 있습니다.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable()) // CSRF 보호 비활성화 (필요 시 설정)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN") // 관리자 페이지 접근 제한
.requestMatchers("/user/**").hasRole("USER") // 일반 사용자 접근 제한
.anyRequest().permitAll() // 나머지 요청은 허용
)
.formLogin(Customizer.withDefaults()) // 기본 로그인 설정
.build();
}
Authentication과 Authorization의 차이점
- 인증(Authentication) 과정
- 사용자가 아이디와 비밀번호를 입력하여 로그인 요청
- Spring Security가 인증을 수행 (예: UserDetailsService를 통해 사용자 확인)
- 인증이 성공하면, Security Context에 사용자 정보가 저장됨
- 이후 요청에서는 Security Context의 인증 정보를 바탕으로 권한을 검증
- 권한 부여(Authorization) 과정
- 사용자가 특정 리소스에 접근하려고 시도 (예: /admin 페이지)
- Spring Security가 사용자의 역할(Role)과 권한을 확인
- 권한이 충분하면 접근 허용, 없으면 403 Forbidden 응답
개념 | 설명 | 예제 |
Authentication (인증) | 사용자가 누구인지 확인하는 과정 | 로그인 (ID, 비밀번호 확인) |
Authorization (권한 부여) | 사용자가 특정 작업을 수행할 수 있는지 결정하는 과정 | 특정 API를 호출할 권한이 있는지 확인 |
Spring Security 세부 설정
1) @EnableWebSecurity와 @Configuration의 역할
- @EnableWebSecurity는 Spring Security를 활성화하는 어노테이션으로, Spring Boot에서 보안 관련 설정을 적용할 수 있도록 한다.
- @Configuration은 Spring 설정 클래스로 인식되도록 설정하는 역할을 한다.
- 함께 사용하여 보안 관련 설정을 구성하는 클래스를 정의할 수 있다.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// 보안 설정
}
2) UserDetailsService의 역할
- 사용자 정보를 DB에서 조회하여 UserDetails 객체로 반환해준다.
package org.example.final1.config.auth;
import lombok.AllArgsConstructor;
import org.example.final1.model.UserDto;
import org.example.final1.repository.User.UserDao;
import org.example.final1.repository.User.UserDaoInter;
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
@AllArgsConstructor
public class PrincipalDetailService implements UserDetailsService {
private final UserDaoInter userDaoInter;
@Override
public UserDetails loadUserByUsername(String user_email) throws UsernameNotFoundException {
UserDto userDto=userDaoInter.findByEmail(user_email);
// DB에서 사용자 정보 조회
if(userDto!=null){
return new PrincipalDetails(userDto);
}
System.out.println("User not found with email: " + user_email);
return null;
}
}
3) AuthenticationProvider의 역할
- 비밀번호 검증 및 인증 처리로 사용자 인증 수행한다.
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
// 비밀번호 검증 로직
if (!password.equals("expectedPassword")) {
throw new BadCredentialsException("비밀번호 불일치");
}
return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList());
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
4) SecurityFilterChain
- 시큐리티 필터가 로그인 경로를 처리할때, 보안을 설정할 수 있다.
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public").permitAll()
.anyRequest().authenticated()
)
.build();
}
}
'cs정리' 카테고리의 다른 글
세션 ID VS JWT (1) | 2025.02.06 |
---|---|
JWT를 이용한 인증 방식의 동작 원리 (0) | 2025.02.05 |
spring IOC 컨테이너란? (0) | 2024.11.11 |
스프링 빈 주입시 생기는 문제들 (0) | 2024.11.09 |
SPRING BEAN이란 (0) | 2024.11.09 |