-
security 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-security'
- 의존성 추가와 함께 이뤄지는 자동 설정
- 서버가 가동되면 스프링 시큐리티의 초기화 작업 및 보안 설정이 이루어짐
- 별도의 설정이나 구현을 하지 않아도 기본적인 웹 보안 기능이 현재 시스템에 연동되어 작동
- security의 기본 설정
- 모든 요청은 인증이 되어야 접근 가능
- 인증 방식은 Form 로그인 방식과 HttpBasic 로그인 방식을 제공
- 기본 로그인 페이지를 제공(미설정시)
- 기본 계정을 제공(username = user / password = UUID 랜덤 문자열을 로그에 제공)
- 이후 해야 할 작업
- 계정 추가, 권한 추가, DB 연동 등
- 기본적인 보안 기능 외 시스템에서 필요로 하는 더 세부적이고 추가적인 보안기능 필요
-
기본 API 와 Filter
-
사용자 정의 보안 기능 구현
- Security Config 없이 실행하는 과정
- 먼저 내부적으로 기본적인 초기화 메서드를 가지고 있음
- 해당 초기화를 거치고 configure 메서드 오버라이딩을 통해 덮어씌우는 작업 후행
- 위 configure 메서드를 재정의 하여 직접 설정한 보안 설정을 적용시킬 수 있음
- 실행할 때마다 새로운 문자열 패스워드를 제공
- 계속 복사하는 것에 귀찮음을 위해 yml 설정 가능
spring.security.user.name = username
설정
spring.security.user.password = password
설정
-
Form 인증
Form 인증의 기본적인 과정
SecurityConfig의 configure 메서드 재정의 예시
- Form인증의 과정
- /home 경로에 GET 방식으로 호출
- 서버는 인증인 안된 사용자일 때 로그인 페이지로 redirect
- 클라이언트는 username, password를 통해 POST 방식으로 인증 요청
- 인증이 완료된 경우 해당 session에 인증 토큰(UsernamePasswordAuthenticationToken)생성 및 저장(정확히는 Security Context에 저장하고 Security Context를 session에 저장)
- 이후 다시 /home 경로 GET 방식으로 호출하는 경우 토큰을 통해 인증을 확인하고 접근에 대해 허용(타임리프 표현식등을 사용)
- configure(AuthenticationManagerBuilder auth) 메서드
- 사용자를 정의할 수 있는 메서드
- 영구적으로 만드는 사용자가 아닌 메모리에 저장하는 일시적인 사용자
- 예)
auth.inMemoryAuthentication().withUser("user").password("{noop}1111").roles("USER");
- password에 사용된
{noop}
은 password 암호화 알고리즘을 작성하는 부분으로 noop의 경우 알고리즘을 사용하지 않음 설정
-
UsernamePasswordAuthenticationFilter
Form Login 인증 과정
- UsernamePasswordAuthenticationFilter 역할
- 인증 전/후로 역할을 나눔
- 인증이 이루어지지 않은 경우 로그인 페이지로 리다이렉팅
- 또한 인증을 하기 전에는 Authentication 객체에 입력한 username, password를 담아서 **인증 객체(AuthenticationManager)**로 전달 → 로그인 페이지에서 POST요청을 하는 경우
- 인증 이후로는 User정보, 권한 목록이 담긴 Authentication 객체를 SecurityContext에 저장하는 역할 → session에서 정보 추출
- FilterChainProxy
- Filter들을 관리하는 빈
- 여러개의 Filter를 가지고 있으며 사용자 요청에 따라 사용할 Filter를 적용
-
Logout, LogoutFilter
Logout 과정
SecurityConfig logout API
LogoutFilter 동작 과정
-
Remember Me 인증
Remember-Me API
파라미터를 통해 remember-me 인증 기능 활성화(체크박스)
- Remember Me 인증이란
- 세션이 만료되고 웹 브라우저가 종료된 후에도 서버가 사용자를 기억하는 기능
- Remember-Me 쿠키에 대한 Http 요청을 확인 후 토큰 기반 인증을 사용해 유효성을 검사하고 토큰이 검증되면 사용자는 로그인
- 사용자 라이프 사이클
- 인증 성공(Remember-Me 쿠키 설정)
- 인증 실패(쿠키가 존재하면 쿠키 무효화)
- 로그아웃(쿠키가 존재하면 쿠키 무효화)
-
RememberMeAuthenticationFilter
RememberMeAuthenticationFilter 동작 과정
- 동작 조건
- SecurityContext내 **Authentication(인증 정보)**가 없는 경우(세션 만료 등) 동작
- RequestHeader에 Remember-Me 쿠키 정보를 가지는 경우 동작
- RememberMeServices
- 인터페이스로 해당 구현체가 RememberMe 인증 처리를 진행
- TokenBasedRememberMeServices, PersistentTokenBasedRememberMeServices 구현체 기본 제공
- TokenBasedRememberMeServices는 메모리에 저장한 토큰 정보와 클라이언트가 헤더에 포함한 쿠키 정보가 일치하는지 확인(일시적 저장)
- PersistentTokenBasedRememberMeServices는 DB에 저장한 토큰 정보와 클라이언트가 헤더에 포함한 쿠기 정보가 일치하는지 확인(영구적 저장)
-
AnonymousAuthenticationFilter
- 익명사용자 인증 처리 필터
- 익명사용자와 인증 사용자를 구분해서 처리하기 위한 용도(로그인 처리 등)
- 인증이 되지 않은 사용자는 필터를 거친 경우 익명 토큰 객체를 생성하여 익명 사용자로 관리(ROLE_anonymous 의 익명 객체 생성)
- 인증객체를 세션에 저장하지 않음
-
동시 세션 제어 및 세션 관리/세션 고정 보호/세션 정책
-
동시 세션 제어 및 세션 관리
SecurityConfig sessionManagement API
- 인증 시 사용자의 세션정보를 등록, 조회, 삭제 등의 세션 이력 관리 및 동일 계정으로 접속이 허용되는 최대 세션수 제한
- 최대 세션 1개 설정한 경우
- 이전 사용자 세션 만료는 같은 계정에 대해 다른 세션에서 인증하는 경우 최근에 인증한 세션을 유지하고 이전에 인증한 세션에 대해서는 만료
- 현재 사용자 인증 실패는 같은 계정에 대해 이미 인증한 세션이 있는 경우 해당 세션의 인증을 유지하고 새로운 인증에 대해서는 실패하도록 처리
maxSessionPreventsLogin()
으로 결정됨
-
세션 고정 보호
SecurityConfig 세션 고정 보호 API
Servlet 3.1 이상에서 default = changeSessionId
Servlet 3.1 이하에서 default = migrateSession
위와 달리 newSession은 session 설정된 다른 값들을 임포트하지 않고 새로운 세션처럼 처리
none은 설정하지 않는다는 의미이며 세션 고정 공격에 취약함
- 인증할 때마다 세션쿠키(JSESSIONID)를 새로 발급받아 공격자의 쿠키 조작 방지
- 세션 고정 보호는 공격자의 JSESSIONID를 통해 인증하는 것을 방지하기 위해 인증을 성공했을 때 새로운 JSESSIONID를 발급함으로서 보호
-
세션 정책
SessionCreationPolicy.Always
= 스프링 시큐리티가 항상 세션 생성
SessionCreationPolicy.If_Required
= 스프링 시큐리티가 필요 시 생성(기본값)
SessionCreationPolicy.Never
= 스프링 시큐리티가 생성하지 않지만 이미 존재하면 사용
SessionCreationPolicy.Stateless
= 스프링 시큐리티가 생성하지 않고 존재해도 사용하지 않음(JWT 등과 같이 세션을 활용하지 않을 때 사용)
-
SessionManagementFilter, ConcurrentSessionFilter
전반적인 인증 과정
RegisterSessionAuthenticationStrategy = 세션 정보를 등록하는 클래스
ChangeSessionIdAuthenticationStrategy = JSESSIONID를 변경하는 클래스
ConcurrentSessionControlAuthenticationStrategy = 세션 최대 개수 제한하는 클래스
- SessionManagementFilter 역할
- 세션 관리 및 동시적 세션 제어
- 세션 고정 보호
- 세션 생성 정책
- ConcurrentSessionFilter 역할
- 매 요청 마다 현재 사용자의 세션 만료 여부를 확인
- 세션이 만료되었을 경우 즉시 인증 만료 처리(로그아웃 처리, 오류 페이지 응답)
- 공통점
- 차이점
- SessionManagementFilter의 경우 인증을 하는 경우 작동
- ConcurrentSessionFilter의 경우 요청이 발생할 경우 작동
-
권한 설정 및 표현식
-
ExceptionTranslationFilter
-
RequestCacheAwareFilter
-
CSRF