3. ㈜유미테크3㈜유미테크 Spring security
1. 소개
• Servlet Filter 기반으로 작동
– 사용자의 요청을 가로채서 전처리 하거나 서버의 응답을 가로채서 후
처리할 수 있다.
– http 엘리먼트의 auto-config 어트리뷰트를 사용하면 Spring Security
는 일련의 필터체인을 구성한다
4. ㈜유미테크4㈜유미테크 Spring security
• Filter 적용
Client
Dispatcher
Servlet
Handler
Mapping
Controller
ViewResolver
View
ModelAndView
1. 처리요청
(URL)
3. 처리요청
4. ModelAndView 지원
Filter
1. 소개
5. ㈜유미테크5㈜유미테크 Spring security
1. 소개
• 필터 체인
필터 설명
SecurityContextPersistenceFilter SecurityContextRepository에서 SecurityContext를 로드하고 저장하는 일을 담
당함
LogoutFilter 로그아웃 URL로 지정된 가상URL에 대한 요청을 감시하고 매칭되는 요청이 있
으면 사용자를 로그아웃시킴
UsernamePasswordAuthenticationFilter 사용자명과 비밀번호로 이뤄진 폼기반 인증에 사용하는 가상 URL요청을 감시
하고 요청이 있으면 사용자의 인증을 진행함
DefaultLoginPageGeneratingFilter 폼기반 또는 OpenID 기반 인증에 사용하는 가상URL에 대한 요청을 감시하고
로그인 폼 기능을 수행하는데 필요한 HTML을 생성함
BasicAuthenticationFilter HTTP 기본 인증 헤더를 감시하고 이를 처리함
RequestCacheAwareFilter 로그인 성공 이후 인증 요청에 의해 가로채어진 사용자의 원래 요청을 재구성
하는데 사용됨
SecurityContextHolderAwareRequestFilter HttpServletRequest를 HttpServletRequestWrapper를 상속하는 하위 클래스
(SecurityContextHolderAwareRequestWrapper)
AnonymousAuthenticationFilter 이 필터가 호출되는 시점까지 사용자가 아직 인증을 받지 못했다면 요청 관련
인증 토큰에서 사용자가 익명 사용자로 나타나게 됨
SessionManagementFilter 인증된 주체를 바탕으로 세션 트래킹을 처리해 단일 주체와 관련한 모든 세션
들이 트래킹되도록 도움
ExceptionTranslationFilter 이 필터는 보호된 요청을 처리하는 동안 발생할 수 있는 기대한 예외의 기본
라우팅과 위임을 처리함
FilterSecurityInterceptor 이 필터는 권한부여와 관련한 결정을 AccessDecisionManager에게 위임해 권
한부여 결정 및 접근 제어 결정을 쉽게 만들어 줌
6. ㈜유미테크6㈜유미테크 Spring security
2. 설정 – 라이브러리 추가
• pom.xml
<!-- security 적용 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${org.springframework-version}</version>
</dependency>
7. ㈜유미테크7㈜유미테크 Spring security
2. 설정 – security filter 적용
• web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security-context.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
12. ㈜유미테크12㈜유미테크 Spring security
3. Expression Language (EL)
• security-context.xml
– 설정
– 표현식
• hasIpAddress(ip) : 접근자의 IP주소가 매칭하는지 확인
• hasRole(role) : 역할이 부여된 권한과 일치하는지 확인
• hasAnyRole(role,role) : 부여된 역할 중 일치하는 항목이 있는지 확인
– 조건
• permitAll : 모든 접근자를 항상 승인
• denyAll : 모든 사용자의 접근을 거부
• anonymous : 사용자가 익명 사용자인지 확인
• authenticated : 인증된 사용자인지 확인
• rememberMe : 사용자가 remember me를 사용해 인증했는지 확인
• fullyAuthenticated : 사용자가 모든 크리덴셜을 갖춘 상태에서 인증했는
지 확인
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/*" access="hasRole('ROLE_USER')" />
</security:http>
13. ㈜유미테크13㈜유미테크 Spring security
• 표현식 생성
– SecurityExpressionOperations
인터페이스 구현
– 표현식 메서드 정의
– AbstractSecurityExpressionHandler 클래스 상속
– Handler에서 SecurityExpressionRoot 생성을
MyWebSecurityExoressionRoot클래스 객체로 생성
3. Expression Language (EL)
14. ㈜유미테크14㈜유미테크 Spring security
• 표현식 생성
– security-context.xml
3. Expression Language (EL)
<security:http auto-config="true" use-expressions="true" >
<security:intercept-url pattern="/login" access="permitAll" />
<security:intercept-url pattern="/*" access="test('ROLE_MIRA')" />
<security:form-login login-page="/login“/>
<security:logout logout-success-url="/login"/>
<security:expression-handler ref="myWebSecurityExpressionHandler"/>
</security:http>
<bean id="myWebSecurityExpressionHandler“
class="com.study.spring.security.MyWebSecurityExpressionHandler"></bean>
“test” 표현식 사용
ExpressionHandler등록
ExpressionHandler 클래스 bean 등록
16. ㈜유미테크16㈜유미테크 Spring security
5. 인증 - AuthenticationProvider 구현
• AuthenticationProvider 구현
• security-context.xml
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="defaultAuthenticationProvider"/>
</security:authentication-manager>
<bean id="defaultAuthenticationProvider"
class="com.study.spring.security.UserAuthenticationProvider" />
public class UserAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean supports(Class<?> authentication) {
// TODO Auto-generated method stub
return false;
}
authentication-provider 등록
Editor's Notes
시큐리티가 모든 설정을 기본값으로 설정 해서 얻게 된 로그인 창.
아이디와 비밀번호를 입력하고 Login 버튼을 클릭하면 애초에 얻고자 했던 URL 리소스에 접근할 수 있다.
permitAll 모든 접근자 항상 허용
<form-login> 요소를 이용하면 손쉽게 로그인 페이지를 변경할 수 있다.
login-page : 로그인이 요청될 시에 이동할 URL을 설정합니다.username-parameter : 로그인 아이디의 파라미터명 즉 name필드값을 설정합니다.passoword-parameter : 비밀번호의 파라미터 명을 설정합니다.login-processing-url : 폼에서 전송할 URL 값을 설정합니다. (action=login-processing-url)
invaldate-session : 세션을 모두 무효로 할 것인지를 사용자에게 묻습니다.logout-url : 로그아웃 경로를 설정합니다.logout-seccess-url : 로그아웃이 성공한 뒤에 이동한 경로를 설정합니다.
패턴 설정은 위부터 순서대로 적용되고 패턴매칭이 완료 되면 아래의 패턴은 무시 되므로 보안 설정을 무시하는 경로는 아래에 나오는 보안 설정 이전에 나와야 한다.
여기서 주의할 점은 로그인 URL 인터셉터를 모든 리소스를 차단하는 인터셉터의 위쪽으로 배치시켜야 한다는 것입니다. 만약 그렇지 않다면 리디렉션 순환 오류로 정상적인 로그인 창이 뜨지 않으실 겁니다.
로그인 페이지는 /login
인증이 성공할때는 loginAuthenticationSuccessHandler로 처리, 실패할때는 loginAuthenticationFailureHandler로 처리.
해당 핸들러 빈설정.
loginAuthenticationSuccessHandler : AuthenticationSuccessHandler 인터페이스 구현
loginAuthenticationFailureHandler : AuthenticationFailureHandler 인터페이스 구현
페이지 권한 설정 할때 (use-expressions="true“) 표현식 사용을 설정하면 표현식들의 사용이 가능해진다.
표현식 사이에 AND, OR 연산도 가능.
org.springframework.security.access.expression.SecurityExpressionRoot
SecurityExpressionRoot클래스에 표현식 메서드들이 정의. 이 클래스를 상속받은 클래스를 생성해서 메서드를 생성
<security:expression-handler>를 등록하지 않으면 DefaultWebSecurityExpressionHandler가 사용되고 표현식을 새로 만들고 싶으면 SecurityExpressionRoot클래스를 상속해서 그안에 표현식 메서드를 정의하고 createSecurityExpressionRoot 메서드에서 루트 객체를 새로 정의한 루트 클래스 객체로 정의. 그 클래스 객체를 사용하는 ExpressionHandler클래스를 생성해서 <security:expression-handler>를 등록하면 메서드를 사용.
SecurityExpressionRoot 클래스에서 표현식 메서드들이 정의 되어있다. 이 클래스를 상속받은 WebSecurityExpressionRoot 클래스를 상속받아서 만든 MyWebSecurityExoressionRoot 클래스. 이 클래스 객체를 사용하는 DefaultWebSecurityExpressionHandler를 상속받아서 만든 MyWebSecurityExpressionHandler를 <security:expression-handler>에 정의 해준다.
SecurityExpressionOperations 인터페이스 안에 hasRole, hasAnyRole, permitAll....
MethodSecurityExpressionRoot 클래스는 디폴트로 정의되어있어서
<security:expression-handler>를 등록하지 않으면 DefaultWebSecurityExpressionHandler가 사용되고 표현식을 새로 만들고 싶으면 SecurityExpressionRoot클래스를 상속해서 그안에 표현식 메서드를 정의하고 createSecurityExpressionRoot 메서드에서 루트 객체를 새로 정의한 루트 클래스 객체로 정의. 그 클래스 객체를 사용하는 ExpressionHandler클래스를 생성해서 <security:expression-handler>를 등록하면 메서드를 사용.
SecurityExpressionRoot 클래스에서 표현식 메서드들이 정의 되어있다. 이 클래스를 상속받은 WebSecurityExpressionRoot 클래스를 상속받아서 만든 MyWebSecurityExoressionRoot 클래스. 이 클래스 객체를 사용하는 DefaultWebSecurityExpressionHandler를 상속받아서 만든 MyWebSecurityExpressionHandler를 <security:expression-handler>에 정의 해준다.
AbstractAuthenticationProcessingFilter를 상속받은 UsernamePasswordAuthenticationFilter.
UsernamePasswordAuthenticationFilter가 사용하는 인터페이스로 AuthenticationManager, AuthenticationSuccessHandler, AuthenticationFailureHandler..
AuthenticationManager 인터페이스의 authenticate() 메써드내에서 실질적인 인증 작업한다. Spring security에서는 AuthenticationManager 인터페이스를 구현한 디폴트 클래스로 ProviderManager를 지원.
ProviderManager 클래스는 ProviderManager로 전달되는 AuthenticationProvider를 이용하여 실질적인 인증 작업을 진행하게 된다. ProviderManager 클래스는 전달된 모든 AuthenticationProvider의 authenticate() 메써드를 호출함으로서 인증 작업을 진행하게 된다.
Spring Security에서 Authentication(인증)을 담당하는 핵심 인터페이스는 Authentication, AuthenticationManager, AuthenticationProvider 세개이다. 이 세개의 인터페이스를 구현하고 있는 구현 클래스들이 실질적인 Authentication 작업을 담당하게 된다. 만약 Acegi Security에서 기본적으로 제공하는 구현 클래스외에 별도의 기능이 필요하다면 이 인터페이스를 구현함으로서 가능하다.
Authentication 클래스는 Authentication(인증)을 진행하기 위하여 필요한 기본 정보들(Principal, Credential)을 포함하고 있으며, 인증이 완료된 후에는 Principal, Credential 정보외에 Authorities 정보를 포함하게 된다. 각 사용자는 하나 이상의 권한을 가질 수 있으므로 Authorities의 배열을 가지게 된다. Authentication 클래스의 정보는 인증 및 인가의 과정을 실행하기 위하여 필요한 정보를 지속적으로 유지하게 된다.
AuthenticationManager 인터페이스의 authenticate() 메써드내에서 실질적인 인증 작업을 하게 된다. 인증을 위하여 필요한 모든 정보는 Authentication 클래스를 통하여 전달된다. Spring Security는 AuthenticationManager 인터페이스를 구현하는 디폴트 클래스로 ProviderManager를 지원하고 있다.
ProviderManager 클래스는 ProviderManager로 전달되는 AuthenticationProvider를 이용하여 실질적인 인증 작업을 진행하게 된다. ProviderManager 클래스는 전달된 모든 AuthenticationProvider의 authenticate() 메써드를 호출함으로서 인증 작업을 진행하게 된다.
ProviderManager 클래스는 하나 이상의 AuthenticationProvider를 이용하여 인증 작업 중 단 하나의 AuthenticationProvider를 통하여 인증이 성공하면 인증이 성공한 것으로 판단하고 나머지 AuthenticationProvider에 대한 인증 과정을 거치지 않게 된다. 인증이 성공하면 인증이 성공했다는 이벤트는 발생시킨다. 따라서 인증이 성공할 경우 추가적인 작업이 필요한 경우가 있다면 Spring 프레임워크의 Event 메커니즘을 이용하는 것이 가능하게 된다.
ProviderManager이 AuthenticationManager 인터페이스를 구현.
ProviderManager 클래스는 ProviderManager로 전달되는 AuthenticationProvider를 이용하여 실질적인 인증 작업을 진행하게 된다. ProviderManager 클래스는 전달된 모든 AuthenticationProvider의 authenticate() 메써드를 호출함으로서 인증 작업을 진행하게 된다.
defaultAuthenticationProvider : AuthenticationProvider 인터페이스를 구현