RESTful 자바 패턴과 실전 응용: 3장 보안과 추적성

3장 보안과 추적성

REST API 로깅

javax.servlet.Filter를 활용하고, log4j를 이용한 REST API 로깅 예제.


대규모 분산 환경에서 로그 데이터는 개발자가 디버깅을 시작할 수 있는 거의 유일한 단서이다. 따라서, 로깅은 서버 문제를 추척하고 오류가 발생하기 직전까지의 과정을 재연하는데 상당한 도움이 된다. 이를위해 로그는 아래와 같은 정보를 포함하여야 한다.

  • 현재 날짜/시간
  • 로깅 레벨
  • 스레드명
  • 간단한 로거명
  • 상세한 메시지
  • 최초 호출자(initiator)
또한, 요청 관련 메타 정보(요청 실행 소요 시간, 요청 상태, 요청 객체의 크기 등 상세한 정보)를 로깅하면 성능 이슈나 응답 지연 문제를 조사하는데 도움이 된다.

아래와 같은 민감한 데이터는 마스킹 또는 숨김처리를 해야한다.
  • 고객 정보(신용카드 정보)
  • 암호: 패스워드 은닉기(obfuscator)
  • 개인 식별 정보(Personally Identifiable Information): 성명, 이메일, 신용카드 번호 -> 치환, 셔플링, 암호화 기법으로 마스킹 처리한다.
더 자세한 정보는 Data Masking 참고.
기본적으로 민감한 정보를 다루는 리소스의 페이로드는 로깅을 하지 않는다.

로깅 시스템을 모니터링 시스템과 연계하면 백그라운드로 SLA 지표 등 통계 관련 자료를 수집할 수 있다.

페이스 북은 스크립(Scribe)이라는 자체 솔루션을 개발했고, 구글은 대퍼(Dapper)라는 수천 개의 요청으로부터 데이터를 샘플링하여 추적 가능할 정도의 충분한 데이터로 가공하여 저장한다. 대부분의 경우 충분한 양의 샘플링만으로도 상세한 내용을 추적하는데 큰 도움이 된다는 것이 밝혀졌다.

RESTful 서비스 검증

JAX-RS는 리소스 클래스를 검증하기 위한 Bean Validation 기능을 갖고 있다. 아래의 두 단계를 거쳐 검증한다.

  1. 리소스 메소드 파라미터에 어노테이션을 붙여 제약 조간을 추가한다.
  2. 엔티티가 파라미터로 전달되었을 때 엔티티 데이터가 유효한지 검증한다.
아래의 예제 프로그램을 통해 살펴본다.

  • @ValidateOnExecution
  • @Valid
  • @Notnull
검증과 관련하여 예외 발생 시 리턴되는 에러 코드 유형은 아래와 같다.

  • HTTP 500 Internal Server Error
    • 메소드의 리턴 타입을 검증하는 과정에서 ValidationException, ConstraintValidationException을 비롯한 ValidationException의 서브클래스에 해당하는 예외 발생
  • HTTP 400 Error
    • 기타 메소드 검증 과정에서 ConstraintViolationException 예외 발생

RESTful 서비스의 예외 처리

JAX-RS ExceptionMapper를 이용하여 REST API 개발자가 직접 특정 예외를 발생시키고, 그에 따라 적절한 HTTP 에러 코드를 매핑시킬 수 있다. ExceptionMapper는 애플리케이션이 던진 예외를 가로채 지정된 HTTP 응답을 하기 위한 커스텀 컴포넌트로 아래 예제와 같이 사용할 수 있다.

인증과 인가 (Authentication, Authorization)

Authentication

Authentication은 브라우저나 앱을 통해 시스템에 접속한 유저가 정당한 사용자인지 확인하는 과정이다.

SAML(Security Assertion Markup Language)
SAML은 상이한 주체(특히, ID 제공자와 서비스 제공자) 간에 인증/인가 정보를 교환하기 위한 XML 기반의 공개 표준 데이터 포맷이다. SAML 2.0 명세는 웹 브라우저 SSO 프로파일을 제공하는데, 웹 애플리케이션의 SSO 구현 방법을 정한 것으로 다음 세가지 롤이 정의되어 있다.

  • Principal: 유저 자신
  • IdP(Identity Provider): 유저의 ID를 확인하는 엔티티
  • SP(Service Provider): 유저의 ID를 확인하기 위해 ID 제공자를 이용하는 엔티티
SAML 2.0 Web Browser SSO (SP Redirect Bind/ IdP POST Response) from https://en.wikipedia.org/wiki/SAML_2.0

Authorization

OAuth (Open Authroization)
OAuth는 유저가 애플리케이션에게 권한을 부여하여 id/password를 일일이 입력하지 않아도 자신의 계정과 관련된 사적인 데이터를 접근하게 하는 인증 기법이다. OAuth 2.0에서 SSL은 필수이다.

Flickr 서비스에서의 Snapfish와 같은 인화 서비스를 이용하여 자신의 사진을 인화하고자 하는 사용 시나리오에서 아래와 같이 3 주체를 정의할 수 있다.

  • 사용자, Resource Owner: 리소스의 실 소유주. 대부분의 시나리오에서 사용자가 실 소유주이다.
  • Consumer Application: 유저를 대신하여 서비스를 제공하는 어플리케이션 (Snapfish)
  • 서비스 제공자(Resource Server): 리소스 서버(Flickr)
OAuth 작동 과정은 아래와 같다.
  1. 사용자는 어플리케이션(Snapfish)에 접근하여 인화하고자 한다.
  2. Consumer Application은 서비스 제공자의 인가 URL로 리다이렉트 시킨다. 즉, 서비스 제공자는 웹 페이지를 띄워 이렇게 물어볼 것이다. "컨슈머 애플리케이션이 당신의 데이터를 읽고 쓰려고 하는데, 허락하시렵니까?"
  3. 유저는 사진 인화 애플리케이션(컨슈머)이 자신의 사진에 접근해도 좋다고 허락한다.
  4. 서비스 제공자는 유저를 다시 컨슈머 애플리케이션으로 돌려보낸다 (리다이렉트 URL을 통해서). 이 때 파라미터로 인가 코드를 전달한다.
  5. 컨슈머 애플리케이션은 접근 허가를 받기 위해 서비스 제공자와 인가 코드를 주고 받는다. 서비스 제공자는 컨슈머에게 액세스 토큰과 리프레시 토큰이 동봉된 접근 허가증을 발급한다.
  6. 컨슈머 애플리케이션은 서비스 API에 접근할 수 있는 참조 정보를 갖고 유저를 대신하여 서비스 제공자를 호출할 수 있다. 컨슈머는 서비스 제공자 서버에서 유저 사진을 가져와 인화를 시작한다.
OAuth의 강점은 실제 유저 크리덴셜 대신에 액세스 토큰을 사용하기 때문에 여러 가지 애플리케이션이 뒤섞인 상태에서도 별다른 혼란을 야기하지 않는다는 점이다. SAML 소시자 보장(bearer assertion)은 앞서 언급한 OAuth 3각과 흐럼면에서 유사하지만, 유저 브라우저를 인증 서버로 리다이렉트시키는 대신에 서비스 제공자가 직접 ID 제공자에 접속해서 간단한 인가 보장(authorization assertion)을 획득한다. 서비스 제공자는 인가 코드를 주고 받지 않고, 유저의 SAML 소지조 보장을 교체한다.

OAuth 2.0 명세에는 토큰을 안전하게 보관할 방법이 없는 자바스크립트 언어로 어떻게 브라우저 내부에서 OAuth를 사용할 수 있는지 기술되어 있다. 또, 모바일 폰, 심지어는 웹 브라우저가 아예 없는 장치들에서의 OAuth의 사용법을 고수준에서 설명하고 있으며, 아주 오래된 컴퓨팅 장치나 네이티브 어플리케이션과 앱 간의 상호 작용에 관한 내용까지 다루고 있다.

권한 승인(Authorization Grant)은 리소스 오너 또는 유저의 권한을 승인한다는 의미의 크리덴셜로서, 보도횐 리소스에 클라이언트가 액세스 토큰으로 자유롭게 접근할 수 있게 한다. OAuth 2.0은 유형별로 다음 네 가지를 정의한다. 또한 이외의 승인 유형도 추가 확장이 가능하다.
  • 인가 코드 승인
  • Implicit 승인
  • 리소스 오너의 패스워드 크리덴셜 승인
  • 클라이언트 크리덴셜 승인
Jersey는 클라이언트에만 OAuth 2.0을 지원한다.

Reference

  1. https://www.packtpub.com/application-development/restful-java-patterns-and-best-practices
  2. https://logging.apache.org/log4j/2.x/
  3. https://www.splunk.com/
  4. https://en.wikipedia.org/wiki/Data_masking
  5. https://github.com/facebookarchive/scribe
  6. https://research.google.com/pubs/pub36356.html
  7. https://en.wikipedia.org/wiki/SAML_2.0

댓글

이 블로그의 인기 게시물

[Math] GCD & LCM

Android essentials summary

i++ vs ++i in C and C++