LUMI_dev
Spring Security - #1.Spring Security 프레임워크 - Filter 대신 인가,인증 편리하게 해줌 본문
Spring Security - #1.Spring Security 프레임워크 - Filter 대신 인가,인증 편리하게 해줌
luminous_dev 2025. 2. 6. 17:53'Spring Security' 프레임워크는 Spring 서버에 필요한 인증 및 인가를 위해 많은 기능을 제공해 줌
build.gradle > 'Spring Security' 프레임워크 추가
// Security
implementation 'org.springframework.boot:spring-boot-starter-security'
SpringAuthApplication
'Spring Security' 활성화
Spring Security 제외 해제
@SpringBootApplication
public class SpringAuthApplication {
public static void main(String[] args) {
SpringApplication.run(SpringAuthApplication.class, args);
}
}
Spring Security는 Filter 기반으로 동작 > 만들었던 Filter가 방해할 수 있음
Filter >@Component 주석 처리
config에 WebSecurityConfig 추가
CSRF (사이트 간 요청 위조, Cross-site request forgery)
공격자가 인증된 브라우저에 저장된 쿠키의 세션 정보를 활용하여
웹 서버에 사용자가 의도하지 않은 요청을 전달하는 것
CSRF 설정이 되어있는 경우 html 에서 CSRF 토큰 값을 넘겨주어야 요청을 수신 가능
쿠키 기반의 취약점을 이용한 공격 이기 때문에 REST 방식의 API 에서는 disable 가능
POST 요청마다 처리해 주는 대신 CSRF protection 을 disable 하기
http.csrf((csrf) -> csrf.disable());
WebSecurityConfig
package com.sparta.springauth.config;
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.Customizer;
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 // Spring Security 지원을 가능하게 함
public class WebSecurityConfig {
//securityFilterChain 메서드를 bean으로
//시큐리티를 사용할 때 어떤 URL은 인가하고 어떤 URL은 인가하지 않고 이런 설정을 해줌
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// CSRF 설정
http.csrf((csrf) -> csrf.disable()); //csrf 사용하지 않겠다.
//여기가 중요함
http.authorizeHttpRequests((authorizeHttpRequests) ->
authorizeHttpRequests
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
// resources(static,css) 폴더(=(PathRequest.toStaticResources().atCommonLocations())) 접근 허용 설정 (permitAll() : 따로 인증처리를 하지 않아도 접근을 모두 허용하겠다)
//이거하면 js/ css 경로에 따라 filter 걸어주는 거 안해도 됨
.anyRequest().authenticated() // 그 외 모든 요청은 인증처리
);
// 로그인 사용
http.formLogin(Customizer.withDefaults());
return http.build(); //build하면서 return
}
}
특히 중요한 거
//여기가 중요함
http.authorizeHttpRequests((authorizeHttpRequests) ->
authorizeHttpRequests
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
// resources(static,css) 폴더(=(PathRequest.toStaticResources().atCommonLocations())) 접근 허용 설정 (permitAll() : 따로 인증처리를 하지 않아도 접근을 모두 허용하겠다)
//이거하면 js/ css 경로에 따라 filter 걸어주는 거 안해도 됨
.requestMatchers("/api/user/**").permitAll() ///api/user/**로 시작하는 모든 것들이 permitall됨
.anyRequest().authenticated() // 그 외 모든 요청은 인증처리
);

위의 코드로 AuthFilter의 /css,/js 부분 코드 안 작성해줘도 됨
.permitall() 외 추가
.hasRole(String role) : 특정 권한이 있는 사용자만 허가 등
spring security에서 제공되는 기본 로그인 창
아이디는 user / 비밀번호는 콘솔에서 가져오기
이걸로 로그인하기 전에 PasswordConfig 주석 처리
그리고 이걸 사용하는 UserService에서 생성자 만든거 주석처리 + 이후 발생하는 빨간 줄 모두 주석 처리
Security는 세션 방식으로 운영
Spring Security - Filter Chain
Spring에서 모든 호출은 DispatcherServlet을 통과하게 되고 이후에 각 요청을 담당하는 Controller 로 분배
각 요청에 대해서 공통적으로 처리 해야할 때 DispatcherServlet 이전에 단계가 필요 = 이것이 Filter
Spring Security도 인증 및 인가를 처리하기 위해 Filter 사용
FilterChainProxy를 통해 상세 로직 구현하고 있음
Form Login 기반 = 인증
Form Login 기반 인증은 인증이 필요한 URL 요청이 들어왔을 때 인증이 되지 않았다면 로그인 페이지를 반환하는 형태
UsernamePasswordAuthenticationFilter
= Spring Security의 필터인 AbstractAuthenticationProcessingFilter를 상속한 Filter
= 기본적으로 Form Login 기반을 사용할 때 username 과 password 확인하여 인증
- ★ ★ ★ 인증 과정
- 사용자가 username과 password를 제출하면
★ ★ ★ UsernamePasswordAuthenticationFilter는
인증된 사용자의 정보가 담기는 인증 객체인 Authentication의 종류 중 하나인 UsernamePasswordAuthenticationToken을 만들어
AuthenticationManager에게 넘겨 인증을 시도 - 실패하면 SecurityContextHolder를 비움
- 성공하면 SecurityContextHolder에 Authentication 세팅
- 사용자가 username과 password를 제출하면
SecurityContextHolder / Authentication
SecurityContextHolder 구성
// 예시코드
//SecurityContextHolder을 SecurityContext로 생성
SecurityContext context = SecurityContextHolder.createEmptyContext();
//Authentiacation 만들기
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, credentials, authorities);
// SecurityContext 에 인증 객체 Authentication 저장
context.setAuthentication(authentication);
//SecurityContextHolder에 만들어진 context 넣기
SecurityContextHolder.setContext(context);
SecurityContextHolder
- 인증이 완료된 사용자의 상세 정보(Authentication) 저장
- SecurityContext는 SecurityContextHolder 로 접근할 수 있음
Authentication
- 현재 인증된 사용자 나타냄
- SecurityContext에서 가져올 수 있음
- principal : 사용자 식별/ Username/Password 방식으로 인증할 때 일반적으로 UserDetails 인스턴스
- credentials : 주로 비밀번호 / 대부분 사용자 인증에 사용한 후 비움
- authorities : 사용자에게 부여한 권한을 GrantedAuthority로 추상화하여 사용
<UserDetails>
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
UserRoleEnum role = user.getRole();
String authority = role.getAuthority();
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(authority);
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(simpleGrantedAuthority);
return authorities;
}
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
UsernamePasswordAuthenticationToken
: Authentication을 implements한 AbstractAuthenticationToken의 하위 클래스
: 인증객체 만드는데 사용
UserDetailsService
: username/password 인증방식을 사용할 때 사용자를 조회하고 검증한 후 UserDetails를 반환
: Custom하여 Bean으로 등록 후 사용 가능
UserDetails
: UsernamePasswordAuthenticationToken 타입의 Authentication를 만들 때 사용
: 해당 인증객체는 SecurityContextHolder에 세팅
: Custom하여 사용가능
'스파르타 코딩 클럽 | 자바 심화 과정 > Spring Master (숙련 주차)' 카테고리의 다른 글
접근 불가 페이지 만들기 (권한 제어 @Secured) (0) | 2025.02.07 |
---|---|
Spring Security - #2. 로그인 (세션) // @AuthenticationPrinciple (0) | 2025.02.07 |
Filter 필터 (1) | 2025.02.06 |
JWT 다루기 (1) | 2025.02.06 |
사용자 관리하기 - #2. 로그인 구현 JWT (1) | 2025.02.05 |