TAI(Trust Association Interceptor)와 WebSphere Application Server를 사용하여 OAuth 토큰 지원하기
소개
OAuth(Open Authorization)는 사용자가 사용자 이름 및 비밀번호와 같은 민감한 계정 정보를 제공하지 않아도 이용자가 사용자 역할을 할 수 있게 하여 데스크탑과 웹 애플리케이션(이용자)에서 안전한 API 인증을 허용하는 오픈 프로토콜이다.
이용자는 모든 고객의 사진을 하나의 웹 페이지에 모으려고 하는 회사이다. 모든 사용자에게 계정을 공유하는 각 사진의 사용자 이름과 비밀번호를 입력하라고 요청하는 대신에 회사가 고객 역할을 할 수 있으며, 웹 사이트를 공유하는 각 사진이 서비스 제공자 역할을 하여 OAuth 토큰을 교환할 수 있다. 이렇게 하면 사용자가 사용자 이름과 비밀번호 정보를 제공하지 않게 되므로 사진을 수집하는 회사는 사용자 계정의 보안을 손상시키지 않으면서 사용자의 사진에 액세스할 수 있게 된다.
개인이나 조직이 OAuth 서비스 제공자가 되려면 OAuth 토큰 요청을 지원하도록 시스템을 구성해야 한다. 이렇게 하는 방식은 여러 가지가 있지만, OAuth를 IBM WebSphere Application Server, LTPA 및 WS-Security가 포함된 특정 애플리케이션 요구사항과 통합하는 가장 좋은 방식을 찾으려고 하는 프로젝트가 오랫동안 진행된 후에야 조사된 모든 가능한 방식 중, TAI를 사용하는 것이 가장 좋다는 사실을 분명하게 확인할 수 있었다.
사용자 정의 TAI(Trust Association Interceptors)를 이용하면 벤더에서 획득한 보안 서비스를 WebSphere Application Server와 통합할 수 있다. 이 경우에는 OAuth가 사용할 보안 서비스에 해당된다. 상위 레벨에서는 TAI가 다음과 같이 작동한다.
- WebSphere Application Server로 요청이 들어오면 HttpServletRequest와 HttpServletResponse를 따라서, WebSphere Application Server 보안 설정에 구성된 각 TAI로 요청이 전달된다.
- 그러면 각 TAI가 HttpServletRequest 오브젝트에 전달된 매개변수에서, 보안 서비스에서 ID 어설션을 처리하기 위해 갖고 있는 보안(인증 또는 권한) 속성을 검색하여 그 TAI가 의도된 TAI인지 판별한다.
- TAI의 다음 단계에서는 요청 과정에서 제공한 데이터를 사용하여 ID를 생성하고 이 ID를 WebSphere Application Server에 확인한다. 그러면 TAI가 구성된 레지스트리에서 사용자를 검색하여 SSO 토큰을 생성한다.
- OAuth 사용자 정의 TAI는 필수 OAuth 요청 매개변수를 확인하고 OAuth 액세스 토큰의 유효성을 검증하여 해당 사용자의 인증 여부와 토큰의 유효성을 판별한다.
표 1. TAI에 대한 대안
대안 | 발견된 문제점 |
---|---|
JAAS 사용자 정의 로그인 모듈 | 고객이 제공한 OAuth 토큰을 재생성하려면 HTTP 요청과 응답에 액세스해야 한다. 불행히도 모듈이 WEB_INBOUND JAAS 로그인의 일부인 경우에만 이 토큰을 로그인 모듈과 함께 사용할 수 있다. 이 개념이 작용하지 않는 또 다른 이유는 OAuth 요청 매개변수가 존재하지 않는 경우에만, 기본적인 사용자 이름/비밀번호 인증을 사용하고 싶지만 JAAS 로그인 모듈 방식의 사용을 막을 수 있는 방법이 없기 때문이다. OAuth 요청을 사용하면 액세스 토큰이 사용자 인증을 처리하기 때문에 사용자 이름/비밀번호를 제공하지 않아도 된다. |
사용자 정의 토큰 생성기/이용자 | 사용자 정의 로그인 모듈과 마찬가지로, OAuth 토큰을 재생성하기 위해 요청/응답에 액세스할 수 없었다. 그 결과 방식이 매우 복잡하게 되었다. |
필터 | 이 방식에서는 특정 애플리케이션을 위한 컴포넌트가 필요하다. 다수의 웹 프로젝트에서 자원을 보호하려고 하면, 각 프로젝트에서 필터를 작성해야 한다. 또한, 필터를 사용하려면 업데이트하여 재배치해야 한다. |
가정
이 기사에서는 독자가 WebSphere Application Server 보안과 WebSphere Application Server 관리 콘솔을 기본적으로 이해하고 있다고 가정한다. OAuth 프로토콜을 잘 알고 있으면 도움이 된다.
또한, 이 기사에서는 서비스 제공자 코드가 이미 제대로 작동하고 있으며 OAuth 토큰을 사용하여 WebSphere Application Server 보호 서비스를 인증하려고 한다고 가정한다. OAuth 서비스 제공자 코드의 세부사항은 이 기사에서는 다루지 않는다. OAuth 프로토콜과 TAI에 대한 세부사항은 참고자료를 참조한다.
사용자 정의 TAI를 작성하려면 com.ibm.wsspi.security.tai.TrustAssociationInterceptor를 구현하는 클래스를 새로 작성해야한다. 다른 프로젝트와 별도로, JAR 파일로 내보낼 수 있도록 이 클래스를 해당 Java™ 프로젝트에 삽입한다. 이 클래스가 TrustAssociationInterceptor를 구현하면 구현되지 않은 메소드를 추가할 수 있다(참고자료 참조).
고객이 전송한 OAuth 토큰의 유효성을 검증하게 되므로 먼저, 예상되는 필수 OAuth 매개변수가 요청에 포함되어 있는지 확인해야 한다(목록 1). 예상되는 요청 매개변수가 존재하면
true
를 리턴하는데, 이는 해당 요청이 OAuth 요청일 가능성이
있다는 점을 TAI에게 알려준다. 이 단계에서는 액세스 토큰의 유효성 검증을 완벽하게 수행하지 않아도 된다. 액세스 토큰의 재생성 및 유효성
검증은 또 다른 메소드가 처리한다(목록 2). 목록 1. isTargetInterceptor() 오버라이드
@Override public boolean isTargetInterceptor(HttpServletRequest req) throws WebTrustAssociationException { boolean target = true; Map<String,String> hdrMap = new HashMap<String,String>(); for (Enumeration<String> hdrs = req.getHeaderNames(); hdrs.hasMoreElements(); ){ String hd = hdrs.nextElement(); hdrMap.put(hd,req.getHeader( hd )); } target &= params.containsKey("oauth_token"); target &= params.containsKey("oauth_consumer_key"); target &= params.containsKey("oauth_signature"); System.out.println("isTargetInterceptor: " + target); return target; } |
요청이 필수 OAuth 매개변수와 함께 WebSphere Application Server로 들어오면 negotiateValidateandEstablishTrust 메소드가 트리거된다. 이 시점에서 요청 매개변수를 이용하여 OAuth 액세스 토큰의 유효성을 검증할 논리를 배치해야 한다(목록 2 참조). OAuth 서비스 제공자 구현은 다른 사용자 정보를 토큰으로 인코딩하며, 인증이나 권한 부여 의사결정을 하기 위해 해당 코드에서 사용할 토큰에서 이 정보를 추출한다. OAuth 서비스 제공자 논리가, 생성된 accessToken이 유효하지 않다고 판별하면 이 메소드는 인증되지 않은 응답을 리턴한다. 그렇지 않고 OAuth 액세스 토큰이 유효한 경우에는 OAuth 액세스 토큰을 통해 판별된 대로 리턴된 TAIResult에 성공했다는 메시지가 표시된다.
목록 2. negotiateValidateandEstablishTrust() 오버라이드
@Override public TAIResult negotiateValidateandEstablishTrust( HttpServletRequest req, HttpServletResponse res) throws WebTrustAssociationFailedException { Map<String,String> hdrMap = new HashMap<String,String>(); for (Enumeration<String> hdrs = req.getHeaderNames(); hdrs.hasMoreElements(); ){ String hd = hdrs.nextElement(); hdrMap.put(hd,req.getHeader( hd )); } Object accessToken = null; //Below method is specific to our OAuth SP implementation. Replace: //AccessToken accessToken = OAuthServiceProvider // .GrantResourceAccess(params, request); if (accessToken == null) { System.out.println("OAuth --- Access token couldn't be created!"); return TAIResult.create(HttpServletResponse.SC_UNAUTHORIZED); } //Strip out LTPA token from response here (see listing 3) String username = accessToken.getUser(); return TAIResult.create(HttpServletResponse.SC_OK, username); } |
이 기술이 SSO(Single-Sign On) 기능을 제공하기 때문에 많은 서비스 제공자 구현에서는 추가 보안에 대한 응답에서 LTPA 토큰을 제거하려고 한다(목록 3 참조). LTPA 토큰이 부여되면 LTPA를 사용하여 보호하는 사이트의 모든 영역을 누구나 LTPA 토큰을 사용하여 액세스할 수 있기 때문에 LTPA 토큰을 제거하지 않으면 코드가 취약해진다. 해당 응답에서 LTPA 토큰을 제거하면 계획대로 OAuth를 액세스할 수 있다.
목록 3. LTPA 토큰 제거(LTPA 버전 1 및 버전 2 쿠키 모두)
Cookie[] cookies = request.getCookies(); if(cookies != null){ for (int i = 0; i < cookies.length; i++) { if (cookies[i].getName().startsWith("LtpaToken")) { cookies[i].setMaxAge(0); cookies[i].setPath("/"); response.addCookie(cookies[i]); } } } |
TAI가 작성되면 WebSphere Application Server를 사용하여 다음과 같은 단계를 통해 사용자 정의 TAI를 구성할 수 있다. (표시된 화면은 WebSphere Application Server V7.0에서 캡처한 것이지만, V8.0에서도 동일한 프로세스가 적용된다.
- TAI 프로젝트를 JAR 파일로 내보낸다.
- 이 파일을
{$installroot}/lib/ext
디렉토리에 배치한다. 예를 들면,/opt/IBM/WebSphere/AppServer/lib/ext
이다({$installroot}/lib
디렉토리에서 이 파일이 사용 가능한지 확인한다.) - 또한, 참조된 모든 JAR 파일을 동일한 디렉토리에 추가한다. OAuth 서비스 제공자 토큰 생성 논리가 공유 JAR 파일에 저장되어 있는 경우에는 이점이 중요하다.
- 관리 콘솔에 로그인한다. Security > Global Security로 이동하여
Web and SIP security를 펼친다. Trust association을
클릭한다(그림 1).
그림 1. 관리 콘솔
- Enable trust association을 선택한다.
- Additional Properties 아래에서 Interceptors를 클릭한 후, New 단추를 클릭한다.
- 사용자 정의 TAI의 Interceptor class name(패키지 정보 포함)을 입력한다(그림 2). 예를 들면,
com.example.CustomTrustAssociationInterceptor
이다.
그림 2. 관리 콘솔의 새 TAI
- OK를 클릭한다.
- 마스터 구성의 변경사항을 저장한 후, 서버, 노드 및 dmgr을 다시 시작하여 변경한 사항을 적용한다.
다시 시작이 완료되면 테스트를 수행하여 TAI가 적절하게 구성되었는지 확인할 수 있다. 사용자 정의 OAuth 프로젝트가 설정되면 OAuth를 테스트할 수 있도록 정상 서비스 제공자 URL과 사용자 정의 토큰을 제공한다. 원하면, Firefox와 같은 브라우저를 사용하여 TAI와 OAuth를 테스트할 수도 있다.
- Firefox 브라우저를 열고 Tools > RESTClient를 선택한다. (RESTClient가 없는 경우에는 참고자료를 확인하여 RESTClient Firefox 추가 기능을 다운로드한다.)
- Enter Login Information 패널(그림 3)에서 Login을 선택한 후, OAuth를 클릭한다.
- oAuth를 선택하고 적절한 인증 방법을 선택한다.
- 서비스 제공자와 연관된 신임정보와 메타데이터를 입력한 후, OK를 클릭한다.
그림 3. Firefox RESTClient
- 서비스 제공자가 제공하는 보호 자원의 메소드 및 URL을 입력한 후, Send를 클릭한다. 제대로 된
경우에는 적절한 응답과 OK 상태를 받게 된다(그림 4).
그림 4. Firefox RESTClient
이제 WebSphere Application Server TAI가 작동 중이므로 고객은 OAuth를 사용하여 OAuth 서비스 제공자에 성공적으로 연결할 수 있을 뿐만 아니라 보호 자원에도 안전하게 액세스할 수 있다. 서비스 제공자 구현을 면밀하게 조사하여 보호 자원 세트가 의도된 것인지 그리고 다른 보안 문제가 처리되었는지 확인한 다음, 토큰 부여 논리를 적절하게 조정한다. OAuth 프로토콜과 TAI를 자세히 배우려면 참고자료를 참조한다.
이 정보는 OAuth 토큰을 WebSphere Application Server와 함께 사용하는 데 도움이 된다. TAI를 사용하는 것이 구현하기 가장 수월한 솔루션일 뿐만 아니라 프로젝트의 배치 요구에도 가장 논리적이다. 그러나 TAI를 사용할 때는 OAuth 요청으로 인해 고객이 WS-Security 및 LTPA 토큰과 같은 다른 보안 방식에 의해 능동적으로 보호되고 있는 모든 자원에 액세스할 수 있게 될 가능성이 있다는 점을 반드시 염두에 두어야 한다. OAuth 서비스 제공자 코드는 고객이 어떤 특정 자원에 액세스하려고 하는지 판별하여 URL을 기반으로 이 액세스를 제한하는 역할을 한다. 이 논리는 서비스 제공자의 OAuth 토큰 부여 구현과 함께 존재해야 한다. 앞에서 설명했듯이 LTPA 토큰을 제거하여 승인을 받은 요청에만 액세스할 수 있게 제한해야 한다.
댓글 없음:
댓글 쓰기