[ Architecture, Technology ,Web ] SSO(Single Sign On) 그리고 SAML에 대해

이미지
이번 프로젝트 내부에서 어쩌다보니  유저 인증 관련 업무를 담당하게 되었고, 해야하는 업무는 내부에 사용했던 적이 없던  새로운 개발 플랫폼에서  SSO의 프로토콜 중  SAML을 이용해 앱의 인증을 구현해야만 했다. SSO를 생각해본적 조차 없는 상황에 이를 새로운 개발 플랫폼에 도입해야 했기 때문에 많은 시행착오를 겪었으나 구현에 성공하였으며 덕분에 SSO에 대한 전반적인 지식을 쌓을 수 있었다. 이번에는 그러한 과정에서 나온 지식들과 경험을  공유하고자 한다. SSO에 대한 정의 먼저 사전적 정의 부터 살펴보자. 다만, 기술적인 용어다보니 자주 사용하는 옥스포드 사전에 정의를 찾을 수 없기 때문에  검색으로 찾을 수 있는 정의를 몇 가지 살펴보고 교차 검증을 해보자. 첫 번째 정의를 살펴보자. Single sign-on (SSO) is an identification method that enables users to log in to multiple applications and websites with one set of credentials.  SSO는 웹사이트에서 한 번의 인증(one set of credentials)으로 복수의 어플리케이션에 로그인 할 수 있는 인증(identification) 방법(method) 이다. 두 번째는 위키피디아의 정의이다. Single sign-on (SSO) is an authentication scheme that allows a user to log in with a single ID to any of several related, yet independent, software systems. SSO는 독립적이지만 연관되어있는 몇몇 소프트웨어에 대해 하나의 ID로 로그인을 할 수 있도록 하는 인증 구조(scheme) 세부 설명에 조금 차이가 있어 보이지만 전체적인 틀은 매우 비슷해 보인다.  몇 가지 포인트가 되는 단어를 추출해 이를 연결해보자면 아래와 같은 의미를 산출 할 수 있다. 독립적이지만 연관되어 있

[ 프로젝트 BEP ] 제 4장 : 프로그래밍 언어 ③ - 프로그래밍 언어의 패러다임



앞서 우리는 프로그래밍 언어의 역사에 대해 이야기를 해봤다.

그렇다면 우리는 이제 프로그래밍 언어의 패러다임에 대해 
이야기 할 수 있으며, 본론에 들어갈 수 있을 것이다.

프로그래밍 언어 패러다임의 분류

물론 프로그래밍 언어의 패러다임에는 
여러가지가 지목될 수 있다.

하지만 내가 다루고자 하는 패러다임은 4종류이다.

절차적 프로그래밍 패러다임(The Procedural (Imperative) Programming Paradigm),
구조적 프로그래밍 패러다임(The Structured Programming Paradigm),
객체 지향적 프로그래밍 패러다임(The object-Oriented Programming Paradigm),
그리고 마지막으로 다중 패러다임(Multi-Paradigms)을 이야기할 것이며
 
특히 다중 패러다임(Multi-Paradigms)의 경우
구조적, 객체지향적 패러다임이 섞인 패러다임을 이야기할 것이다.

이야기 함과 더불어 각 패러다임에 속하는
언어들을 살펴보며 특성들을 추출해보자.

절차적 프로그래밍 패러다임(The Procedural (Imperative) Programming Paradigm)

절차적 프로그래밍 패러다임은 
프로그램이 최종 목표에 도달하기 위해 
완료 해야 하는 작업 목록을 지정한다.

또한 코드를 서브 루틴으로 나누는 
명령형 프로그래밍 패러다임의 일종인데,

일부 코드를 서브루틴(프로시저, 함수 등으로 불리는)으로 분류하여 
어느 정도 재사용성을 확보 할 수 있으며, 
구조를 좀 더 쉽게 이해하고 유지할 수 있게 해준다.



위의 코드는 Fortran의 코드를 보여주는데,

if, while, for와 같은 예약어를 사용해 
컴퓨터가 이해하기 쉽게 
위에서 부터 아래로 내려가는 흐름(절차적)을 코드로 표현 한다.
 
그러나, 
이에 해당하는 언어들은 인간의 사고 방식보다는 
기계의 사고 방식에 가깝기 때문에 
복잡한 경우에는 해결하기가 까다롭다.

또한 프로그램의 유지 관리가 어렵고, 
프로그램의 덩치가 크면 클 수록 
코드의 재사용이 힘들어진다.

이러한 단점에 의해 여러 패러다임 중 
사용하는데에 많은 비용이 드는 패러다임이다.

이에 언급될 수 있는 언어는 
위에서 언급한 Fortran을 포함한 Algol, Cobl 등이 해당 된다.


구조적 프로그래밍 패러다임(The Structured Programming Paradigm)

구조적 프로그래밍 패러다임은 
앞서 설명한 절차적 프로그래밍 패러다임의 하위 집합으로
절차적 프로그래밍과 유사한 느낌을 받을 수 있으나

임의의 점프(goto와 같은) 및 
전역 상태 변경을 금지하는 등의
절차적 프로그래밍 패러다임 보다 좀 더 체계적인 접근 방식이다.
(goto의 경우 논란의 여지가 있을 수 있음)



위는 C언어의 코드를 보여주는데,

절차적 프로그래밍과 동일하게 
기계가 이해하기 쉽도록 위에서 아래로 순차적으로 
if, where, for를 사용하여 흐름을 제어한다.

구조적 프로그래밍 패러다임의 특징은
전역 변수의 사용을 줄이거나, 제거와 
로컬 변수(지역 변수)의 개념을 도입했다는 것 이다.

1950년대 후반 Algol 58 및 Algol 60이 등장하면서
{}와 같이 블록 구조(Block Structured)를 가지게 되었고,
이 블록 구조 안에 블록 외부에서는 보이지 않는 
로컬 변수(지역 변수)를 도입했다는 것 이다.

다만 이 접근법의 경우
계속해서 문제(모듈)을 더 이상 분해되지 않을 때 까지 
가능한 최소화하는 모듈화(modularity)를 지향함으로써

모듈안의 모듈이 종속되면서 나타나는 
의도하지 않는 데이터의 변화와 
모듈의 낮은 재사용성 방지하지 않으면

낮은 재사용성으로 나타나는 퍼포먼스 하락,
후에 수정해야 할 경우의 비용 증가를 포함해
이로 나타나는 버그가 발생하기 쉬운 리스크 증가 등의
내/외적으로 수 많은 비용이 증가할 수도 있다.

이에 언급될 수 있는 언어는 위에서 언급한 C언어이다.

객체 지향적 프로그래밍 패러다임(The object-Oriented Programming Paradigm)

객체 지향 프로그래밍 패러다임은 기계 보다는 
좀 더 인간이 문제를 해결하는 방식과 유사한 접근 방법으로

속성(attributes)동작(behaviors)이 있고 
특정한 메시지(대개 객체)를 전달하여 
다른 엔티티(객체)들과 상호 작용을 하며,

이 엔티티라는 객체(Object) 측면에서 문제를 해결하려고 한다.

객체 지향 프로그래밍 패러다임은
클래스, 캡슐화, 상속, 추상화 등의 특성을 가진다.

이 중 추상화는 인터페이스와 실제 구현을 분리되는데
특히 이 인터페이스라는 개념은 
현재의 



Django와 Ruby on Rails와 같은 
생산성을 높이기 위해 반복적인 기능을 템플릿으로 제공해주고
이를 오버라이딩 할 수 있게 허용해주는 

지금의 웹 서버 프레임워크를 만들게 해준 
가장 중요한 개념이라 생각한다.

또한 캡슐화를 통해 데이터를 격리하고, 
어떤 것(변수, 메소드 등)을 접근 허용하고 막을 것인지를 지정할 수 있다.



위의 사진은 객체 지향 프로그래밍 패러다임을 담고 있는 
대표적인 언어인 Java의 코드로

메소드와 지역변수를 하나의 Class로 감싸 캡슐화를 하고

내부의 지역 변수는 private라는 명령어를 통해 막음과 동시에 
메소드를 통해서만 값을 수정하고, 변경할 수 있게 하는 
객체지향 프로그래밍 패러다임의 모습을 보여준다.

이 처럼 객체 지향 프로그래밍 패러다임은 
이전 패러다임에 비해 많은 이점이 존재하는데,

추상화와 캡슐화를 통한 모듈화,
데이터를 숨길 수 있어 보안 강화,
중복 코드를 제거 또는 최소화 그리고 상속을 통한
모듈의 재사용성 상승 등의 효과를 볼 수있다.

즉, 재사용성(Reusability), 확장성(Extensibility), 
신뢰성 및 유지보수성(Reliability and Maintainability)이
상승하는 효과를 볼 수 있다.


이에 언급될 수 있는 대표적인 언어는 Java이다.


다중 패러다임(Multi-Paradigms)


위에서 언급했듯이 다중 패러다임은 
여러가지 패러다임이 섞인 경우를 이야기하지만,

여기서 이야기하는 다중 패러다임은
구조적, 객체지향 패러다임이 잘 섞인 것 만을 이야기한다.

이에 언급될 수 있는 언어들은 바로 C++, Ruby와 Python이다.

이 세 가지는 구조적, 객체지향 패러다임이 
비교적 잘 녹아들어가져 있는데,

구조적 패러다임에서의 함수와 
객체지향 패러다임의 클래스와 메소드를 통해 코드를 구성할 수 있다.

특히 이 3가지 언어 중에 가장 훌륭한 언어를 꼽자면 
Python을 꼽고 싶은데,
그 이유는 설계 자체가 Python만의 표준 보다는
확장성을 더욱 염두했기 때문이다.


위의 사진은 Python의 간단한 코드를 보여주는데

코드를 Class의 형태로도, def라는 명령어로 함수로도 정의내릴 수 있다.

또한 선언시 자료형을 명시하지 않는
JavaScript와 같이 느슨한 타이핑을 추구한다.

다만, 이런 다중 패러다임의 문제는
도구를 효율적으로 사용하기 위해서는 
각 패러다임에 대한 이해가 있어야 된다는 것이다.

특히 최근에 다중 패러다임에는 
기본적으로 구조적 패러다임과 객체 지향형 패러다임이 녹아들어가져 있으며,
경우에 따라서는 다른 패러다임들도 들어가 있는 경향이 있기 때문이다.

Django에는 추가적으로 메타 패러다임이 들어가 있다.

패러다임에 대한 이해

좀 더 이해하기 쉽게 다른 예로 들어보자.

한 가지 예로서 게임 캐릭터를 
구현해야 하는 문제가 생겼다고 가정해보자.

그 게임 캐릭터는 쓰랄이라는 캐릭터이다.


이를 어떻게 구현해야 할까?

C와 같은 절차지향적 프로그래밍 패러다임의 면에서 보면
컴퓨터가 이해하기 쉽게 




위와 같이 먼저 쓰랄이 가지고 있는 속성인 
HP, MP, 소유 기술 등을 구조화(Structed) 해야 할 것이다.

또한 이는 기계가 이해하기 쉽게 
가급적 상단 쪽에 선언해야 하며,

그 하단에는 상호 작용하기 위한 
함수, 서브 루틴, 프로시저를 작성해야 한다.

또한 함수와 일부 변수가 분리되어 있는 경향이 있어
전역 변수를 사용하지 않으려면(call by reference 문제), 
포인터를 활용해야 할 필요가 있기 때문에
코드의 가독성이 매우 떨어져 비용이 증가 한다.
(C의 경우) 

반대로 
객체지향 프로그래밍 패러다임에서 바라보면



위와 같이 쓰랄을 하나의 엔티티로 명시하고 
하나의 객체(Object)로서 바라보면 된다.

즉, Class의 이름을 쓰랄로 지정하고 
Class가 가지고 있는 지역변수로 
이름, HP, MP, 능력 등을 지정하고 
이에 관련된 메소드를 작성하면 될 것이다.

이 두 가지 방법 중 어느 것이 이해하기 쉬운가?

당연히 객체지향 프로그래밍 패러다임이
인간으로서 이해하기가 더 쉽다.

따라서 현재 대부분의 언어들이 
객체지향 패러다임의 특징을 가지고 있는 이유는 

객체 지향 패러다임이 절차적 패러다임 보다 
인간의 측면에서 바라보면
설계, 프로그래밍 등이 다소 이해하기 쉽기 때문이다.

좀 더 쉽게 말하면 "생산성"이 뛰어나다.

하지만, 한 가지 주의해야할 점은 
각 패러다임은 서로 상호 배타적이 아니라는 것 이다.

예컨데, 흔히 
절차적 패러다임과 객체지향적 패러다임이 
상호 배타적인 것 처럼 서로 비교되고, 이야기 되어지는데
각 패러다임은 바라보는 시점이 다를 뿐이다.

예컨데, 절차적 프로그래밍 패러다임과 
그 하위인 구조적 프로그래밍 패러다임은 문제를 해결하기 위해 
좀 더 기계에 가까운 관점으로 바라보는 것이고,

객체지향적 프로그래밍 패러다임은 문제를 해결하기 위해
좀 더 인간에 가까운 관점으로 바라보는 것 이다.

따라서 이 두 가지 패러다임의 중 
어떤 특정한 경우에 어느 패러다임이 효율적이라고 말할 수 는 있으나
어느 패러다임이 우열이 있다고 보기에는 힘들다.

그렇기에 경우에 따라, 
그리고 필요(해결하기 힘들 때)에 따라 하나의 솔루션으로서 바라보고
이를 경우에 맞게 적절히 활용하는 것이 중요하다.

즉, 
어느 것이 더 좋고 나쁘다가 아닌
우등하고 열등하고가 아닌
패러다임을 하나의 방법론으로 바라보는 것이 
중요하다는 것이다.

예컨데,
확실히 컴퓨팅적인 퍼포먼스는 당연히 
절차지향 패러다임이 뛰어날 것 이다.

하지만, 프로젝트적 관점에서의 하나의 프로젝트를, 
그리고 서비스를 
즉, 하나의 솔루션을 완성하려고 하는 목적에 있어서는 
객체지향 패러다임이 퍼포먼스가 뛰어나다고 
나는 생각하고 있다.

이를 증명하듯이
객체지향적 패러다임을 담고 있거나 영향을 크게 받은
언어들이 현재 주를 이르고 있다.

어떤 패러다임이 좋고 나쁘냐는 논의는
더 나아가 어떤 언어가 더 좋고 나쁘냐는 논의는
프로젝트 내에서 시스템을 요건 정의를 내릴때 
의미가 있는 것이지,

그 외에는 그다지 큰 의미가 없으며
그런 것들로 우열을 정하려고 하는 논의는 결국
서로의 커뮤니케이션을 방해하는 벽을 새울 뿐이다.

Next Paradigms?

지금 시점(2020년)에는 
아직 다중 패러다임에 속해 있다고 나는 생각하고 있다.

왜냐하면 이런 다중 패러다임에 속하는 Python과 Ruby가 
아직까지는 많은 인기를 누리고 있기 때문이다.

내가 아는한 아직까지는 다중 패러다임이 많은 인기를 누리고 있기 때문에
이런 다중 패러다임을 가지고 있는
언어들이 한동안은 꾸준한 인기를 가질 것으로 보인다.

하지만 다중 패러다임의 경우의 한계는 명확하다.

구조적 패러다임과 객체 지향 패러다임을 가져온 것은 좋으나
패러다임이 섞인 바람에 프로그램의 복잡성을 증가시켰다는 것 이다.

예컨데, 함수형과 클래스형을 허용하면서
통일되지 않은 형태의 프로그램도 동시에 허용되었고,
이는 코드 가독성에도 영향을 주게 된다.

이는 프로그램이 크면 클수록 두드러지게 나타날 것 이다.

특히 일부 다중 패러다임에 속해 있는 
프로그래밍 언어들 중에 2가지 외에도 메타 프로그래밍을 포함한 다른 패러다임을 차용하는 경우가 있는데

패러다임이 추가 되면 추가 될 수록
다른 개발자가 이해하기 더욱 힘들어지며
프로젝트 내부에 나타나는 리스크는 더욱 증가하게 될 것 이다.

즉,
기존 패러다임에 비해 알아야 하는게 너무 많다는 것이다.

하지만, 우리는 다음 패러다임에 대해서 
논의를 해볼 수도 있을 것이다.

여기에 언급될 수 있는 언어는 
최근 구글에서 개발하고 배포하고 있는 




GO라는 언어가 될 수도 있다.

GO language의 설계자들은 프로그래머들이 
C++에 대해  공통적으로 싫어하는 부분에 주목을 했다는데[1]
상속, 제네릭 프로그래밍, 포인터[2]과 같은 특정 기능을
의도적으로 생략했다고 한다.

Go langouage에 대한 특징은 아래의 사진과 같다.


기본 적으로 GO 언어는 C언어에 영향을 받았지만,  
간단함(Simplicity), 안정성(safety)에 중점을 둔다고 한다.

이에 대한 특징은 아래와 같다.

첫 번째, 변수 선언에 있어서 정적, 동적 선언 및 초기화가 가능하다는점
(예 : int x = 0; 또는 var x = 0;)

두 번째, 빠른 컴파일과 원격 패키지 관리 및 문서를 제공해준다는 점

세 번째, 고 루틴(Go Routin)이라는 동시 발생 컴퓨팅(Concurrent computing)[3]을 
하기 위한 문법을 제공하는 점(병렬 처리 가능)

네 번째, C++에서만 사용하는 가상 상속(virtual inheritance)이 아닌
인터페이스 시스템을 사용하는 점

다섯 번째, 라이브러리와 같은 도구들(A toolchain)이 
외부 종속성 없이, 정적으로 연결된 네이티브 바이너리로 생성된다는 점

여기에는 포함되어 있지 않지만, 
Go 언어는 가비지 컬렉션도 사용하고 있다.

코드를 조금 살펴보자


코드를 조금 살펴보면 
C에 영향을 받은 것이 확실히 드러난다.

이 코드만 보면 
스타일 자체는 C와 유사하며 
Class는 보이지 않으며 구조체를 사용한 점, 
포인터 허용 그리고 main을 사용한다는 점이다.

스타일 자체는 구조적 프로그래밍 패러다임에 가까운 것 같다.





참고 :



[3] : 순차적(Several)으로 실행되는 것이 아닌, 동시(concurrently)에 실행되는 컴퓨팅을 말함










2020.10.07 초안 작성 및 개행 완료




이 블로그의 인기 게시물

[ Web ] 웹 애플리케이션 아키텍처 (Web Application Architecture)

[ Web ] 서버 사이드(Sever Side) ? 클라이언트 사이드(Client Side)? 1 [서론, 클라이언트 사이드(Client Side)]

[ Web ] 웹 애플리케이션 서버 아키텍처의 정의 및 유형 ( Define and Types of Web Application Server Architecture )