2017년 6월 10일

Spring Security - Login 시 사용자 정의 입력 값 전달하기

SpringSecurity 기반의 인증을 사용하는 환경에서 username 과 password 이외의 값을 추가로 전달하여 사용자를 인증을 할 수 없을까? (예를들어 회사번호, 아이디, 비밀번호를 전달받아 인증을 하는 경우 )

환경

Spring 4.3.1.RELEASE
Spring Security 4.1.2.RELEASE

Stack overflow 및 몇가지 자료를 참고하면 아래와 같이 구현을 한면 되다고 한다.

How to pass an additional parameter with spring security login page
  1. UsernamePasswordAuthenticationFilter 를 확장하여 사용자 정의 필터를 구현.
  2. 사용자 정의 UserDetailsService 구현.
  3. <http/> 설정에 사용자 정의 필터를 추가
아쉽게도  SpringSecurity 4.1 부터는 내부 구현 로직을 변경으로 UsernamePasswordAuthenticationFilter 를 위와 같은 방식으로 사용자 정의 필터로 변경할 수 없다.

SpringSecurity 4.1 이상의 환경에서는 필터를 수정하지 않고 RequestContextFilter 를 사용하여 사용자 정의 AuthenticationProvider 구현체에서  RequestContextHolder 를 사용하여 로그인시에 전달된 추가적인 파라메터 값을 꺼내어 원하는 방법으로 인증을 구현하면 된다.

RequestContextFilter 필터는 web.xml 에 필터 설정을 추가하여 사용할 수 있다.

WEB-INF/web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- spring request context filter -->
<filter>
  <filter-name>requestContextFilter</filter-name>
  <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>requestContextFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>    
 
<!-- spring security filter -->
<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>

또는 Spring Security 설정 컨텍스트 ( 문서에서는 WEB-INF/context-config/securitySubsystemContext.xml 사용함 ) 에 아래와 같이 필터를 추가한다.

WEB-INF/context-config/securitySubsystemContext.xml
1
2
3
4
5
<http auto-config="true" use-expressions="true" disable-url-rewriting="true">
<custom-filter ref="requestContextFilter" before="FORM_LOGIN_FILTER"></custom-filter>       
<form-login login-page="/accounts/login.do" username-parameter="username" password-parameter="password"></form-login>
</http>
<beans:bean id="requestContextFilter" class="org.springframework.web.filter.RequestContextFilter"></beans:bean>


사용자 정의 인증 구현에서는 아래와 같이 RequestContextHolder 클래스를 사용하여 클라이언트에서 전달된 파라메터 값을 접근할 수 있다.
1
2
3
4
5
6
7
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); 
if( attr!=null && attr.getRequest() != null ) {
    long companyId = ParamUtils.getLongParameter(attr.getRequest(), "companyId", 0L);
    return super.retrieveUser(companyId, username, authentication);
}else
    return super.retrieveUser(username, authentication);
}


참고자료
Spring 기반 웹 프로그램 개발 Part 2 - SpringSecurity 사용하기

댓글 없음:

댓글 쓰기