상세 컨텐츠

본문 제목

Keycloak를 활용한 OAUTH2로 로그인하기 (Feat.미해결 에러에 대한 고민)

기타

by 리액트바오 2024. 2. 1. 21:29

본문

와디즈사이트의 로그인화면을 가져와보았다.

와디즈사이트를 로그인하려면 카카오, 네이버, 구글, 페이스북, 애플 로그인을 할 수 가 있다. 

와디즈뿐 아니라 요즘음 많은 사이트에서 이렇게 SNS로그인을 할 수 있는것을 볼 수 있다.  SNS로그인을 구현하는방식인 OAUTH에 대해서 알아보고, 또 경험해본 이야기를 적어보려고 한다. 

 

 

OAuth (Open Authorization)란 

Open Authorization: 공개승인

Auth는 비밀번호를 넘겨주지 않고도 온라인에서 제공하는 콘텐츠를 안전하게 공유할 수 있는 시스템이다. 그러니깐, 이용하고싶은 A사이트에 비밀번호를 넘겨주지 않는다 하더라도 하나의 온라인 계정을 사용하여(예를들면 구글 계정을 이용하여) A사이트에 로그인할 수 있는것이다. 

이해를 돕기위해 다시한번 설명해보겠다.

이메일, 소셜 미디어, 쇼핑 사이트 등 온라인에 다양한 계정이 있을거고, 각 계정에는 이름, 이메일 주소는 물론 사진이나 친구 목록과 같은 개인 정보가 포함되어 있다. 이제 사용하고 싶은 멋진 새 웹사이트를 찾았다고 가정해 보자. 하지만 이 앱에는 이메일 주소나 프로필 사진과 같은 다른 계정 중 하나의 정보가 필요하다. 이때, 하나의 온라인 계정을 사용하여(예를들면 구글 계정을 이용하여) 새 웹사이트에 로그인할 수 있는것이다. 

 

비밀번호를 알려주고 싶지 않은 경우

계정에 직접 액세스할 수 있도록 새 웹사이트에 비밀번호를 제공하는 대신(위험함) OAuth를 사용하면 특정 앱에만 제한된 액세스 권한을 앱에 부여할 수 있다. 

 

 

 

 

OAUTH는 데이터를 안전하게 유지한다.  

OAuth를 사용하면 사용하는 모든 앱에 비밀번호를 제공하지 않으므로 데이터를 더욱 안전하게 유지할 수 있다. 대신, 필요한 것에 액세스할 수 있는 임시 패스를 제공하는 것이다. 따라서 OAuth는 요청하는 모든 사람에게 비밀번호를 넘겨주지 않고도 온라인 콘텐츠를 안전하게 공유할 수 있는 유용한 시스템과 같다. 

 

 

 

 

 

OAuth의 흐름

OAuth 2.0 프로세스를 그려보았다.

 

1. 사용자가 서비스에 액세스하려고 함

내가 이용하고 있는것으로 예를 들어볼것이다. 새로 알게된 Mattermost에 SNS계정으로 로그인 싶다고 가정해 보자.(참고로 Mattermost는 슬랙과 디스코드와 비슷하다.)  Mattermost서비스에 엑세스하기 위해서는 이메일 계정이나 소셜 미디어 프로필과 같은 다른 서비스의 데이터에 먼저 액세스해야 한다. 

2. 앱에서 권한 요청

계정을 Mattermost와 연결하려고 하면 서비스 제공업체인 gitlab 승인 페이지로 리디렉션된다. (나의 상황에 맞게 gitlab으로 하겠다.) Mattermost는 특정 데이터에 액세스하거나 사용자를 대신해 특정 작업을 수행할 수 있는 권한을 gitlab에게 요청한다. 

3. 인증 서버로 리디렉션

이제 서비스 제공업체의 인증 서버 gitlab으로 리디렉션된다.  여기에서 아직 로그인하지 않은 경우, 로그인하라는 메시지가 표시된다. 이 단계를 통해 서비스 제공자는 누가 권한을 부여하는지 알 수 있다.

4. 권한 부여

로그인 후 서비스 제공업체는 요청된 권한을 보여주는 동의 화면을 표시한다.

이런화면 많이 봤을것이다.  권한을 검토하고 앱에 대한 액세스 권한을 부여할지 거부할지 결정한다.

5. 인증 코드 생성

접근 권한을 부여하면 인증 서버가 인증 코드를 생성하고 콜백 URL을 통해 Mattermost로 다시 보낸다.  이 코드는 Mattermost가 액세스 토큰으로 교환할 수 있는 임시 토큰 역할을 한다. 

6. 토큰 교환

Mattermost는 클라이언트 ID 및 클라이언트 비밀번호와 함께 인증 코드를 인증 서버로 다시 보낸다. 그 대가로 인증 서버는 액세스 토큰을 다시 보낸다. (토큰을 주거니 받거니~)

7. 액세스 토큰 사용

이제 Mattermost는 액세스 토큰을 사용하여 사용자를 대신하여 서비스 공급자의 API에 요청할 수 있다. 액세스 토큰은 앱이 데이터에 액세스하도록 승인했다는 증거로 사용된다.

8. 액세스 취소

언제든지 서비스 제공업체 웹사이트의 계정 설정으로 이동하여 해당 권한을 제거함으로써 내 데이터에 대한 앱의 액세스를 취소할 수 있다. 

 

 

 

그럼 OAuth가 있고 OAuth2가 있던데 무슨 차이지?

OAuth와 OAuth 2.0은 모두 안전한 권한 부여 및 인증을 가능하게 하는 유사한 목적을 제공하지만 OAuth 2.0은 이전 버전에 비해 향상된 유연성, 보안 및 단순성을 제공한다.  OAuth 및 OAuth 2.0은 관련된 인증 및 권한 부여 프로토콜이지만 몇 가지 주요 측면에서 다르다. 

 

버전: OAuth 2.0은 OAuth 1.0의 후속 버전으로, 이전 버전에 비해 몇 가지 개선 사항과 단순화가 도입되었다.

범위: OAuth 1.0은 주로 웹 서비스 간의 보안 API 인증을 위해 설계되었다. 이와 대조적으로 OAuth 2.0은 더 유연하며 웹 애플리케이션, 모바일 앱 및 IoT 장치를 포함한 더 넓은 범위의 시나리오에 사용할 수 있다.

토큰 유형: OAuth 1.0은 인증을 위해 주로 액세스 토큰과 액세스 토큰 비밀을 사용했다. OAuth 2.0에는 액세스 토큰, 새로 고침 토큰 및 인증 코드를 포함한 다양한 토큰 유형이 도입되어 토큰 관리에 더 많은 유연성과 보안을 제공한다.

단순성: OAuth 2.0은 일반적으로 OAuth 1.0에 비해 구현 및 사용이 더 간단하다. 일반적인 사용 사례에 대한 보다 명확한 지침과 표준 흐름을 제공하여 개발자 친화적이다.

보안 향상: OAuth 2.0에는 보안 HTTPS 통신 지원, 토큰 만료 및 새로 고침 메커니즘 지원, CSRF(Cross-Site Request Forgery)와 같은 다양한 공격에 대한 향상된 보호 등 OAuth 1.0에 비해 여러 가지 보안 향상 기능이 포함되어 있다.

역방향 호환성: OAuth 2.0은 상당한 아키텍처 차이로 인해 OAuth 1.0과 역호환되지 않는다. 그러나 광범위한 채택과 향상된 기능으로 인해 많은 OAuth 1.0 구현이 OAuth 2.0으로 마이그레이션되었다.

 

 

 

 

 

OAuth 서비스의 주요 제공업체

Google: Google은 Google Identity Platform을 통해 OAuth 2.0 인증 및 승인 서비스를 제공한다. 개발자는 사용자 인증과 다양한 Google API 액세스를 위해 Google OAuth를 통합할 수 있다.

Facebook: Facebook은 Facebook 로그인 기능을 통해 OAuth 2.0 인증 서비스를 제공한다. 개발자는 Facebook OAuth를 사용하여 사용자를 인증하고 Facebook의 소셜 그래프 데이터에 액세스할 수 있다.

트위터: 트위터는 API 액세스를 위해 OAuth 1.0a 인증을 제공한다. OAuth 2.0이 널리 보급되었지만 트위터에서는 이전 버전과의 호환성을 위해 여전히 OAuth 1.0a를 지원한다.

GitHub: GitHub는 개발자가 버전 제어 및 저장소 관리 플랫폼과 통합할 수 있도록 OAuth 2.0 인증을 제공한다. 개발자는 GitHub OAuth를 사용하여 사용자가 GitHub 계정으로 로그인하고 GitHub API에 액세스할 수 있도록 할 수 있다.

Amazon: Amazon은 Amazon Cognito 서비스를 통해 OAuth 2.0 인증 및 권한 부여 서비스를 제공한다. 개발자는 Amazon Cognito를 사용하여 사용자를 인증하고 사용자 데이터를 안전하게 관리할 수 있다.

Microsoft: Microsoft는 Azure AD(Azure Active Directory)를 통해 OAuth 2.0 인증 서비스를 제공한다. 개발자는 Azure AD OAuth를 사용하여 SSO(Single Sign-On)를 활성화하고 Microsoft 서비스 및 타사 애플리케이션에 대한 보안 액세스를 활성화할 수 있다.

 

 

 

 

 

그렇다면 OAuth 서비스의 제공업체는 아주아주 큰 회사에서만 제공하는것일까?

No!

이는 OAuth 서비스를 제공하는 회사의 몇 가지 예일 뿐이지만 시장에는 다른 많은 공급자도 있다. 또한 많은 조직에서는 내부 사용을 위해 또는 소프트웨어 플랫폼의 일부로 자체 OAuth 서버를 구현한다. OAuth는 개방형 표준 프로토콜이므로 모든 조직에서 이를 구현하여 인증 및 권한 부여 서비스를 제공할 수 있다. 이는 대기업에만 국한되지 않는다. 실제로 OAuth는 스타트업부터 대기업에 이르기까지 다양한 산업과 모든 규모의 회사에서 널리 사용된다.

 

 

 

 

 

나의상황

OAuth를 이용하여 gitlab로그인을 하고싶은데  토큰을 받지 못했다는 오류가 뜬다.

진행중인 프로젝트의 상황은 이러하다.

 

우리사이트에 연동한 mattermost에 로그인을 oauth로 구현을 해야하는데, 깃랩로그인 버튼을 클릭하면 

이렇게 token에러가 뜨는것이다.

지피티에 물어보면 계속 리다이렉트 uri가 일치하지 않기 때문이라는데 일치한다. 일치한다고!!! ㅜ.ㅜ

그리고 추측할 수 있는 원인으로는 인증 실패, 토큰 교환 실패와 같은 이유일 수 있다고 알려주었다. 

 

 

 

 

그런데 좀 특이사항이 있다.  로그인을 두번하는 상황이랄까?

일단 우리회사가 진행중인 obp사이트에도 먼저 로그인을 해야한다. 그래야 mattermost메뉴에 접근을 할 수가 있단 말이다. 로그인을 한뒤에 mattermost로그인을 깃랩으로 해야하는 상황이다. 혹시 이게 좀 토큰 발급에 문제가 있을까??? 그러니깐, 로그인에 한단계가 더 있다는 특징이 있는거다.(이 부분이 내가만난 토큰에러에 영향을 미치는지 아직 모르겠다.) 먼저 obp에 로그인을 해야 mattermost로그인 화면을 볼수가 있고, mattermost로그인을 깃랩로그인으로 하려고 하는상황이다. 이게 영향이 있는걸까?(지푸라기라도 잡는심정)

 

 

 

 

또 특이사항이 있다면 keycloack을 사용한다는 것이다. 

keycloak은 

Keycloak은 애플리케이션 내에서 사용자 ID, 인증 및 권한 부여 프로세스의 보안 및 관리를 강화하는 역할을 한다.  그런데 keycloak 이놈은 정체가 뭔지, 내가 앞서 파악해온 OAuth의 흐름과는 좀 다른것 같았다. gitlab에서 따로 설정을 해줄 필요가 없는것이다. 

 

 

 

 

그렇다면 왜 Keclak을 쓰면 gitlab에서 따로 설정 안해줘도 될까?

Keycloak은 인증 프로세스를 처리하고 사용자를 대신해서 Mattermost에 인증 토큰을 제공하는 IdP(ID 공급자) 역할을 한다. 이는 사용자가 Keycloak을 통해 GitLab계정으로 로그인할 때 GitLab 자체가 인증 프로세스에 직접 참여할 필요가 없음을 의미한다.

 

 

 

 

GitLab에서 아무것도 구성할 필요가 없는 이유는 Kecloak이 ID 공급자 역할이기 때문이다.

SSO(Single Sign-On): Keycloak은 SSO(Single Sign-On)를 지원하도록 구성되어 사용자가 GitLab 자격 증명으로 한 번 로그인하고 또 로그인할 필요 없이 여러 애플리케이션에 액세스할 수 있도록 한다. 다시 GitLab은 인증을 위해 Keycloak을 사용하는 각 특정 애플리케이션을 인식할 필요가 없다.

OAuth 2.0: Keycloak은 OAuth 2.0 프로토콜을 사용하여 GitLab에서 사용자를 인증한다. 이 설정에서 Keycloak은 OAuth 2.0 인증 서버 역할을 하며 GitLab의 OAuth 2.0 엔드포인트와 통신하여 사용자를 인증하고 자격 증명을 얻는다. 

중앙 집중식 ID 관리: Keycloak을 ID 공급자로 사용하면 조직에서 사용자 인증 및 액세스 제어 정책을 중앙 집중화할 수 있다.  즉, 모든 인증 관련 구성 및 사용자 관리 작업이 Keycloak 내에서 처리되므로 인증을 위해 GitLab과 같은 개별 애플리케이션을 구성할 필요가 없는것이다. 그러니깐 Keycloak은 GitLab과 애플리케이션 간의 중개자 역할을 하고 인증 프로세스를 관리하며 여러 사용자에게 원활한 로그인 환경을 제공하므로 GitLab에는 명시적인 구성이 필요하지 않다.

 

 

 

 

 

IdP(ID 공급자) 역할엔 어떤게 있는지 다시한번 자세히 알아보자.

인증: IdP의 기본 기능은 사용자를 인증하는 것이다. 사용자 이름/비밀번호, 생체 인식 데이터 또는 디지털 인증서와 같은 자격 증명을 기반으로 사용자의 신원을 확인한다.

SSO(Single Sign-On): IdP는 Single Sign-On을 지원하는 경우가 많으므로 사용자가 한 번 로그인하면 다시 로그인할 필요 없이 여러 애플리케이션에 액세스할 수 있다. 이를 통해 사용자가 관리해야 하는 자격 증명 수가 줄어들어 사용자 경험이 향상되고 보안이 향상된다.

사용자 디렉터리: IdP는 일반적으로 사용자 ID와 속성이 저장되는 사용자 디렉터리 또는 데이터베이스를 유지 관리한다. 여기에는 사용자 프로필, 인증 자격 증명, 그룹 멤버십 및 기타 관련 정보가 포함된다.

토큰 발급: 인증에 성공하면 IdP가 사용자에게 보안 토큰을 발급한다. 이러한 토큰에는 사용자의 ID 및 인증 상태에 대한 정보가 포함되어 있다. 일반적인 유형의 토큰에는 JWT(JSON 웹 토큰) 및 SAML(Security Assertion Markup Language) 토큰이 포함된다.

페더레이션: IdP는 종종 페더레이션을 지원하여 다양한 조직이나 도메인에 걸쳐 여러 ID 시스템을 통합할 수 있다. 페더레이션을 통해 사용자는 기본 ID 인프라에 관계없이 리소스와 서비스에 원활하게 액세스할 수 있다.

보안 및 액세스 제어: IdP는 애플리케이션 및 리소스에 대한 사용자 액세스를 규제하기 위해 보안 정책 및 액세스 제어 규칙을 시행한다. 승인된 사용자만 보호된 리소스에 액세스할 수 있고 액세스가 허용되는 것을 보장한다.

 

 

 

 

 

만약 keycloak이 없다면?

Keycloak 또는 유사한 ID 공급자가 없는 경우 각 개별 애플리케이션 내에서 인증 및 사용자 관리를 별도로 처리해야 한다. Keycloak과 같은 중앙 집중식 ID 공급자가 없으면 각 애플리케이션이 자체 사용자 인증 프로세스를 담당하게 된다.

keycloak을 사용하지 않고 그냥 OAuth2를 이용할때말이다. 

위에서 먼저 보았던 OAuth 2.0 프로세스대로 라면

별도 인증 시스템: 각 애플리케이션에는 자체 인증 시스템이 있으며, 여기서 사용자는 사용하는 각 애플리케이션에 대해 별도의 계정을 만들고 관리해야 한다.

별도의 사용자 데이터베이스: 사용자 정보는 각 애플리케이션의 데이터베이스에 별도로 저장되므로 사용자 관리 작업이 중복되고 잠재적으로 일관되지 않은 사용자 경험이 발생한다.

SSO(Single Sign-On) 없음: 중앙 집중식 ID 공급자가 없으면 SSO(Single Sign-On) 기능이 없다. 사용자는 이미 각 애플리케이션 중 하나로 인증했더라도 각 애플리케이션에 별도로 로그인해야 한다.

복잡한 사용자 관리: 여러 애플리케이션에서 사용자 계정, 권한 및 보안을 관리하는 것은 각 애플리케이션이 자체 사용자 관리 기능을 구현해야 하므로 더 복잡하고 시간이 많이 걸린다.

 

전반적으로 Keycloak과 같은 중앙 집중식 ID 공급자가 없으면 사용자 경험이 덜 간소화되고, 각 애플리케이션에서 인증 메커니즘을 구현하기 위한 개발 노력이 증가하며, 여러 사용자 데이터베이스 및 인증 시스템 관리와 관련된 잠재적인 보안 및 유지 관리 문제가 발생할 수 있다.

 

 

 

 

Keycloak을 사용할 때의 흐름

현재상황인 Mattermost에서 인증을 위해 keycloak을 사용할때의 예를 그렸다.

Keycloak을 이용한 프로세스

 

사용자가 GitLab 로그인 버튼을 클릭: 사용자가 Mattermost에서 GitLab 로그인 버튼을 클릭하면 클라이언트 측 애플리케이션은 사용자가 GitLab을 사용하여 인증하기를 원한다는 것을 나타내는 요청을 Mattermost 서버에 보낸다.

Mattermost 서버가 Keycloak으로 리디렉션: Keycloak을 인증 공급자로 사용하여 구성된 Mattermost 서버는 사용자의 브라우저를 Keycloak 인증 엔드포인트로 리디렉션한다. 이 리디렉션에는 클라이언트 ID, 리디렉션 URI 및 기타 필수 세부정보를 지정하는 매개변수가 포함된다.

Keycloak으로 사용자 인증: 사용자의 브라우저가 Keycloak 인증 페이지로 리디렉션되고 여기서 자격 증명을 하라고 요구한다.

(현재 이부분에서 문제가 되고 있는것 같다. 정상적으로 리디렉션되었다면 자격증명을 요청하는 위의 로그인 화면이 떠야하는데, 응답으로 계속 invalid_grant 를 받고 있으니말이다.) 

Keycloak은 사용자 자격 증명의 유효성을 검사한다: 사용자의 자격 증명(로그인을 말한다.)을 받으면 Keycloak은 사용자 데이터베이스에 대해 이를 확인한다. 자격 증명이 유효하면 Keycloak은 인증 토큰을 생성하고 이를 사용자 세션과 연결한다.(Keycloak의 컨텍스트에서 사용자가 로그인하면 Keycloak은 해당 사용자에 대한 세션을 생성한다. 이 세션은 사용자의 인증 상태 및 관련 정보를 추적하는데 Keycloak이 인증 토큰을 생성하고 이를 사용자 세션과 연결한다는 것은 Keycloak이 향후 상호 작용을 위해 사용자의 인증 상태를 인식하고 검증할 수 있도록 이 토큰을 세션에 연결한다는 의미다.)

Keycloak이 Mattermost로 다시 리디렉션: 인증에 성공한 후 Keycloak은 사용자의 브라우저를 Mattermost 서버로 다시 리디렉션한다. 이때, 리디렉션에는 URL 매개변수의 일부로 인증 토큰이 포함된다.

Mattermost 서버가 토큰을 검증한다: Mattermost 서버는 Keycloak으로부터 인증 토큰을 받고, 토큰의 유효성을 검사하여 진위성과 무결성을 보장한다.  토큰이 유효한 경우 Mattermost는 토큰에 포함된 사용자 정보를 사용하여 사용자에 대한 세션을 생성한다.

사용자가 인증된 사용자로 Mattermost에 액세스: 유효한 세션이 생성되면 이제 사용자가 인증되고 Mattermost에 대한 액세스 권한이 부여된다. 이제 인증된 사용자로서 애플리케이션과 상호 작용할 수 있는것이다.

이 흐름을 통해 사용자는 Keycloak을 통해 GitLab 자격 증명을 사용하여 안전하게 인증할 수 있으며 Mattermost 앱 내에서 원활하고 통합된 로그인 환경을 제공할 수 있다.

 

 

 

 

 

 

 느낀점1

키클락의 존재가 뭔지 처음에 이해가 잘 안되서 대체 번거롭게 왜 한번 더 중간에 껴서 난린가!!! 싶었다. 처음엔 키클락이 깃랩에게 또 인증받고 깃랩에서 키클락으로, 키클락이 또다시 메타모스트로 이렇게 가는 흐름이라 추측했기 때문이다. 

알고 보니 키클락은 OAuth2 인증 방법에 비해 더 간단했다.  는 Keycloak이 SSO(Single Sign-On), 토큰 발급, 세션 관리 이런 기능을 즉시 제공하기 때문에 인증 프로세스와 관련된 많은 복잡성을 간단하게 해주기 때문이다.  Keycloak을 사용하면 애플리케이션 개발자를 대신해서 토큰 관리 및 세션 처리와 같은 많은 기본 복잡성을 처리하는 중앙 집중식 인증 서비스를 제공함으로써 인증 프로세스가 단순화된다.  

느낀점2

단순화된 버전을 알기전에 복잡한 버전도 경험을 해본다면, 필요성을 더 느낄 수 있을텐데.. 다음에 사이트 프로젝트할때 keycloak을 사용하지 않는 버전으로 OAuth기능을 구현해보고싶다.

 

 

관련글 더보기