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

 
 
   requestContextFilter
   org.springframework.web.filter.RequestContextFilter
 
 
   requestContextFilter
   /*
      
 
 
 
  springSecurityFilterChain
  org.springframework.web.filter.DelegatingFilterProxy
 
 
  springSecurityFilterChain
  /*
 


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

WEB-INF/context-config/securitySubsystemContext.xml
     
            
    
    
    


사용자 정의 인증 구현에서는 아래와 같이 RequestContextHolder 클래스를 사용하여 클라이언트에서 전달된 파라메터 값을 접근할 수 있다.

    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 사용하기

댓글 없음:

댓글 쓰기