OAuth의 짧은 설명

2013. 6. 7. 11:08 from 컴퓨터 기술

** 본 글은 OAuth 2.0을 기준으로 작성하였습니다.

OAuth 란?


웹, 모바일 앱, 그리고 어플리케이션에서 권한 인증을 수행할 수 있는 단순하고 표준 방법인 Open 프로토콜이다.


간단히 예를 들어보면, 자동차에 발렛키라는게 있다. (소형차만 타는 난 처음 들었다. 헉 그런게 있었어???) 발렛키는 단어 의미 그대로 발렛 파킹(대리 주차) 할 때 주차요원에게 주는 키다. 이 발렛키는 트렁크는 열수 없고, 1km만 주행할 수 있는 등 자동차 주차에 필요한 제한적인 기능만 사용할 수 있게 하는 키라고 한다(찾아보니 역시나 고급차에 포함되어 있다). 자동차의 발렛키처럼 웹서비스나 웹서비스에서 공개해 놓은 API를 사용하기 위한 인증 수단이 필요하게 된것이다. 그 인증 수단이 OAuth인 것이다.


자동차에 발렛키가 있다면, IT에서 특정 기능에 접근하기 위한 발렛키를 사용하려고 하는데, 그 IT 발렛키를 발급받기 위한 수단이 OAuth이다. OAuth을 이용하면 특정 기능에 접근 할 수 있는 인증토큰(Access Token, 발렛키)를 발급 받을 수 있는 것이다. 그 인증 토큰는 서비스를 접근하기 위한 키로 사용된다.



OAuth의 역할들(Roles)


Resource Owner : 사용자

Resource Server : API 서버

Client : 서드파티 어플리케이션

Authorization Server : 인증서버



OAuth에서 권한 획득 방법


Authorization Code

웹 서버에서 API를 호출하는 등의 시나리오에서 Confidential Client가 사용하는 방식이다. 서버사이드 코드가 필요한 인증 방식이며 인증 과정에서 client_secret 이 필요하다.

로그인시에 페이지 URL에 response_type=code 라고 넘긴다.


Implicit

Token과 scope에 대한 스펙 등은 다르지만 OAuth 1.0a과 가장 비슷한 인증방식이다. Public Client인 브라우저 기반의 어플리케이션(Javascript application)이나 모바일 어플리케이션에서 이 방식을 사용하면 된다. Client 증명서를 사용할 필요가 없으며 실제로 OAuth 2.0에서 가장 많이 사용되는 방식이다.

로그인시에 페이지 URL에 response_type=token 라고 넘긴다.


Resource Owner Password Credentials

이 방식은 2-legged 방식의 인증이다. Client에 아이디/패스워드를 저장해 놓고 아이디/패스워드로 직접 access token을 받아오는 방식이다. Client 를 믿을 수 없을 때에는 사용하기에 위험하기 때문에 API 서비스의 공식 어플리케이션이나 믿을 수 있는 Client에 한해서만 사용하는 것을 추천한다.

로그인시에 API에 POST로 grant_type=password 라고 넘긴다.


Client Credentials

어플리케이션 이 Confidential Client일 때 id와 secret을 가지고 인증하는 방식이다.

로그인시에 API에 POST로 grant_type=client_credentials 라고 넘긴다.



OAuth는 어떻게 작동하는가?


title OAuth 2.0 flow

Client->+Resource Owner: (A) Authorization Request
Resource Owner-->-Client: (B) Authorization Grant
Client->+Authorization Server: (C) Authorization Grant
Authorization Server-->-Client: (D) Access Token
Client->+Resource Server: (E) Access Token
Resource Server-->-Client: (F) Protected Resource

     

위 플로우차트는 4개의 역할들 간 절차를 보여주며 각각의 단계는 다음과 같다.


(A)  Client는 Resource Owner에게 권한은 요청한다. 권한 요청은 Resouce owner에게 위와 같이 직접 전달 될수도 있으며, 또는 간접적으로 중개인 역활을 하는 인증 서버를 통해 간접적으로 전달 될수도 있다.


(B) Client는 Resource Owner의 권한을 나타내는 증명서와 같은 권한 인증서를 얻는다. 이 권한 인증 방식은 OAuth 명세에 정의된 4가지 권한 인증 방식 중 하나이거나, 또는 확장형 권한 인증 방식(Extension grant type)을 사용한다.(이에 대한 자세한 설명을 보고자 하면, [링크]를 눌러서, 4절의 내용을 보면 된다.) 인증 권한 타입은 권한 인증한 클라이언트, 그리고 인증 서버가 지원하는 타입에 따라 다르다.


(C) Client는 Authorization Server에  클라이언트 인증과 (B)에서 획득한 권한 인증서을 이용해 Access token을 요청한다.


(D) Authorization Server는 클라이언트를 인증하고, 권한 인증서가 유효한지 검증한다. 그리고 모든게 유효하면 Access Token을 발행한다.


(E) Client는 Resource Server에 Access Token을 넘겨, 제한적으로 사용할 수 있는 자원을 요청한다.


(F) Resource Server는 Access Token 유효한지 검증하고, 유효한 경우 제한적으로 사용할 수 있는 자원을 넘겨준다.


여기서 Client가 Resource Owner로 부터 권한 인증서를 얻어오는 방법은 Authorization Server를 중개인으로 둬서,  Authorization Sever를 통해 Resource Owner로 부터 권한 인증서를 얻어오는 방법을 추천하고 있다. 


다음에는 직접 오픈 소스를 이용해 OAuth를 간단한 예제를 구현해 보겠다. 조금 더 한글로 자세히 정리된 곳을 보고 싶다면, 아래 참조 사이트의 [링크]를 따라가 보면 된다.


참조사이트


http://tools.ietf.org/html/rfc6749

http://en.wikipedia.org/wiki/OAuth

http://earlybird.kr/1584



Posted by 빌리 :

POJO 란?


각종 프레임웍 책에서, 그리고 기술 서적에서 POJO라는 단어를 통해 처음 접하게 된 용어이다. 그런데 막상 책에 나온 설명을 읽고, 다시 인터넷을 찾아봐도 이해가 되지 않았다. 평범한 객체!? 명백(Plain) 오래(Old) 자바(Java) 객체(Object)라는데 이게 무슨 말일까? 


실제적으로 POJO를 이해하기 위해선 Enterprize Java Bean(EJB)를 이해해야 한다. EJB에서 나오는 빈을 사용하는데 단점들을 극복하기 위해서 시작되었다. EJB에서 복잡한 3-티어(tier) 애플리케이션 환경을 이해해야 하는 어려움이 있었다. 단순히 빈을 만들기 위해서 다양한 부모 클래스를 알아야 했고, 인터페이스를 구현해야 했던 것이다. 이러한 제약들을 없애고 '단순한 자바 객체'를 이용해 개발하자는 것이었다. 이후에는 데이터베이스와 직접 상호 작용하기 위해 POJO 기반의 하이버네이트가 개발되어고, 간단하게 작업을 ORM 기능을 구현할 수 있게 되었다.(하이버네이트를 공부해보니, mybatis보다 쉽게 데이터베이스 작업을 할 수 있다. 한번 공부해놓으면 좋은 기술이다.)


개념적으로는 자바 언어 명세에서 강제적으로 제한되어진 것을 제외하고 어떠한 제약이 없는 자바 객체를 말한다. 구체적으로 예를 들면 다음과 같다. 


1. 부모 클래스를 확장하지 않는다.

public class Foo extends javax.servlet.http.HttpServlet { ...


2. 인터페이스 클래스를 구현하지 않는다.

public class Bar implements javax.ejb.EntityBean { ...


3. 어노테이션(Annotation)을 포함하지 않는다.

@javax.persistence.Entity public class Baz { ...


하지만, 여러 이유 때문에 많은 소프트웨어 제품이나 프레임워크에서 영속성(Persistence)과 같은 기능이 제대로 작동할 수 있도록 어노테이션을 사용하도록 제한을 두고 있다.


POJO는 기존의 복잡한 것들을 버리고, 간단한 자바 객체를 가지고 일을 처리하자는 철학을 가지고 있다.

클래스를 간단히 설계하고, 이 클래스를 여기저기에 배치하기 쉽게 의존성을 줄인 것이다.



POJO는 어떻게 쓰이나?


1. JavaBeans

자바빈 = 직렬화된 POJO. 특징을 살펴 보면 생성자는 어떠한 매개변수도 갖지 않으며, 간단한 이름 명명 규칙([get|set] + 변수명)을 따르는 getter/setter 메소드를 이용해 속성(Property)에 접근할 수 있다. (이러한 규칙을 활용해 코드를 작성하지 않고, 어떻게 사용할 것인가 모델을 명시하면, 프로그램을 작성되는 솔루션도 있다.)  


다음은 POJO 속성들과 양방향 연결을 가진  JSF 컴포넌트의 예를 보여 준다.

<h:inputText value="#{myBean.someProperty}"/>

POJO 클래스는 아래와 같이 정의 될 수 있다.

public class MyBean {
 
    private String someProperty;
 
    public String getSomeProperty() {
         return someProperty;
    }
 
    public void setSomeProperty(String someProperty) {
        this.someProperty = someProperty;
    }
}


자바빈에서 속성 값 "someProperty"을 자동으로 "getSomeProperty()" 메소드를 연결해 값을 가져오고, "setSomeProperty(String)" 메소드를 연결해 값을 설정할 수 있기 때문에 위와 같이 사용할 수 있다.


2. Framwork

POJO를 사용하는 설계들이 점점 더 일반적으로 사용면서, 프레임워크내에서도 POJO의 역할이 커졌다. 이런 모델에서 개발자는 POJO 이외의 것은 생성할 필요가 없어졌다. POJO는 프레임워크 내에 어떠한 의존성을 가지지 않으면서, 순수하게 비즈니스 로직에 초점을 맞출수 있었다. 결국 개발자는 프레임워크를 이용해 개발할 때 비즈니스 로직을 포함한 단순한 클래스를 생성하고, 이를 맵핑해주는 설정 파일만 작성하면 할 일이 끝난다. 


이러한 생각들을 제일 먼저 구현한게 Spring이고, 현재 가장 인기있는 프레임워크가 되었다. 다른 것들에는 다음과 같은 것들이 있다.


- Enterprise JavaBeans

  2.0 버전에서는 JavaBeans 구현하기 위해서 EnterpriseBean을 상속받는 클래스로 구현해야 했지만, EJB3부터 POJO를 지원하기 시작했다. 뒤늦게 POJO의 영향력이 커지며 이를 반영했다.


- JPA (including Hibernate)

  Java persistence API로 자바를 이용해 관계형 데이터를 관리하는 프레임워크이다. 흔히 쓰는 mybatis 같은 O/R 맵핑 프레임워크라고 생각하면 된다. 대신 좀 더 간단하게 쓰기 쉽게 사용할 수 있고, JPA를 기반으로 개발되어진게 Hibernate이다.


- CDI (http://jcp.org/en/jsr/detail?id=299)

  이건 뭐지? 조금 찾아봐야겠다. 2009년에 마지막 릴리즈 이후 추가 개발 활동은 없고, 커뮤니티 가도 2011년 글이 끝이고, 소리 소문 없이 사장되고 있나보다.

  


실제로 POJO를 사용하는 프레임워크를 사용하려면 POJO클래스를 어디서 사용해야 할지 설정이 필요하다. 초기에는 이를 주로 XML을 이용해 설정하다, 이후 어노테이션(Annotation)을 이용하기 시작됐고, 대부분의 프레임워크가 둘 다 지원하게 되었다.


만약 아무것도 배우지 않고 프레임워크를 접하게 된다면, 아무것도 할 수 있는게 없다. 마치 디자인 패턴을 배우지 않은 사람이 디자인 패턴으로 도배된 코드를 보면서 헤메는 것과 같다고나 할까? 프레임워크를 사용하기 위해서는 사용설명서를 반드시 읽어야 한다는 것이다.


프레임워크에서 POJO를 사용하면서 다양한 기술을 사용할 수 있게 되었다. 그게 AOP(Aspect-oriented programming)를 가능하게 만든게 아닐까 하는 생각이 든다. 



정리


POJO를 처음 접하게 되면, 인터넷을 찾아보고, POJO에 대한 글을 읽으며 혼란을 느꼈었다. 뭐 단순한 클래스라고 하는데, 무슨 말이야? 라는 의문이 제일 먼저 들었다. 그런데 시간이 지나면서 프레임워크에 대한 지식도 쌓이고, 설계도 관심을 가지게 되면서 POJO의 역할을 생각해보면, POJO란 하나의 철학이 아닐까 한다. 그 철할을 활용한 것이 프레임워크가 된 것이고 말이다. 처음 접하는 사람은 너무 복잡하게 생각하지 말고, 아~ 이런게 있구나 라고 넘어가도 될 것 같다.



참고 사이트


http://en.wikipedia.org/wiki/Plain_Old_Java_Object

http://blog.naver.com/PostView.nhn?blogId=iamtheman&logNo=130127393725

http://gissmmo.tistory.com/436

http://keymaker83.blogspot.kr/2010/05/pojo%EB%9E%80%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80.html

http://srzero.tistory.com/m/post/view/id/86


* 생각이 조금 다른 부분이 있다면 댓글을 남겨주세요. 위에 글은 개인적인 정리글이라 틀린 부분이 있을 수 있습니다.

'개발자 > Java Enterprise' 카테고리의 다른 글

Java Message Service API  (2) 2013.05.15
Posted by 빌리 :

컴퓨터 프로그램을 개발하면 흔히 MVC 구조, MVC 패턴,  MVC 아키텍처라는 단어를 많이 듣게 된다. 그리고 그 뒤에 간단한 설명이 뒤 따른다.

 

MVC에서 모델은 애플리케이션의 정보(데이터)를 나타내며, 뷰는 텍스트, 체크박스 항목 등과 같은 사용자 인터페이스 요소를 나타내고, 컨트롤러는 데이터와 비즈니스 로직 사이의 상호동작을 관리한다. (출처-위키피디아)

 

뭐 간단히 정리하면 프로그램을 구성하는 요소들을 데이터, 화면, 컨트롤로 나누어서 각자의 역할을 부여해고, 각자 일에만 충실히 수행하자는 말이된다. 결국 각각이 가진 특징들을 이해해, 구성 요소들이 할일만 구현하면, 다른 요소를 수정하지 않으면서 유지보수가 편해진다고 한다.

 

그런데 직접 개발을 하면서 드는 의구심은 이렇다.

 

- 정말 다른건 수정안해도 되나?
- 각각의 역할이 정확히 뭐지??
- 구성 요소들을 알맞게 분류한게 맞을까?
- 컨트롤이 하는 역할은 어디까지 해야하나?
- 컨트롤하는 역할은 너무 많은데..? 이게 정말 맞는거야?

 

이렇게 수많은 궁금증들이 떠오르곤 한다. 수많은 책에서 MVC 구조라고 말하며, MVC의 구성요소들을 설명하면서 스스로 반성을 해보면 스스로 MVC가 무엇이야? 그리고 어떻게 해야 MVC 구조인거야? 라고 묻지만 단순하게 MVC 구성요소와 그 역할들만 설명할 수 있을 거 같다. 그래서 MVC의 각 구성 요소에 대한 가이드 라인정리 하고자 한다.

 

실제로 MVC 아키텍처로 개발된 Framework를 사용한다며, 소스들의 적절한 위치 및 역할을 지키지 않고 개발된다면, 실제 MVC 구성 요소들의 힘이 제대로 발휘되지 않을 것이다. 결국 다시 코드들을 찾아서 죄다 수정하는 평소로 되돌아 갈테니 말이다.

 

정리에 대한 MVC에 가이드라인은 Eclipse Graphical Editing Framework(GEF)에 대한 개념 설명 글을 바탕으로 작성함을 밝힌다.(GEF의 이해[한글][영문])

 

모델(Model)


데이터를 가진 객체를 모델이라 지칭한다.  데이터는 내부에 상태에 대한 정보를 가질 수도 있고, 모델을 표현하는 이름 속성으로 가질 수 있다.

 

모델은 다음 규칙을 가지고 있음을 이해해야 한다.

1) 사용자가 편집하길 원하는 모든 데이터를 가지고 있어야만 한다.

즉, 화면에 네모 박스 안에 글자가 표현 된다면, 네모 박스의 화면 위치 정보, 네모 박스의 크기 정보, 글자 내용, 글자의 위치, 글자의 포멧 정보 등을 가지고 있어야 한다.

 

2) 뷰(View)나 컨트롤러(Controller)에 대해서 어떤 정보도 알지 말이야 한다.

 데이터 변경이 일어 났을때, 모델에서 화면 UI(View)를 직접 조정해서 수정할 수 있도록 뷰를 참조하는 내부 속성값을 가지면 안된다는 말이다.

 

3) 변경이 일어나면, 변경 통지에 대한 처리 방법을 구현해야만 한다.

모델의 속성 중 텍스트 정보가 변경되면, 이벤트를 발생시켜 누군가에게 전달해야 하며, 누군가 모델을 변경하도록 요청하는 이벤트를 보냈을때 이를 수신할 수 있는 처리 방법을 구현해야 한다. 이는 모델이 변경되는 방법을 다른 구성 요소들에게 알려주게 되는 방법이다.

 

 

뷰 (View)


화면에 표시되는 글자, 체크박스, 윈도우와 같은 UI라는 시각적 요소를 지칭한다.

 

뷰에서도 다음 규칙을 이해하고, 사용해야 한다.

1) 모델이 가지고 있는 정보를 따로 저장해서는 안된다.

화면에 글자를 표시 하기 위해, 모델 정보를 전달 받게 될텐데, 그 정보를 유지 하기 위해서 임의로 뷰 내부에 저장하면 안된다는 말이다. 단순히 네모 박스를 그리라는 명령을 받으면, 화면에 표시하기만 하고, 그 화면을 그릴때 필요한 정보들은 저장하지 않는 다는 것이다.

 

2) 모델이나 컨트롤러과 같이 다른 구성 요소를 몰라야 된다.

모델과 같이 자기 자신의 빼고는 다른 요소는 참조하거나 어떻게 동작하는지 알아서는 안된다. 그냥 뷰는 데이터를 받으면, 화면에 표시해주는 역할만 가진다고 보면된다. 각자 이기적이라고 보면 된다. '난 화면에만 그리고 그때 쓴 데이터는 쓰레기 통에 버릴꺼야' 하는 이기적인 녀석 말이다.

 

3) 변경이 일어나면, 변경 통지에 대한 처리 방법을 구현해야만 한다.

모델과 같이 변경이 일어났을때 이에 누군가에게 변경을 알려줘야하는 방법을 구현해야 한다. 뷰에서는 화면에서 사용자가 화면에 표시된 내용을 변경하게 되면 이를 모델에게 전달해서, 모델을 변경해야 할 것이다. 그 작업을 하기 위해 변경 통지를 구현한다.

 

뭐 이쯤 읽었으면 이에 대한 처리 방법을 왜 구현해야 하는지 짐작할 수도 있을것이다. 이는 모델이나 뷰에서 변경이 일어났을때, 이를 컨트럴로에게 알리고, 컨트롤러는 어떻게 처리할지 결정해 다시 다른 구성 요소에서 변경을 알려주는 중재자 같은 역할을 위해 변경 통지 관련 처리 방법을 구현하는 이유이다.

 

 

컨트롤러 (Controller)


모델과 뷰를 연결해 주는 역할을 한다. 주로 비즈니스 로직(문제를 해결하기 위한 과정)이 이 컨트롤러에서 구현되어 있는 것이다. 음식 재료와 음식을 예를 들면, 음식 재료가 있고 이를 조리법을 이용해 음식을 완성한다고 했을때, 음식 재료들은 데이터가 될터이고, 조리법은 컨트롤러, 그리고 완성된 음식은 뷰로 표현할 수도 있을것 같은데... 예를 들고 보니 조금은 부적절하다는 생각도 들지만, 필자의 지식 수준이 여기까지라고 생각하고 글을 읽어주길 바란다.

 

컨트롤러는 다음 규칙을 이해해야 합니다.

1) 모델이나 뷰에 대해서 알고 있어야 한다.

모델이나 뷰는 서로의 존재를 모르고, 변경을 외부로 알리고, 수신하는 방법만 가지고 있는데, 이를 컨트롤러가 중재하기 위해 모델과 그에 관련된 뷰에 대해서 알고 있어야 합니다.

 

2) 모델이나 뷰의 변경을 모니터링 해야 한다.

모델이나 뷰의 변경을 통지 받으면, 이를 해석해서 각각의 구성 요소에게 통지를 해야 하는것입니다.

 

끝맺음

몇 가지 기준을 세우고, MVC 패턴을 이해하고 사용한다면, 왠만한 Framework를 익히는 기초가 될꺼라 생각됩니다. 사실 '좋은 말 한마디가 천금보다 낫다'는 말처럼 개발자에게는 긴 글 보다 한줄의 코드로 이해하기 쉬울 수도 있을텐데....사실 이 글은 스스로에게 알려주는 글이다 보니, 태생적 한계가 존재하게 되었습니다.

 

요즘 기초적인 부분을 정리하면서 드는 생각들은, 수많은 개발 기술들이 세상에 나오고, 활용 되는 것을 보면, 그 내용들은 기초에서 파생되어 발전된 내용이라는 것을 알게됩니다. 기초는 모르고 써도 되지만, 결국 한계에 다다르지요.

 

'개발자' 카테고리의 다른 글

SK Planet CodeSprint 2013 대회  (0) 2013.06.30
SQL Query의 기본  (0) 2013.06.21
POI에서 shiftrow 사용시 hyperlink가 복사 되지 않는 문제  (0) 2013.04.26
Posted by 빌리 :