27
스프링 시큐리티 구조 이해 (어플리케이션 중심) 신림 프로그래머, 최범균, 2014-07-09

스프링 시큐리티 구조 이해

Embed Size (px)

DESCRIPTION

스프링 시큐리티의 주요 구성 요소인 SecurityFilterChain, AuthenticationManager, SecurityInterceptor의 구조 소개

Citation preview

Page 1: 스프링 시큐리티 구조 이해

스프링 시큐리티 구조 이해(웹 어플리케이션 중심)신림 프로그래머, 최범균, 2014-07-09

Page 2: 스프링 시큐리티 구조 이해

목표

● 스프링 시큐리티의 구성 요소와 동작 방식 이해○ 이를 통한 커스터마이징 포인트 잡기!

Page 3: 스프링 시큐리티 구조 이해

기본 구성 요소

Page 4: 스프링 시큐리티 구조 이해

보안 관련 3요소

● 접근 주체(Principal)○ 보호된 대상에 접근하는 사용자

● 인증(Authenticate)○ 현재 사용자가 누군인지 확인하는 과정○ 일반적으로 아이디/암호를 이용해서 인증을 처리

● 인가(Authorize)○ 현재 사용자가 특정 대상(URL, 기능 등)을 사용(접근)할 권한이 있는지 검사하는 것

Page 5: 스프링 시큐리티 구조 이해

스프링 시큐리티와 보안 3요소의 매칭

접근 주체

인증

인가

Authentication

AuthenticationManager

SecurityInterceptor

Page 6: 스프링 시큐리티 구조 이해

Authentication와 SecurityContext

● Authentication의 용도○ 현재 접근 주체 정보를 담는 목적○ 인증 요청할 때, 요청 정보를 담는 목적

● SecurityContext○ Authentication을 보관○ 스프링 시큐리티는 현재 사용자에 대한

Authentication 객체를 구할 때 SecurityContext로부터 구함

Page 7: 스프링 시큐리티 구조 이해

SecurityContextHolder

● SecurityContext를 보관○ 기본: 쓰레드로컬에 SecurityContext를 보관

● 전형적인 SecurityContext 설정 코드Authentication auth = someMethodForGettingAuth(req, resp);try { SecurityContextHolder.getContext().setAuthentication(auth); chain.doFilter(request, response); // 이후 코드에서 동일 SecurityContext 사용} finally { SecurityContextHolder.clearContext();} 스프링 시큐리티가 유사한 필터 이미 제공

Page 8: 스프링 시큐리티 구조 이해

참고, Authentication의 주요 메서드

● Authentication의 주요 메서드○ String getName(): 사용자의 이름○ Object getCredential(): 증명 값 (비밀번호 등)○ Object getPrincipal(): 인증 주체 정보○ boolean isAuthenticated(): 인증되었는지 여부○ Collection<GrantedAuthority) getAuthorities(): 현재 사용자가 가진 권한(GrantedAuthority)

Page 9: 스프링 시큐리티 구조 이해

AuthenticationManager

● 인증을 처리함public interface AuthenticationManager { Authentication authenticate(Authentication authentication) throws AuthenticationException;}

● 인증에 성공하면 인증 정보를 담고 있는 Authentication 객체 리턴○ 스프링 시큐리티는 리턴한 Authentication 객체를 SecurityContext에 보관 및 인증 상태를 유지하기 위해 세션에 보관

● 인증 실패시 AuthenticationException을 발생시킴

Page 10: 스프링 시큐리티 구조 이해

(Abstract)SecurityInterceptor

● 인가를 처리○ 웹의 경우 FilterSecurityInterceptor 구현 사용○ AccessDecisionManager에 권한 검사 위임

public interface AccessDecisionManager { void decide(Authentication authentication, // 사용자 Object object, // 접근 자원 Collection<ConfigAttribute> configAttributes) // 보안 설정 throws AccessDeniedException, InsufficientAuthenticationException; boolean supports(ConfigAttribute attribute); boolean supports(Class<?> clazz);}

● 사용자가 자원의 보안 설정 기준으로, 접근 권한이 없을 경우 익셉션 발생

Page 11: 스프링 시큐리티 구조 이해

SecurityFilterChain

Page 12: 스프링 시큐리티 구조 이해

웹 어플리케이션 보안 지원

● 보인 필터 체인를 이용한 보안 처리FilterChainProxy

보안 필터 체인

실제 자원

주로 다음 기능을 제공- Authentication 정보 생성- 접근 권한 검사- 인증 요청 처리

<sec:http use-expressions="true"> <sec:intercept-url pattern="/admin/**" access="hasAuthority('ROLE_ADMIN')" /> <sec:intercept-url pattern="/manager/**" access="hasRole('ROLE_MANAGER')" /> <sec:intercept-url pattern="/member/**" access="isAuthenticated()" /> <sec:intercept-url pattern="/**" access="permitAll"/>

<sec:form-login /> <sec:logout />

</sec:http>

생성

생성

스프링 빈으로 등록된 필터(springSecurityFilterChain)

Page 13: 스프링 시큐리티 구조 이해

웹 요청을 FilterChainProxy 적용

<filter> <filter-name> springSecurityFilterChain </filter-name> <filter-class> o...filter.DelegatingFilterProxy </filter-class></filter><filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern></filter-mapping>

FilterChainProxy

보안 필터 체인

DelegatingFilterProxy

Page 14: 스프링 시큐리티 구조 이해

보안 필터 체인

보안 필터 체인의 주요 구성 요소

SecurityContextPersistenceFilter

LogoutFilter

UsernamePasswordAuthenticationFilter

DefaultLoginPageGeneratingFilter

AnonymousAuthenticationFilter

ExceptionTranslationFilter

FilterSecurityInterceptor접근 권한 검사

익셉션 처리

로그인 폼 출력

인증 요청 처리

로그아웃 요청 처리

Authentication 로딩 ● 필터 체인은 순서대로 실행

● 필터에 따라 요청을 처리하고 체인 실행을 끝내기도 함

임의 사용자 처리

Page 15: 스프링 시큐리티 구조 이해

접근 권한 없을 때 처리, 인증 전보안 필터 체인

SecurityContextPersistenceFilter

LogoutFilter

UsernamePasswordAuthenticationFilter

DefaultLoginPageGeneratingFilter

AnonymousAuthenticationFilter

ExceptionTranslationFilter

FilterSecurityInterceptor

1. 요청

AccessDecisionManager 2. 권한 검사

요청

4. 익셉션 발생

AuthenticationEntryPoint

5. 인증 과정 시작 처리

<sec:form-login login-page="/user/loginform"/>

Page 16: 스프링 시큐리티 구조 이해

접근 권한 없을 때 처리, 인증 상태보안 필터 체인

SecurityContextPersistenceFilter

LogoutFilter

UsernamePasswordAuthenticationFilter

DefaultLoginPageGeneratingFilter

AnonymousAuthenticationFilter

ExceptionTranslationFilter

FilterSecurityInterceptor

1. 요청

AccessDecisionManager 3. 권한 검사

요청

4. 익셉션 발생

AccessDeniedHandler

5. 접근 거부 응답 처리

<sec:access-denied-handler error-page="/accessDenied"/>

SecurityContextRepository

2. 보관된 SecurityContext를 로딩

Page 17: 스프링 시큐리티 구조 이해

기본 로그인 폼 제공보안 필터 체인

SecurityContextPersistenceFilter

LogoutFilter

UsernamePasswordAuthenticationFilter

DefaultLoginPageGeneratingFilter

AnonymousAuthenticationFilter

ExceptionTranslationFilter

FilterSecurityInterceptor

1. /spring_security_login 경로 요청

2. 로그인 폼 응답 전송

Page 18: 스프링 시큐리티 구조 이해

인증 요청 처리 과정 (성공시)보안 필터 체인

SecurityContextPersistenceFilter

LogoutFilter

UsernamePasswordAuthenticationFilter

DefaultLoginPageGeneratingFilter

AnonymousAuthenticationFilter

ExceptionTranslationFilter

FilterSecurityInterceptor

1. 인증 요청

AuthenticationManager

2. 인증 실행

SecurityContext

3. Authentication 보관

AuthenticationSuccessHandler

4. 성공 후처리

SecurityContextRepository

5. SecurityContext 보관

<sec:form-login login-processing-url="/user/login" username-parameter="userid" password-parameter="password" default-target-url="/index"/>

Page 19: 스프링 시큐리티 구조 이해

인증 요청 처리 과정 (실패시)보안 필터 체인

SecurityContextPersistenceFilter

LogoutFilter

UsernamePasswordAuthenticationFilter

DefaultLoginPageGeneratingFilter

AnonymousAuthenticationFilter

ExceptionTranslationFilter

FilterSecurityInterceptor

1. 인증 요청

AuthenticationManager

2. 인증 실행

AuthenticationFailureHandler

3. 실패 후처리

<sec:form-login ... authentication-failure-url="/user/loginform?error=true"/>

Page 20: 스프링 시큐리티 구조 이해

로그아웃 요청 처리 과정보안 필터 체인

SecurityContextPersistenceFilter

LogoutFilter

UsernamePasswordAuthenticationFilter

DefaultLoginPageGeneratingFilter

AnonymousAuthenticationFilter

ExceptionTranslationFilter

FilterSecurityInterceptor

1. 로그 아웃 요청

LogoutSuccessHandler

3. 로그아웃 후 처리

LogoutHandler2. 로그아웃 처리

<sec:logout logout-url="/user/logout" logout-success-url=”/”/>

Page 21: 스프링 시큐리티 구조 이해

AuthenticationManager

Page 22: 스프링 시큐리티 구조 이해

AuthenticationManager 구조1<sec:authentication-manager> <sec:authentication-provider> ... </sec:authentication-provider></sec:authentication-manager>

사용자 정보 제공사용자 암호 비교

AuthenticationProvider에 위임

Page 23: 스프링 시큐리티 구조 이해

AuthenticationManager 구조2

<sec:authentication-provider> <sec:user-service> <sec:user name="bkchoi" password="1234" authorities="ROLE_USER" /> </sec:user-service></sec:authentication-provider>

<sec:authentication-provider> <sec:jdbc-user-service data-source-ref="dataSource" id="jdbcUserService" /></sec:authentication-provider>

Page 24: 스프링 시큐리티 구조 이해

커스텀 구현 설정

<sec:authentication-manager >

<!-- AuthenticationProvider의 커스텀 구현 사용 --> <sec:authentication-provider ref="customAuthenticationProvider" />

<!-- DaoAuthenticationProvider 구현 사용 → <!-- UserDetailsService의 커스텀 구현 사용 --> <sec:authentication-provider user-service-ref="customUserDetailsService" />

</sec:authentication-manager>

Page 25: 스프링 시큐리티 구조 이해

FilterSecurityInterceptor &

AccessDecisionManager

Page 26: 스프링 시큐리티 구조 이해

FilterSecurityInterceptor

<sec:http use-expressions="true"> <sec:intercept-url pattern="/user/loginform" access="permitAll" /> <sec:intercept-url pattern="/user/login" access="permitAll" /> <sec:intercept-url pattern="/admin/usermanager/**" access="hasAuthority('USER_MANAGER')" /> ...</sec:http>

Page 27: 스프링 시큐리티 구조 이해

AccessDecisionManager

<sec:http use-expressions="true"> ...</sec:http>