Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 대량쿼리
- jQueryUI
- Hibernate
- 자바서블릿
- 벌크연산
- paging
- JQuery
- 엔티티직접사용
- JPQL
- namedQuery
- calendar
- jQuery값전송
- 제네릭
- fullcalendar
- 페이징
- fetchjoin
- JPA
- 제너릭
- values()
- joinfetch
- LIST
- javaservlet
- 프로젝트생성
- jQuery값전달
- jscalendar
- 스프링데이터흐름
- javascriptcalendar
- 페치조인
- springflow
- Generic
Archives
- Today
- Total
가자공부하러!
Spring Security(1) 본문
섹션1 스프링 시큐리티 기본 API 및 Filter 이해
1. spring-boot-starter-security 디펜던시를 추가하면 무슨일이 생기나
- 서버가 기동되면 스프링 시큐리티의 초기화 작업 및 기본적인 보안 설정이 이루어진다.
- 기본적인 보안 설정?
- 모든 요청에 대해 인증을 요구한다.
- 인증 방식은 폼 로그인 방식과 httpBasic로그인 방식을 제공한다.
- 기본 로그인 페이지 제공
- 기본 계정 제공 : user / {password}
Using generated security password: 4add4fb7-0180-4223-8cde-a278183cb58c
- 기본적인 보안 설정?
2. 사용자 정의 보안 기능 구현(Customizing)
- WebSecurityConfigurerAdapter
- 서버가 구동되면서 이 클래스를 호출한다.
- 스프링 시큐리티의 웹 보안 기능을 초기화하고 설정해주는 추상 클래스
- HttpSecurity를 생성한다.(WebSecurityConfigurerAdapter의 init메서드에서)
- HttpSecrity는 세부적인 보안 기능을 설정할 수 있는 API를 제공한다. 크게 인증 API, 인가 API로 나뉜다.
// WebSecurityConfigurerAdapter가 갖는 메서드 @Override public void init(WebSecurity web) throws Exception { HttpSecurity http = getHttp(); web.addSecurityFilterChainBuilder(http).postBuildAction(() -> { FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class); web.securityInterceptor(securityInterceptor); }); } protected final HttpSecurity getHttp() throws Exception { if (this.http != null) { return this.http; } // ... 생략 this.http = new HttpSecurity(this.objectPostProcessor, this.authenticationBuilder, sharedObjects); // ... 생략 return this.http; }
- 커스터마이징
- @EnableWebSecurity 어노테이션을 custom config클래스에 선언해주어야 한다. : 웹 보안을 활성시키기 위한 어노테이션
- FormLogin custom 설정
http .formLogin() .loginPage("/login") // 사용자 정의 로그인 페이지 .defaultSuccessUrl("/home") // 로그인 성공 후 이동 페이지 .failureUrl("/login?error=true") // 로그인 실패 후 이동 페이지 .usernameParameter("username") // form에 아이디 파라미터 key .passwordParameter("password") // form에 비밀번호 파라미터 key .loginProcessingUrl("") // 로그인 Form action URL .successHandler(loginSuccessHandler()) // 로그인 성공 후 핸들러 .failureHandler(loginFailureHandler()) // 로그인 실패 후 핸들러
- UsernamePasswordAuthenticationFilter
- username과 password로 인증을 처리하는 필터
- AbstractAuthenticationProcessingFilter를 상속받고 있음(doFilter메서드는 부모클래스에)
- 동작
- request의 요청 정보가 설정된 값(loginProcessingUrl)과 같으면 동작, 아니면 다음 필터로(chain.doFilter)
- Authentication 객체 생성(username + password)
- AuthenticationManager로 인증객체 전달(Authentication Manager 내부에 갖고있는 AuthenticationProvider 객체에 인증을 위임)
- ProviderManager가 provider를 찾아서 인증처리
- AuthenticationProvider에서 인증 실패하면 예외 발생, 성공하면 인증정보를 Authentication객체에 담아 manager로 리턴
- 여기까지 오면 Authentication 객체는 유저 정보와 권한들을 가짐
- 인증객체를 SecurityContext에 저장
- SuccessHandler 동작
- LogoutFilter
- 로그아웃(세션 무효화, 인증토큰 삭제, 쿠키정보 삭제 등) 처리해주는 필터
- logoutHandler : 위 작업들을 처리해주는 핸들러. 추가 기능이 필요한 경우 커스텀 가능
- 동작
- request의 요청 정보가 설정된 값(logoutUrl)과 같으면 동작, 아니면 다음 필터로(chain.doFilter)
- SecurityContext의 인증정보를 가져와서 로그아웃 핸들러로 보냄
- 로그아웃 핸들러는(여러 핸들러 공존 가능) 세션 무효화, 쿠키 삭제, 인증토큰 삭제, 컨텍스트 클리어 등 동작
- RememberMeAuthenticationFilter
- 서버가 쿠키를 발급해주고 클라이언트가 쿠키를 서버로 올렸을 때 서버는 토큰기반 인증을 사용해 검증이 되면 로그인 처리
- 인증 성공할 때 쿠키 생성, 인증 실패 또는 로그아웃할 때 쿠키 삭제
- 동작
- authentication 객체가 null일 때만 동작(null이 아니면 다음 필터로)
- RememberMeService에서 인증처리(구현체에 따라 remember-me 정보 메모리에 저장할지 DB에 저장할지 등 선택)
- 토큰이 있으면 추출, 없으면 doFilter
- 토큰을 decode해서 토큰이 서로 일치하는지, User 계정이 존재하는지를 검증하고 인증처리
- 4단계에서 문제 있으면 예외 발생
- AnonymousAuthenticationFilter
- 익명사용자 인증 처리 필터. Authentication 객체에 anonymousUser, ROLE_ANONYMOUS로 설정해준다.
- 인증여부를 구현할 때 isAnonymous, isAuthenticated로 구분해서 사용한다. : AuthenticationTrustResolver
- SessionManagementFilter
- 세션 관리 필터(등록, 조회, 삭제, 이력관리, 동시세션제어, 세션고정보호, 세션생성정책결정)
- 세션고정보호
- 공격 시나리오 : 공격자가 사용자의 세션ID(쿠키)를 공격자의 세션 ID로 설정해서 로그인한 것 처럼 사용
- 보호방법 : 인증할 때 마다 새 세션 ID 생성(changeSessionId)
- 서블릿 3.1이전 : 이전 세션 값 가져와서 생성(migrateSession), 전혀 새로운 세션 생성(newSession)
- 인증된 세션 ID를 탈취하는 공격에 대해서는 다르게 방어해야함(ex_ IP check)
- 세션인증전략 순서(AuthenticationStrategy)
- CompositeSessionAuthenticationStrategy가 delegateStrategies로 관리한다.
- HttpSecurity(extends AbstractConfiguredSecurityBuilder).doBuild 에서 1~3은 init(), 4는 configure()에서 설정되기 때문에 아래와 같은 순서를 갖는다.
- ConcurrentSessionControlAuthenticationStrategy : 동시세션 제어
- ChangeSessionIdAuthenticationStrategy : 세션고정보호(세션 발급)
- RegisterSessionAuthenticationStrategy : sessionRegistry에 세션정보를 등록하는 역할
- CsrfAuthenticationStrategy : CSRF Token 체크
- 위 전략 외 필요에 따라 다른 것들이 더 추가될 수 있음
- ConcurrentSessionFilter
- 동시세션 제어 필터
- maximumSessions 설정이 있을 때만 필터체인에 등록됨 (SessionManagementConfigurer에 maximumSessions가 null이 아닌 경우)
- 권한설정과 표현식(인가)
- 권한설정 방식
- 선언적 방식
- URL : 특정 URL마다 접근권한 지정
- 메서드 : 특정 메서드마다 접근권한 지정
- 선언적 방식
- URL 선언적 방식에서 표현식
- antMatchers에 URL선언은 순서를 갖는다.
hasRole(String role) // configurer에서 ROLE_ 붙여줌 hasAnyRole(String... roles) // configurer에서 ROLE_ 붙여줌 hasAuthority(String authority) hasAnyAuthority(String... authorities) access(String attribute) //위 표현식들이 호출하는 메서드 hasIpAddress(String ipaddressExpression) permitAll() denyAll() anonymous() // 익명 사용자 허용 rememberMe() // rememberMe 허용 authenticated() fullyAuthenticated() // rememberMe 제외하고 인증된 사용자 허용
- 권한설정 방식
- ExceptionTranslationFilter
- 인증예외 처리 필터이며 FilterSecurityInterceptor가 던지는 예외를 잡아서 호출함
- 처리하는 예외 종류
- AuthenticationException : 인증 예외, AuthenticationEntryPoint 호출
- AccessDeniedException : 인가 예외, AccessDeniedHandler에서 예외 처리
- HttpSessionRequestCache
- 인증 예외가 발생한 경우 request정보를 담고있는 객체(세션에 저장됨)
- ExceptionTranslationFilter에서 entryPoint.commence 메서드 호출하기 전 저장한다.(session.setAttribute)
- RequestCacheAwareFilter에서 가져온다
- 인증 예외 발생 후 다시 로그인에 성공했을 때 loginSuccessHandler에서 예외 발생 당시 requestUrl로 쉽게 리다이렉트 시켜줄 수 있다.
- 사이트 간 요청 위조(CSRF)
- 피해자의 의도와 무관하게 공격자가 의도한 행위를 서버에 요청하게끔 만드는 공격
- CsrfFilter
- 모든 요청에 랜덤하게 생성된 토큰을 http 파라미터로 요구
- 서버가 내린 csrf 토큰과 일치하지 않으면 요청실패
- XSS공격과 혼용돼서 csrf토큰까지 탈취되면 의미없음
*** 분명 Filter인데 chain.doFilter를 못찾은 경험이 있다. 그럴 땐 상속클래스를 확인해보면 된다.
*** 중간에 있는 eventPublisher는 어떻게 동작하나? 필터체인 중간에 끼게할 수 있나?
'공부 > Spring' 카테고리의 다른 글
Spring Security(3) - form 로그인 방식 예제 (0) | 2021.07.12 |
---|---|
Spring Security(2) - 전체 구조와 필터 별 역할 정리 (2) | 2021.07.07 |
토비의 스프링(8) - 스프링이란 무엇인가? (0) | 2021.06.17 |
토비의스프링(7) - 스프링 핵심 기술의 응용 (0) | 2021.06.17 |
토비의스프링(6) - AOP (0) | 2021.03.30 |
Comments