OAuth 및 OpenID Connect
이 섹션은 Backstage가 플러그인이 사용자를 대신해 OAuth Access Token과 OpenID Connect ID Token을 요청해 다양한 서드파티 API에 대한 인증에 사용할 수 있게 하는 방법을 설명합니다.
출처: 문서
본문
이 섹션은 Backstage가 플러그인이 사용자를 대신해 OAuth Access Token과 OpenID Connect ID Token을 요청해 다양한 서드파티 API에 대한 인증에 사용할 수 있게 하는 방법을 설명합니다.
요약
사용자가 OAuth를 통한 인증이 필요한 서드파티 서비스에 대해 작업을 수행하고 싶은 경우가 있습니다. Backstage는 그러한 사용 사례를 위해 GoogleAuthApi 같은 표준화된 Utility API를 제공합니다. Backstage에는 또한 이러한 API의 구현 세트가 포함되어 있으며, 이는 auth-backend 플러그인과 통합되어 팝업 기반 OAuth 흐름을 제공합니다.
배경
OAuth의 접근 제어는 앱에 부여된 권한 목록인 scope로 구현됩니다. OAuth 서비스는 프로필 정보 보기, 서비스에서 사용자 데이터 읽기 및/또는 쓰기 같은 특정 scope 집합에 연결된 Access Token을 발행할 수 있습니다. scope 형식과 처리는 각 OAuth 공급자마다 다르며, 사용 가능한 scope 집합은 일반적으로 공급자의 인증 솔루션을 설명하는 문서에서 찾을 수 있습니다. 예를 들어 developers.google.com/identity/protocols/oauth2/scopes가 있습니다.
OAuth 공급자로 로그인하는 일부로, 사용자는 로그인 자체와 앱이 사용을 요청하는 scope 집합 모두에 동의해야 합니다. 이는 OAuth 공급자가 제공하는 페이지를 로드해 이루어지며, 사용자는 여기서 로그인할 계정을 선택하고 요청을 수락하거나 거부할 수 있습니다. 사용자가 로그인 요청을 수락하면 토큰이 발행되고, 토큰 보유자는 그 토큰을 사용해 서드파티 서비스에 인증된 요청을 할 수 있습니다.
@backstage/core-app-api와 auth-backend에서의 OAuth
Backstage의 기본 OAuth 구현은 OAuth 서버 측 오프라인 접근 흐름에 기반합니다. 즉 자격 증명을 교환하기 위해 백엔드를 헬퍼로 사용합니다. 이 유형의 흐름의 이점은 서드파티 쿠키를 사용할 필요가 없으며, 다양한 브라우저와 프라이버시 브라우징 플러그인, 엄격한 보안 설정 등에서 견고하다는 것입니다.
이 구현은 또한 팝업 기반 흐름을 사용하며, 여기서 auth 요청은 앱이 열는 새 팝업 창에서 처리됩니다. 팝업 기반 흐름을 사용하면 리다이렉트 없이 앱의 어떤 시점에서든 인증을 요청할 수 있습니다. 이 때문에 모든 scope를 미리 요청할 필요가 없고, 리다이렉트로 앱을 방해하거나 플러그인 작성자가 리다이렉트 후 상태를 복원하도록 강제할 필요도 없습니다. 전반적으로 플러그인 내에서 인증된 요청을 만드는 것이 훨씬 쉬워집니다.
OAuth 흐름
다음은 @backstage/core-app-api의 auth-backend와 DefaultAuthConnector가 구현하는 OAuth 흐름을 설명합니다.
컴포넌트와 API는 사용 가능한 모든 Auth 공급자에서 Access 또는 ID Token을 요청할 수 있습니다. 요청한 scope를 (최소한) 포함하는 캐시된 신선한 토큰이 이미 있다면 즉시 반환됩니다. OAuth 공급자가 토큰 새로 고침을 구현한다면, 세션이 없을 때 이 검사가 토큰 새로 고침 시도를 트리거할 수도 있습니다.
새 scope가 요청되거나 사용자가 해당 공급자로 아직 로그인하지 않았다면, 사용자에게 지정된 공급자로 로그인해야 한다고 알리는 대화 상자가 표시됩니다. 사용자가 계속하는 데 동의하면 전체 동의 흐름을 구현하는 별도의 팝업 창이 열립니다.
팝업 창은 auth-backend 플러그인의 auth 공급자 /start 엔드포인트를 가리키며, 그런 다음 공급자의 OAuth 동의 화면으로 리다이렉트합니다. 동의 화면은 OAuth 공급자가 제어하며, 사용자에게 계정으로 로그인하라는 프롬프트를 표시하고 요청된 scope 집합을 검토하는 등의 작업을 합니다. 로그인 요청이 수락되면 팝업 창은 auth 백엔드의 /handler/frame 엔드포인트로 다시 리다이렉트됩니다. 리다이렉트 URL에는 단기 인증 코드가 포함되며, 백엔드가 이를 가져와 OAuth 공급자에 대한 호출을 통해 장기 토큰으로 교환합니다. 그런 다음 Access 및 가능하면 ID Token이 postMessage를 통해 메인 Backstage 페이지로 전달됩니다. OAuth 공급자가 오프라인 새로 고침을 구현한다면, 새로 고침 토큰이 auth-backend 플러그인의 특정 공급자로 범위가 지정된 HTTP-only 쿠키에 저장됩니다.
특정 공격으로부터 보호하기 위해 위 흐름에는 간단한 nonce 검사와 가벼운 CSRF 보호 헤더도 포함됩니다. nonce 검사는 공격자가 데이터를 수집하기 위해 사용자가 선택한 계정으로 로그인하도록 속이는 공격으로부터 보호하기 위해 수행됩니다. 흐름의 첫 부분에서 팝업이 /start 엔드포인트로 향할 때 nonce가 생성되어 쿠키와 OAuth state 양쪽에 배치됩니다. 그런 다음 리다이렉트 핸들러에서 쿠키와 OAuth state에서 받은 nonce를 확인하며, 유효하지 않으면 auth 시도가 실패합니다. /refresh 및 /logout 엔드포인트에 대한 CSRF 보호는 X-Requested-With 헤더의 존재를 간단히 확인하며 구현됩니다.
postMessage의 대상 출처도 흐름을 안전하게 유지하는 데 중요합니다. 프로세스는 각 auth 공급자와 환경에 대해 단일 값으로 구성됩니다. 단일 구성된 출처가 없으면 어떤 페이지든 팝업을 열고 접근 토큰을 요청할 수 있습니다.
시퀀스 다이어그램
다음 다이어그램은 이전 섹션에서 설명한 흐름을 시각화합니다.