Record

개념

======================

사용 이유

보안의 수준을 알 수 없는 애플리케이션에서 일일이 계정을 만들어 사용하면 ID/PW관리가 어렵고 개인정보가 유출되면 연쇄적으로 피해가 심각해질 수 있기 때문에 보안의 수준이 어느정도 검증된 사이트(OAuth provider(ex. google, facebook))의 API를 이용해서 인증을 받는 방법(OAuth)이 보안상 좋기 때문이다.

OAuth1.0 단점

암호화 요구사항의 복잡성
웹 기반 애플리케이션만 지원
성능 확장에 어려움

OAuth 역할들(Roles)

  • Client 사용자가 사용하려는 우리가 만든 서비스.
    • 클라이언트는 자원 소유자를 대신하여 자원 서버의 서비스를 사용하고자 하는 애플리케이션입니다.
  • Resource Server 서비스에 자신의 API를 제공하는 타사 서비스.
    • 자원 서버는 보호된 정보를 제공하는 서버로 일반적으로 웹 애플리케이션입니다.
  • Resource Owner 타사 서비스 API의 정보의 주인, 즉 우리가 만든 서비스를 타사 서비스를 통해 이용하려는 사용자.
    • 자원 소유자는 자원 서버에 계정을 가지고 있는 사용자로 클라이언트가 그들의 계정을 통해 자원 서버에 접근하는 것을 인가(authorize)합니다.
  • Authorization Server 인가 서버는 클라이언트가 자원 서버의 서비스를 사용할 때 사용하는 접근 토큰(Access Token)을 발행합니다.

인가 승인 유형(Authorization Grant Types)

  • 인가 코드 승인 (Authorization Code) : 웹 서버 상에서 동작하는 애플리케이션 (가장 많이 사용되는 유형)
    • 클라이언트가 다른 사용자 대신 특정 리소스에 접근을 요청할 때 사용됩니다. 리스소 접근을 위한 사용자 명과 비밀번호, 권한 서버에 요청해서 받은 권한 코드를 함께 활용하여 리소스에 대한 엑세스 토큰을 받는 방식입니다.
  • 시적 승인 (Implicit) : 모바일 앱 또는 단말기에서 동작하는 웹 애플리케이션
    • 권한 부여 코드 승인 타입과 다르게 권한 코드 교환 단계 없이 엑세스 토큰을 즉시 반환받아 이를 인증에 이용하는 방식입니다.
  • 자원 소유자 패스워드 승인 (Resource Owner Password) : 단말기 OS 또는 높은 신뢰 관계의 애플리케이션 (다른 유형들을 사용할 수 없는 경우에만 사용)
    • 클라이언트가 암호를 사용하여 엑세스 토큰에 대한 사용자의 자격 증명을 교환하는 때입니다.
  • 클라이언트 인증 정보 승인 (Client Credentials) : 애플리케이션 API 접근 (신뢰하는 클라이언트만 사용)
    • 클라이언트가 컨텍스트 외부에서 액세스 토큰을 얻어 특정 리소스에 접근을 요청할 때 사용하는 방식입니다.

프로세스

Authorization Code

Alt text

  • (1) 클라이언트가 파리미터러 클라이언트 ID, 리다이렉트 URI, 응답 타입을 code로 지정하여 권한 서버에 전달합니다. 정상적으로 인증이 되면 권한 코드 부여 코드를 클라이언트에게 보냅니다.
    • 응답 타입은 code, token 이 사용 가능합니다.
    • 응답 타입이 token 일 경우 암시적 승인 타입에 해당합니다.
  • (2) 성공적으로 권한 부여 코드를 받은 클라이언트는 권한 부여 코드를 사용하여 엑세스 토큰을 권한 서버에 추가로 요청합니다. 이때 필요한 파라미터는 클라이언트 ID, 클라이언트 비밀번호, 리다이렉트 URI, 인증 타입 입니다.
  • (3) 마지막으로 받은 엑세스 토큰을 사용하여 리소스 서버에 사용자의 데이터를 보냅니다.

Implicit

Alt text

  • (1) 클라이언트가 파리미터러 클라이언트 ID, 리다이렉트 URI, 응답 타입을 code로 지정하여 권한 서버에 전달합니다. 정상적으로 인증이 되면 권한 코드 부여 코드를 클라이언트에게 보냅니다.
    • 응답 타입은 code, token 이 사용 가능합니다.
    • 응답 타입이 token 일 경우 암시적 승인 타입에 해당합니다.
  • (2) 응답 해준 Access Token 이 유효한지 검증 요청을 합니다.
  • (3) 요청 받은 Access Token 정보에 대한 검증에 대한 응답값을 돌려줍니다.
  • (4) 유효한 Access Token 기반으로 Resource Server와 통신합니다.

Resource Owner Password

Alt text

  • (1) 인증을 진행합니다. 대부분 ID, Password를 통해서 자격 증명이 진행됩니다.
  • (2) 넘겨 받은 정보기반으로 권한 서버에 Access Token 정보를 요청합니다.
  • (3) Access Token 정보를 응답 받습니다. 이때 Refresh Token 정보도 넘겨 줄 수도 있습니다.
  • (4) Access Token 기반으로 Resource Server와 통신합니다.

Client Credentials

Alt text

  • (1) Access Token 정보를 요청합니다.
  • (3) Access Token 정보를 응답합니다. 이때 Refresh Token 정보는 응답하지 않는 것을 권장합니다. 별다른 인증 절차가 없기 때문에 Refresh Token 까지 넘기지 않는 것이라고 생각합니다.
  • (4) Access Token 기반으로 Resource Server와 통신합니다.

Facebook 프로세스

Alt text

  • (1) 포탈에 node.js 사이트 관련 정보 (서비스 URL, CallBack URL, 서비스 명 등)을 입력하면,
  • (2) 포탈에서 client_id와 client_secret을 발급해준다. client_id는 서버에서 발급되는 node.js 만든 서비스에 대한 id 라고 생각하면 되고, client_secret은 그 id에 대한 일종의 인증용 패스워드이다. (절대로 외부에 노출되면 안되는)
  • (3) 이렇게 받은 client_id와 client_secret을 node.js 애플리케이션 내에 저장한다.

Alt text

  • (1) 먼저 사용자는 Web Browser에서, node.js 서버로 서비스를 요청한다.
  • (2) Node.js 서버는 사용자가 로그인이 되어 있지 않은 상태라면, Facebook log in URL에 대한 rediretion URL을 브라우져에게 보낸다. 이 때, node.js 서버임을 식별하기 위해서 client_id와 몇 가지 추가적인 정보를 보내는데, 그 내용은 다음과 같다. Ÿ client_id : 사용자를 통해서 인증을 요청하는 서비스가 앞에서 등록한 node.js 애플리케이션임을 알려준다. Ÿ redirect_url : 페이스북 인증서버에서 인증이 끝난후에, 인증 결과를 받을 node.js 애플리케이션으 HTTP URL을 정의한다. Ÿ scope : 페이스북에 접근을 요청한 리소스 목록을 정의한다. 예를 들어, 글쓰기, 읽기, 사진 올리기, 연락처 공유등과 같이 리소스에 대한 범주를 정의한다. Oauth 2.0의 특징중의 하나가 단순히 사용자 인증(Authentication)만을 하는 것이 아니라, 사용자가 소유한 리소스중, 접근을 허가 하는 권한 제어(Authorization) 기능을 함께 제공한다는 것이다.

https://oauth2 authorizationserver.com/auth?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=photos

실제 facebook용 redirection URL

https://www.facebook.com/login.php?skip_api_login=1&api_key=253044994897796&signed_next=1&next=https://www.facebook.com/v2.0/dialog/oauth?redirect_uri=http://localhost:8080/auth/facebook/callback&scope=read_stream&response_type=code&client_id=253044994897796&ret=login&cancel_uri=http://localhost:8080/auth/facebook/callback?error=access_denied&error_code=200&error_description=Permissions error&errorreason=user_denied#=_&display=page

  • (3) Browser는 Redirect URL을 받아서,페이스북의 인증 서버 URL로 Redirect를 한다.
  • (4) 페이스북 인증 서버는 log in page를 사용자에게 보낸다.
  • (5) 사용자는 사용자 ID와 PASSWORD를 입력한다. 인증이 되고 나면, scope에 의해서 리소스에 대한 접근 요청을 허가할 것인지를 물어보는데, 아래는 node.js 애플리케이션이 글쓰기 권한을 요청했을때 사용자에게 node.js 애플리케이션에 글쓰기 권한을 허용할지를 물어보는 화면이다.
  • (6) 페이스북의 인증서버는 ID,PASSWORD를 인증과 권한 획득에 성공하면, 인증과 권한 획득에 성공했다는 Authorization Code와 함께, 다시 2에서 정의된 Service Consumer인 node.js server의 callback URL (redirect_url= redirect_uri=http://localhost:8080/auth/facebook/callback )로 redirect request를 보낸다.
  • (7) Browser는 위에서 받은 Authorization code와 함께, 앞에서 받은 node.js 서버의 callback URL로 redirect를 한다. http://localhost:8080/auth/facebook/callback?code=AQAKlwhopD1DD5(중략)
  • (8) Node.js 서버는 이 사용자가 인증 되었음 증명하는 받은 authorization code를 가지고, 페이스북의 authorization server에 문의한다. POST https://api.oauth2server.com/token grant_type=authorization_code& code=AUTH_CODE_HERE& redirect_uri=REDIRECT_URI& client_id=CLIENT_ID& client_secret=CLIENT_SECRET

Ÿ grant_type : grant type은 앞에서 설명한 4개중에서, 현재 사용하는 grant type은 authorization code 방식이기 때문에 이를 정의한다.

Ÿ code : 앞에서 받은 authorization code

Ÿ redirect_uri

Ÿ client_id : node.js 서버를 인증하기 위한 client id. 앞서 developer portal에서 발급받아서, node.js 서버 애플리케이션안에 넣어놓았다.

Ÿ client_secret : node.js 서버를 인증하기 위한 client_secret(password). 앞서 developer portal에서 발급받아서, node.js 서버 애플리케이션안에 넣어놓았다.

  • (9) 페이스북의 authorization server는 이 authorization code를 가지고, 해당 요청이 인증되었음을 확인하고, node.js 서버에게로 API 접근을 허용하는 access_token을 발급한다.
  • (10) Node.js 서버는 이 access_token을 가지고 페이스북 API에 접근을 요청하면, 페이스북 API서버는 access_token을 통해서 API 접근 가능 여부를 판단한 후, 인가된 요청인 경우 API 요청을 수락하여 서비스를 제공한다.