2. 발표자 소개 제13회 한국자바개발자 컨퍼런스
前 한국자바 개발자 협의회 회장(2007~2008)
現 OkGosu.Net 운영자
現 플랫폼 전문가 그룹 정회원
現 NHN 컨텐츠 제휴팀 부장
現 ZDNet UX 컬럼니스트 (2007~현재)
前 Adobe, Macromedia RIA Consulting
前 한국 SW 아키텍트 연합 공동 회장(2008~2010)
<저서>
- NHN 오픈 API를 활용한 매시업 (2012.9.14, 공저) * 네이버 Open API 개발가이드 작성 (2011.10.18)
- okgosu의 플렉스 4.5 & 플래시 빌더 정석(2011.6)
- okgosu의 액션스크립트의 정석(2010.4)
- 예제로 배우는 플렉스(2006.9)
3. 인증이란? 제13회 한국자바개발자 컨퍼런스
• 어떤 사람이나 사물이 실제 그 사람 또는 사물인지를 판단하는 과정
• 일반적인 인증은 아이디와 비밀번호를 이용
4. id/pw 방식 인증의 위험성 제13회 한국자바개발자 컨퍼런스
• 잘 모르는 써드파티앱에 자신이 가입한 서비스(예: 네이버)의 아이디와 암
호를 직접 입력하면 누출의 위험이 있음.
5. OAuth 등장 배경 제13회 한국자바개발자 컨퍼런스
• 사용자 입장에서는 ID/PW를 써드파티앱에 노출하지 않고 회원 인증할
수 있어야 함.
• 서비스 제공자 입장에서는 인증한 API에 대해 권한을 부여하고 이에 따라
API를 제공할 수 있어야 함.
6. OAuth 버전 제13회 한국자바개발자 컨퍼런스
• 2007년 10월 : OAuth 1.0 발표
• 2008년 6월: OAuth 1.0a (1.0의 보안 문제를 해결한 수정 버전)
• 2010년 4월 : OAuth 1.0a가 IETF 표준으로 등록
• RFC5849 – The OAuth 1.0 Protocol
• 2012년 3월: OAuth 2.0 draft 배포
• 2012년 10월: OAuth 2.0이 IETF 표준으로 등록
• RFC6749 - The OAuth 2.0 Authorization Framework
• RFC6750 – Bearer Token 사용
7. OAuth 적용 기업 제13회 한국자바개발자 컨퍼런스
Oauth 적용 인터넷 서비스 기업 OAuth 버전
Facebook 2.0
Foursquare 2.0
Google 2.0
Microsoft (Hotmail, Messenger, Xbox) 2.0
LinkedIn 2.0
Daum(티스토리 2.0
NHN (오픈API) 1.0a
Daum(요즘, 오픈API) 1.0a
MySpace 1.0a
Netflix 1.0a
트위터 1.0a
Vimeo 1.0a
Yahoo! 1.0a
8. OAuth 1.0a 작동 방식 제13회 한국자바개발자 컨퍼런스
• 3-legged model
• User : 사용자 (예: 네이버 회원)
• Consumer: 써드파티앱 (예: 카페앱 개발사)
• Service Provider: 플랫폼 서비스 제공자 (예: 네이버 서비스)
• OAuth 인증 프로세스
• 써드파티앱은 회원을 서비스 제공자 화면으로 이동시켜 회원인증을 하면 서
비스 제공자로부터 접근토큰(Access Token)을 전달받음
• 서비스 제공자의 API를 호출할 때 접근토큰을 함께 넘겨야 사용 가능
• 예) 네이버 회원 – 카페앱 – 네이버 서비스
3) 네이버 로그인
2) 네이버 로그인 화면 이동
1) 네이버 로그인 요청 4) 접근 토큰 전달 (Access Token)
9. OAuth 인증 절차 – 이용자 관점 제13회 한국자바개발자 컨퍼런스
1) 컨슈머가 제공한 앱에서 ‘네이버 카페목록보기’를 실행한다.
2) 네이버 로그인 화면으로 자동으로 이동하고, 유저가 네이버 아이디와 비
밀번호를 입력한다
3) 네이버 회원 인증 성공시 컨슈머에 대해서 정보 접근 허용 여부를 묻는
화면으로 이동
4) 유저가 컨슈머에 대한 정보 접근을 허락하면 네이버 카페목록 보기 화면
이동
네이버 로그인 화면 컨슈머 정보 접근 허락 화면
10. 컨슈머 등록 제13회 한국자바개발자 컨퍼런스
• 컨슈머가 OAuth를 이용하기 위해서는,
서비스 제공자에게 컨슈머 정보를 등록해 컨슈머키와 시크릿값을 발급 받아야 함
- Consumer Key는 서비스 제공자가 써드파티앱을 식별하기 위한 아이디
- Consumer Secret은 컨슈머에서 전달한 요청을 서비스 제공자가 검증할 수 있도록 하는 비밀 코드
11. OAuth 1.0a 개발 제13회 한국자바개발자 컨퍼런스
• OAuth 1.0a 개발은 서비스 제공자로부터 ‘접근토큰’을 발급 받기 위함
1단계) 서비스 제공자에게 요청토큰(Request Token)을 요청함
이때 oauth_signature, oauth_consumer_key, oauth_nonce를 비롯한 6가지의 매개변수를
서버에 전달해야 하며, oauth_signature는 지정된 방식으로 암호화 처리한 서명값임.
2단계) 화면을 서비스 제공자의 로그인 페이지로 이동시킴
사용자가 로그인 후, 컨슈머의 정보를 보고 접근을 승인
3단계) 서비스 제공자에게 접근토큰(Access Token)을 요청함.
서비스제공자는 컨슈머에게 접근 토큰을 발급하고 컨슈머의 콜백URL로 이동
13. OAuth 2.0의 등장 제13회 한국자바개발자 컨퍼런스
• 2010년 4월 말 OAuth 2.0 draft 등록
• OAuth 1.0a은 2010년 4월
• OAuth 1.0의 불편한 점을 개선하기 위해 처음부터 IEFT에서 스펙논의 시
작
• 암호화, 다양한 앱 지원 등 애플리케이션에 대한 지원 강화
• 스펙정의를 위해 개발자를 비롯한 플랫폼사(구글, 페이스북, 세일즈포스
닷컴 등) 에서도 적극 참여하는 과정에서 잡음이 있었음
• Eran Hammer의 OAuth 2.0에 대한 불만
• OAuth 2.0은 2012년 10월에 IETF 표준 등록
• RFC6749 - The OAuth 2.0 Authorization Framework
• RFC6750 – Bearer Token 사용
14. OAuth 1.0 vs 2.0 제13회 한국자바개발자 컨퍼런스
구분 OAuth 1.0 OAuth 2.0
지원범위 웹 애플리케이션에 초점 다양한 애플리케이션 지원
요청방식 토큰요청시 암호화된 서명 사용 서명없이 HTTPS로 요청가능
Access Token의 유효기간 없음
토큰유효기간 Access Token의 유효기간 설정 가능
(서비스 제공자가 선택적 구현)
인증모델 3-legged 모델 3-legged, 2-legged 등 다양한 방식 가능
인증서버 인증서버에 대한 스펙 없음 인증서버와 API 서버 분리 및 다중화 가능
사용자 User Resource Owner
Public Client (웹 브라우저, 써드 파티앱 등)
써드파티앱 Consumer
용어
Confidential Client (신뢰 가능한 앱 등)
개념 분리
Authorization Server
서비스제공자 Service Provider
API Server
15. OAuth 2.0 인증 방식 제13회 한국자바개발자 컨퍼런스
인증모델 클라이언트 구분 인증방식 설명
Public Client용 Implicit Code Grant OAuth 1.0a와 유사한 토큰을 이용해 인증
3-legged
Confidential Client용 Authorization Code Grant 웹서버 API 호출
Confidential Client용 Password Credentials Grant 클라이언트에 id/pw 저장해서 접근토큰 요청
2-legged
Confidential Client용 Client Credentials Grant id와 secret 값으로 인증
40. OAuth 2.0a 인증 예제 제13회 한국자바개발자 컨퍼런스
구글 TASK API 활용앱 개발
41. 1. 프로젝트 기본 설정 제13회 한국자바개발자 컨퍼런스
1) 안드로이드 퍼미션, 화면 구성은 Naver OAuth와 동일함
2) 아래 jar 파일들을 안드로이드 프로젝트의 libs 폴더에 복사
1. google-api-client-1.4.1-beta.jar
2. google-api-client-googleapis-1.4.1-beta.jar
3. guava-r09.jar // HTTP 처리
4. jackson-core-asl-1.9.9.jar // JSON 처리
42. 2. Activity 변수 선언 제13회 한국자바개발자 컨퍼런스
컨슈머정보, SCOPE, API키, TASK API 요청 URL 변수 설정
// 구글 API Console에 등록한 클라이언트 ID값 설정
String CLIENT_ID = “?????????????.apps.googleusercontent.com";
String API_KEY = “????????????????????????????????"; // API Key 값
String CLIENT_SECRET = ""; // 클라이언트 시크릿 값은 비워둠 (사용안함)
// Task API를 호출하기 위한 SCOPE, URL값
String SCOPE = "https://www.googleapis.com/auth/tasks";
String ENDPOINT_URL = "https://www.googleapis.com/tasks/v1/users/@me/lists";
String REDIRECT_URI = "http://localhost";
String oauthUrl; // 요청URL
43. 3. 버튼 클릭시 제13회 한국자바개발자 컨퍼런스
1) 웹뷰를 초기화하고 보이도록 설정
2) 인증 URL값 획득
3) onPageFinished 구현
4) 인증페이지 로딩
final WebView webview = (WebView)findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
// 자바스크립트를 활성화해야 로그인 페이지가 작동함
webview.setVisibility(View.VISIBLE);
// 인증 URL 값을 획득함
oauthUrl = new GoogleAuthorizationRequestUrl(CLIENT_ID, REDIRECT_URI, SCOPE).build();
webview.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
}); // setWebView
webview.loadUrl(oauthUrl);// 인증 페이지 로딩
44. 4. onPageFinished 구현 제13회 한국자바개발자 컨퍼런스
1) 접근 토큰 요청 준비
// 접근 토큰 요청 준비
JacksonFactory jsonFactory = new JacksonFactory(); // JSON 처리
HttpTransport transport = new NetHttpTransport(); // HTTP처리
String code = url.substring(REDIRECT_URI.length()+7,url.length()); // 접근 토큰 요청시 넘길 코드값
AccessTokenResponse accessTokenResponse; // 접근 토큰 요청 객체 생성
45. 4. onPageFinished 구현 제13회 한국자바개발자 컨퍼런스
2) 접근 토큰 요청
3) Task API 호출
try {
// 접근 토큰 요청
accessTokenResponse = new GoogleAuthorizationCodeGrant(
transport, jsonFactory, CLIENT_ID, CLIENT_SECRET, code, REDIRECT_URI).execute();
// 접근 토큰 요청을 활용한 TASK API 호출
GoogleAccessProtectedResource accessProtectedResource
= new GoogleAccessProtectedResource( accessTokenResponse.accessToken,
transport, jsonFactory, CLIENT_ID, CLIENT_SECRET, accessTokenResponse.refreshToken);
HttpRequestFactory rf = transport.createRequestFactory(accessProtectedResource);
GenericUrl endPoint = new GenericUrl(ENDPOINT_URL);
try {
HttpRequest request = rf.buildGetRequest(endPoint);
HttpResponse response = request.execute();
String str = response.parseAsString();
webview.setVisibility(View.INVISIBLE);
tv.setText(str);
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e1) {
e1.printStackTrace();
}
47. [표-1]리퀘스트 토큰 매개 변수 제13회 한국자바개발자 컨퍼런스
- 리퀘스트 토큰을 요청하기 위해서는 아래와 같은 매개변수를 전달해야 함
- 이때 서비스 프로바이더로 보내는 요청이 위변조되지 않았다는 무결성을 보장하는 서명이 필
요: oauth_signature
- 서명을 생성하기 위한 방법은 oauth_signature_method로 지정
- 서명을 생성하기 위한 필요한 값으로 oauth_consumer_key(컨슈머만 알고 있는 비밀 코드)
를 비롯해 동적인 값을 생성하기 위해 oauth_nonce, oauth_timestamp 값을 포함
매개변수 설명
Service Provider가 인증을 완료한 후 리다이렉트할
Consumer의 웹 주소. 만약 Consumer가 웹 애플리케이션이
oauth_callback
아니라 리다이렉트할 주소가 없다면 소문자로 'oob'(Out Of
Band라는 뜻)를 값으로 사용한다.
Consumer를 구별하는 키 값. Service Provider는 이 키
oauth_consumer_key
값으로 Consumer를 구분한다.
Consumer에서 임시로 생성한 임의의 문자열.
oauth_timestamp의 값이 같은 요청에서는 유일한 값이어야
oauth_nonce
한다. 이는 악의적인 목적으로 계속 요청을 보내는 것을 막기
위해서이다.
OAuth 인증 정보를 암호화하고 인코딩하여 서명 값. OAuth
인증 정보는 매개변수 중에서 oauth_signature를 제외한
oauth_signature
나머지 매개변수와 HTTP 요청 방식을 문자열로 조합한
값이다. 암화 방식은 oauth_signature_method에 정의된다.
oauth_signature를 암호화하는 방법. HMAC-SHA1, HMAC-
oauth_signature_method
MD5 등을 사용할 수 있다.
요청을 생성한 시점의 타임스탬프. 1970년1월 1일 00시 00분
oauth_timestamp
00초 이후의 시간을 초로 환산한 초 단위의 누적 시간이다.
oauth_version OAuth 사용 버전. 1.0a는 1.0이라고 명시하면 된다.
48. [표-2]억세스 토큰 매개 변수 제13회 한국자바개발자 컨퍼런스
- 억세스 토큰은 사용자가 OAuth 인증을 할 때마다 변경되며, 사용자가 언제라도 제거할
수 있고 유효 기간도 있음 (유효 기간은 오픈 API 제공자에 따라 선택적으로 구현)
매개변수 설명
Consumer를 구별하는 키 값. Service Provider는 이 키
oauth_consumer_key
값으로 Consumer를 구분한다.
Consumer에서 임시로 생성한 임의의 문자열.
oauth_timestamp의 값이 같은 요청에서는 유일한 값이어야
oauth_nonce
한다. 이는 악의적인 목적으로 계속 요청을 보내는 것을 막기
위해서이다.
OAuth 인증 정보를 암호화하고 인코딩하여 서명 값. OAuth
인증 정보는 매개변수 중에서 oauth_signature를 제외한
oauth_signature
나머지 매개변수와 HTTP 요청 방식을 문자열로 조합한
값이다. 암화 방식은 oauth_signature_method에 정의된다.
oauth_signature를 암호화하는 방법. HMAC-SHA1, HMAC-
oauth_signature_method
MD5 등을 사용할 수 있다.
요청을 생성한 시점의 타임스탬프. 1970년1월 1일 00시 00분
oauth_timestamp
00초 이후의 시간을 초로 환산한 초 단위의 누적 시간이다.
oauth_version OAuth 사용 버전
Request Token 요청 시 oauth_callback으로 전달받은
oauth_verifier 값이다. oauth_verifier는 서버에서 생성한
oauth_verifier
무작위 문자열로, 앞 단계에서 누군가 oauth_token을
알아내 해킹을 시도하는 것을 막을 수 있게 해 준다
Request Token 요청 시 oauth_callback으로 전달받은
oauth_token
oauth_token 값
49. OAuth 서명 생성 방식 제13회 한국자바개발자 컨퍼런스
- HMAC_SHA1 방식
: 대칭 키 방식이라 연산 비용이 크지 않고 쉽게 서명을 할 수 있기 때문에 많이 사용되고 있다.
네이버를 포함한 많은 서비스에서 HMAC_SHA1 방식을 기본으로 지원한다.
(HMAC: Hash based Message Authentication Code)
- RSA_SHA1 방식
: 비대칭 키로 서명을 하고 오픈 API 제공자도 클라이언트 서비스의 Private Key를 알 수 없기
때문에 더 안전하지만 Private, Public Key를 생성하고 등록하는 등 쓰기 복잡하고 연산에 부
가적인 비용이 들어간다.
- PLAINTEXT 방식
: 아무런 보안책을 제공하지 않으므로 HTTPS와 같은 채널에서만 써야 한다.