Spring Security 개요
Spring MVC 기반 애플리케이션의 인증(Authentication)과 인가(Authorization) 기능을 지원하는 보안 프레임워크로써, Spring MVC 기반 애플리케이션에 보안을 적용하기 위한 사실상의 표준
- 다양한 유형(폼 로그인 인증, 토큰 기반 인증, OAuth 2 기반 인증, LDAP 인증)의 사용자 인증 기능 적용
- 애플리케이션 사용자의 역할(Role)에 따른 권한 레벨 적용
- 애플리케이션에서 제공하는 리소스에 대한 접근 제어
- 민감한 정보에 대한 데이터 암호화
- SSL 적용
- 일반적으로 알려진 웹 보안 공격 차단
- 이 외에도 SSO, 클라이언트 인증서 기반 인증, 메서드 보안, 접근 제어 목록(Access Control List) 같은 보안을 위한 기능들을 지원
Spring Security Architecture 는 Dispatcher Servlet 전 Filter 단에서 처리되며, 3가지로 구성됨
delegatingFilterProxy(Bean Filter)
- (계층) securityFilterChain : usernamePassword authenticationFilter token → authenticationManager → success/Failure : SecurityContextHolder에 인증객체가 담김
- Security Context Holder 구조
- principal(주체) : 인증된 객체 자체
- Credentials(인증) : 자격증명 - 인증되고 나서 삭제되도 무방한 정보
- Authorities(인가) : 권한
Spring Security 사용
1. Spring dependency 추가
- dependency 추가 만으로 로그인 화면 구성됨 → custom 필수
- 디폴트 로그인 정보 : user - 구동시 콘솔에서 pw 확인
dependencies { ...
//Spring Security
implementation 'org.springframework.boot:spring-boot-starter-security'
}
2. Spring Security Configuration 적용
- spring의 환경설정은 configuration에서 시작됨
- User - Role - Privilege 간의 연관관계 설정
1) SecurityFilterChain Bean 등록 : 클래스명 WebSecurityConfig , SecurityConfiguration
- and() : Spring Security 보안 설정을 메서드 체인 형태로 구성
- formLogin() : 기본적인 인증 방법을 폼 로그인 방식으로 지정(UsernamePasswordAuthenticationFilter의 인증방식 중 하나로 httpbasic() 등이 있음
- longin 설정
- loginPage("/auths/login-form") : 커스텀 로그인 페이지를 사용하도록 설정
- loginProcessingUrl("/process_login") : 메서드를 통해 로그인 인증 요청을 수행할 요청 URL을 지정
- loginProcessingUrl()의 파라미터인 "/process_login"은 login.html에서 form 태그의 action 속성에 지정한 URL과 동일
- failureUrl("/auths/login-form?error") : 로그인 인증에 실패할 경우 리다이렉트 할 화면지정
- 권한설정
- 모두 허용 : authorizeHttpRequests().anyRequest().permitAll() : 인증에 성공할 경우 모든 권한 부여
- 권한 제한 : authorizeHttpRequests(authorize -> authorize.antMatchers...) : 란다 표현식으로 request URI에 대한 접근 권한 부여
- request URL 설정 오류를 방지하기 위해 항상 더 구체적인 URL 경로부터 접근 권한을 부여한 다음 덜 구체적인 URL 경로에 접근 권한을 부여할 것.
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers().frameOptions().sameOrigin() // 개발에서 H2 웹 콘솔을 사용하기 위해 보안 옵션 해제, Clickjacking 공격에 취약
.and()
.csrf().disable()
.formLogin()
.loginPage("/auths/login-form")
.loginProcessingUrl("/process_login")
.failureUrl("/auths/login-form?error")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.and()
.exceptionHandling().accessDeniedPage("/auths/access-denied")
.and()
.authorizeHttpRequests(authorize -> authorize
.antMatchers("/orders/**").hasRole("ADMIN")
.antMatchers("/members/my-page").hasRole("USER")
.antMatchers("⁄**").permitAll()
);
//.and()
//.authorizeHttpRequests()
//.anyRequest().permitAll();
return http.build();
}
// 인메모리DB에 사용자 추가
@Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user =
User.withDefaultPasswordEncoder()
.username("kevin@gmail.com")
.password("1111")
.roles("USER")
.build();
// admin 권한 유저
UserDetails admin =
User.withDefaultPasswordEncoder()
.username("admin@gmail.com")
.password("2222")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
2) PasswordEncoder Bean 등록
- Spring Security에서 제공하는 패스워드 암호화 기능을 제공하는 컴포넌트
- PasswordEncoder : 다양한 암호화 방식을 제공하며, Spring Security에서 지원하는 디폴트 암호화 알고리즘은 bcrypt
3. Spring Security에서 관리하는 User Class 구현체 구현
1) Entity implements UserDetails
- Spring Security에서 관리하는 User 정보를 UserDetails로 관리
- UserDetails는 UserDetailsService에 의해 로드(load)되어 인증을 위해 사용되는 핵심 User 정보를 표현하는 인터페이스
- UserDetails 인터페이스의 구현체는 Spring Security에서 보안 정보 제공을 목적으로 직접 사용되지는 않고, Authentication 객체로 캡슐화되어 제공
2) Service implements UserDetailsService
- Spring Security에서 User 정보를 로드(load)하는 핵심 인터페이스
- 여기서 로드(load)의 의미는 인증에 필요한 User 정보를 어딘가에서 가지고 온다는 의미이며, 여기서 말하는 ‘어딘가’는 메모리가 될 수도 있고, DB 등의 영구 저장소가 될 수도 있음
'Coding > Back - Spring Framework' 카테고리의 다른 글
Spring Security : JWT #26 (0) | 2023.10.26 |
---|---|
Spring Security : Authorization 2/2 #Day25 (0) | 2023.10.26 |
보안 기초 : 쿠키(Cookie) & 세션(Session) #Day23 (0) | 2023.09.18 |
gitAction 자동배포 #Day22 (0) | 2023.09.14 |
Docker란? 컨테이너 생성하고 구동하기 #Day21 (0) | 2023.09.13 |