> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# OIDC 인증

<Info>
  이 기능은 [yu-i-i/overleaf-cep](https://github.com/yu-i-i/overleaf-cep)에서 개발되었습니다. 여기에서는 구성에 필요한 몇 가지 문서를 제공합니다.
</Info>

### 구성

내부적으로 Overleaf OIDC 모듈은 [passport-openidconnect](https://github.com/jaredhanson/passport-openidconnect) 라이브러리를 사용합니다. OpenID Connect 구성에 문제가 있다면 `passport-openidconnect`의 README를 읽어 이 라이브러리가 기대하는 구성을 파악해 보는 것이 좋습니다.

OIDC 인증 모듈을 활성화하려면 `EXTERNAL_AUTH` 환경 변수가 필요합니다. 이 환경 변수는 활성화할 외부 인증 방법을 지정합니다. 이 변수의 값은 목록입니다. 목록에 `oidc`가 포함되어 있으면 OIDC 인증이 활성화됩니다.

예: `EXTERNAL_AUTH=ldap oidc`

OIDC 인증 방법을 사용하면 사용자는 Identity Provider(IdP) 인증 사이트로 리디렉션됩니다. IdP가 사용자를 성공적으로 인증하면, Overleaf 사용자 데이터베이스에서 다음과 같은 구조의 `thirdPartyIdentifiers` 필드를 포함하는 레코드를 확인합니다:

```text theme={null}
thirdPartyIdentifiers: [
  {
    externalUserId: "...",
    externalData: null,
    providerId: "..."
  }
]
```

`externalUserId`는 IdP 서버가 반환한 프로필의 사용자 ID와 일치해야 하며(`OVERLEAF_OIDC_USER_ID_FIELD` 환경 변수 참조), `providerId`는 OIDC 공급자의 ID와 일치해야 합니다(`OVERLEAF_OIDC_PROVIDER_ID` 참조).

일치하는 레코드가 없으면 IdP 사용자 프로필의 이메일과 일치하는 기본 이메일 주소를 가진 사용자를 데이터베이스에서 검색합니다:

* 그런 사용자가 있으면 `thirdPartyIdentifiers` 필드가 업데이트됩니다.
* 일치하는 사용자가 없고 JIT 계정 생성이 비활성화되어 있지 않으면, IdP 프로필의 이메일 주소와 `thirdPartyIdentifiers`로 새 사용자가 생성됩니다.

두 경우 모두 사용자는 외부 OIDC 사용자와 '연결'되었다고 합니다. 사용자는 `/user/settings` 페이지에서 OIDC 공급자와의 연결을 해제할 수 있습니다.

#### 디스커버리 문서로 값 찾기

모든 OpenID Provider(OP)는 `<issuer>/.well-known/openid-configuration`에 디스커버리 문서를 게시합니다. 값을 직접 입력하지 말고 이 문서에서 복사하세요. 문자 하나만 틀려도 로그인이 실패할 수 있습니다.

<Steps>
  <Step title="디스커버리 URL 찾기">
    OP는 Overleaf용으로 만든 클라이언트(공급자) 페이지에 이 URL을 표시합니다. Authentik에서는 **Applications > Providers**를 열고 공급자를 선택한 다음 **OpenID Configuration URL**과 **OpenID Configuration Issuer**를 찾습니다:

    <Frame caption="Authentik: 공급자의 디스커버리 URL과 issuer(테스트 인스턴스)">
      <img src="https://mintcdn.com/ayakaleaf-pro/TjqwH4XzxYAkHStq/images/on-premises/oidc-authentik-provider.png?fit=max&auto=format&n=TjqwH4XzxYAkHStq&q=85&s=e3cb5603d959665472b53e39b58b2775" alt="" width="1280" height="633" data-path="images/on-premises/oidc-authentik-provider.png" />
    </Frame>

    URL은 보통 다음과 같은 형태입니다:

    * Keycloak: `https://keycloak.example.com/realms/<realm>/.well-known/openid-configuration`
    * Authentik: `https://authentik.example.com/application/o/<application-slug>/.well-known/openid-configuration`
  </Step>

  <Step title="값 읽기">
    브라우저에서 URL을 열거나 Overleaf 서버에서 다음을 실행합니다:

    ```shell theme={null}
    curl -s https://authentik.example.com/application/o/overleaf/.well-known/openid-configuration \
      | jq '{issuer, authorization_endpoint, token_endpoint, userinfo_endpoint, end_session_endpoint}'
    ```

    Authentik의 응답은 다음과 같습니다:

    ```json theme={null}
    {
      "issuer": "https://authentik.example.com/application/o/overleaf/",
      "authorization_endpoint": "https://authentik.example.com/application/o/authorize/",
      "token_endpoint": "https://authentik.example.com/application/o/token/",
      "userinfo_endpoint": "https://authentik.example.com/application/o/userinfo/",
      "end_session_endpoint": "https://authentik.example.com/application/o/overleaf/end-session/"
    }
    ```

    Authentik은 공급자 페이지 아래쪽에도 이 URL들을 표시합니다:

    <Frame caption="Authentik: 공급자의 엔드포인트(테스트 인스턴스)">
      <img src="https://mintcdn.com/ayakaleaf-pro/TjqwH4XzxYAkHStq/images/on-premises/oidc-authentik-endpoints.png?fit=max&auto=format&n=TjqwH4XzxYAkHStq&q=85&s=55d130cbbbf27fd11aebafa1ab3f090c" alt="" width="1280" height="633" data-path="images/on-premises/oidc-authentik-endpoints.png" />
    </Frame>
  </Step>

  <Step title="`variables.env`에 복사하기">
    | 디스커버리 문서의 필드 | 환경 변수 |
    | - | - |
    | `issuer` | `OVERLEAF_OIDC_ISSUER` |
    | `authorization_endpoint` | `OVERLEAF_OIDC_AUTHORIZATION_URL` |
    | `token_endpoint` | `OVERLEAF_OIDC_TOKEN_URL` |
    | `userinfo_endpoint` | `OVERLEAF_OIDC_USER_INFO_URL` |
    | `end_session_endpoint` | `OVERLEAF_OIDC_LOGOUT_URL` |

    ```dotenv theme={null}
    OVERLEAF_OIDC_ISSUER=https://authentik.example.com/application/o/overleaf/
    OVERLEAF_OIDC_AUTHORIZATION_URL=https://authentik.example.com/application/o/authorize/
    OVERLEAF_OIDC_TOKEN_URL=https://authentik.example.com/application/o/token/
    OVERLEAF_OIDC_USER_INFO_URL=https://authentik.example.com/application/o/userinfo/
    OVERLEAF_OIDC_LOGOUT_URL=https://authentik.example.com/application/o/overleaf/end-session/
    ```
  </Step>

  <Step title="Overleaf가 OP에 접근할 수 있는지 확인하기">
    Overleaf는 컨테이너 내부에서 token 및 userinfo 엔드포인트를 호출하므로, 브라우저뿐 아니라 컨테이너에서도 OP에 접근할 수 있어야 합니다:

    ```shell theme={null}
    docker exec sharelatex curl -sS -o /dev/null -w "%{http_code}\n" \
      https://authentik.example.com/application/o/overleaf/.well-known/openid-configuration
    ```

    `200`이 출력되어야 합니다.
  </Step>
</Steps>

<Warning>
  `issuer`는 끝의 슬래시까지 포함해 정확히 복사하세요. Overleaf는 이 값을 ID 토큰의 issuer와 한 문자씩 비교하며, 조금이라도 다르면 모든 OIDC 로그인이 다음 오류와 함께 실패합니다:

  `{"message":{"message":"ID token not issued by expected OpenID provider."}}`

  Authentik에서 issuer는 애플리케이션에 속합니다(`.../application/o/<application-slug>/`). authorize, token, userinfo URL은 모든 애플리케이션이 공유하지만, issuer는 Authentik 서버의 주소가 아닙니다.
</Warning>

#### 환경 변수

다음 다섯 개의 필수 변수 값은 OpenID Provider(OP)의 `.well-known/openid-configuration` 엔드포인트에서 확인할 수 있습니다. 위 내용을 참고하세요.

* `OVERLEAF_OIDC_ISSUER` <strong>(필수)</strong>
* `OVERLEAF_OIDC_AUTHORIZATION_URL` <strong>(필수)</strong>
* `OVERLEAF_OIDC_TOKEN_URL` <strong>(필수)</strong>
* `OVERLEAF_OIDC_USER_INFO_URL` <strong>(필수)</strong>
* `OVERLEAF_OIDC_LOGOUT_URL` <strong>(필수)</strong>

다음 두 개의 필수 변수 값은 OP 관리자가 제공합니다.

* `OVERLEAF_OIDC_CLIENT_ID` <strong>(필수)</strong>
* `OVERLEAF_OIDC_CLIENT_SECRET` <strong>(필수)</strong>
* `OVERLEAF_OIDC_SCOPE`
  * 기본값: `openid profile email`
* `OVERLEAF_OIDC_PROVIDER_ID`
  * OP의 임의 ID이며, 기본값은 `oidc`입니다.
* `OVERLEAF_OIDC_PROVIDER_NAME`
  * `/user/settings` 페이지의 `Linked Accounts` 섹션에서 사용되는 OP 이름이며, 기본값은 `OIDC Provider`입니다.
* `OVERLEAF_OIDC_IDENTITY_SERVICE_NAME`
  * 로그인 페이지에서 사용되는 ID 서비스의 표시 이름입니다(기본값: `Log in with $OVERLEAF_OIDC_PROVIDER_NAME`).
* `OVERLEAF_OIDC_PROVIDER_DESCRIPTION`
  * `Linked Accounts` 섹션에서 사용되는 OP 설명입니다(기본값: `Log in with $OVERLEAF_OIDC_PROVIDER_NAME`).
* `OVERLEAF_OIDC_PROVIDER_INFO_LINK`
  * OP 설명에 있는 `Learn more` URL이며, 기본값은 설명에 `Learn more` 링크가 없는 것입니다.
* `OVERLEAF_OIDC_PROVIDER_HIDE_NOT_LINKED`
  * 사용자 계정이 OP와 연결되어 있지 않으면 `/user/settings` 페이지에 OP를 표시하지 않습니다. 기본값은 `false`입니다.
* `OVERLEAF_OIDC_USER_ID_FIELD`
  * 이 속성의 값은 Overleaf에서 외부 사용자 ID로 사용되며, 기본값은 `id`입니다. 다른 합리적인 값으로는 `email`과 `username`(`preferred_username` OIDC 클레임에 해당)이 있습니다.
* `OVERLEAF_OIDC_ALLOWED_EMAIL_DOMAINS`
  * OIDC로 인증하는 사용자의 JIT(Just-in-Time) 계정 생성을 제한합니다. 쉼표로 구분된 도메인 이름 목록으로 설정하면, 사용자 이메일 주소의 도메인이 목록의 도메인 중 하나와 일치하는 경우에만 새 계정이 생성됩니다. 도메인이 일치하지 않으면 관리자가 OIDC 사용자의 이메일 주소를 사용해 강력한 무작위 비밀번호를 설정하거나, 가급적 `hashedPassword` 필드 없이 사용자 계정을 직접 생성해야 합니다. 도메인 이름에는 하위 도메인과 일치시키기 위한 선행 `*.` 와일드카드를 포함할 수 있습니다.
    * 예: `name@example.com` 및 `name@math.example.com`과 같은 이메일 주소를 가진 사용자의 JIT 계정 생성을 허용하려면:\
      `OVERLEAF_OIDC_ALLOWED_EMAIL_DOMAINS=example.com, *.example.com`
    * 예: JIT 계정 생성을 완전히 비활성화하려면:\
      `OVERLEAF_OIDC_ALLOWED_EMAIL_DOMAINS=`
* `OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN`
  * `true`로 설정하면 로그인 시 사용자의 `first_name` 및 `last_name` 필드를 업데이트하고, `/user/settings` 페이지의 사용자 정보 양식을 비활성화합니다.
* `OVERLEAF_OIDC_IS_ADMIN_FIELD` 및 `OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE`
  * 두 환경 변수가 모두 설정된 경우, OP가 반환한 프로필에 `OVERLEAF_OIDC_IS_ADMIN_FIELD`로 지정한 속성이 있고 그 값이 `OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE`와 일치하거나 `OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE`를 포함하는 배열(예: `groups` 클레임)이면 로그인 과정에서 `user.isAdmin = true`로 업데이트되고, 그렇지 않으면 `user.isAdmin`이 `false`로 설정됩니다. `OVERLEAF_OIDC_IS_ADMIN_FIELD`가 `email`이면 일치 여부 확인에 `emails[0].value` 속성 값이 사용됩니다.

OpenID Provider의 리디렉션 URL은 `https://my-overleaf-instance.com/oidc/login/callback`입니다.

<Accordion title="variables.env 파일 예시">
  ```dotenv title="variables.env" wrap theme={null}
  OVERLEAF_APP_NAME="Our Overleaf Instance"

  ENABLED_LINKED_FILE_TYPES=project_file,project_output_file,url

  # Enables Thumbnail generation using ImageMagick
  ENABLE_CONVERSIONS=true

  # Disables email confirmation requirement
  EMAIL_CONFIRMATION_DISABLED=true

  ## Nginx
  # NGINX_WORKER_PROCESSES=4
  # NGINX_WORKER_CONNECTIONS=768

  ## Set for TLS via nginx-proxy
  # OVERLEAF_BEHIND_PROXY=true
  # OVERLEAF_SECURE_COOKIE=true

  OVERLEAF_SITE_URL=http://my-overleaf-instance.com
  OVERLEAF_NAV_TITLE=Our Overleaf Instance
  # OVERLEAF_HEADER_IMAGE_URL=http://somewhere.com/mylogo.png
  OVERLEAF_ADMIN_EMAIL=support@example.com

  OVERLEAF_LEFT_FOOTER=[{"text": "Contact your support team", "url": "mailto:support@example.com"}]
  OVERLEAF_RIGHT_FOOTER=[{"text":"Hello, I am on the Right", "url":"https://github.com/yu-i-i/overleaf-cep"}]

  OVERLEAF_EMAIL_FROM_ADDRESS=team@example.com
  OVERLEAF_EMAIL_SMTP_HOST=smtp.example.com
  OVERLEAF_EMAIL_SMTP_PORT=587
  OVERLEAF_EMAIL_SMTP_SECURE=false
  # OVERLEAF_EMAIL_SMTP_USER=
  # OVERLEAF_EMAIL_SMTP_PASS=
  # OVERLEAF_EMAIL_SMTP_NAME=
  OVERLEAF_EMAIL_SMTP_LOGGER=false
  OVERLEAF_EMAIL_SMTP_TLS_REJECT_UNAUTH=true
  OVERLEAF_EMAIL_SMTP_IGNORE_TLS=false
  OVERLEAF_CUSTOM_EMAIL_FOOTER=This system is run by department x

  OVERLEAF_PROXY_LEARN=true
  NAV_HIDE_POWERED_BY=true

  #################
  ## OIDC for CE ##
  #################

  EXTERNAL_AUTH=oidc

  OVERLEAF_OIDC_PROVIDER_ID=oidc
  OVERLEAF_OIDC_ISSUER=https://keycloak.provider.com/realms/example
  OVERLEAF_OIDC_AUTHORIZATION_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/auth
  OVERLEAF_OIDC_TOKEN_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/token
  OVERLEAF_OIDC_USER_INFO_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/userinfo
  OVERLEAF_OIDC_LOGOUT_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/logout
  OVERLEAF_OIDC_CLIENT_ID=Overleaf-OIDC
  OVERLEAF_OIDC_CLIENT_SECRET=DoNotUseThisATGgaAcTgCcATgGATTACAagGtTCaGcGTAG
  OVERLEAF_OIDC_IDENTITY_SERVICE_NAME='Log in with Keycloak OIDC Provider'
  OVERLEAF_OIDC_PROVIDER_NAME=OIDC Keycloak Provider
  OVERLEAF_OIDC_PROVIDER_INFO_LINK=https://openid.net
  OVERLEAF_OIDC_IS_ADMIN_FIELD=email
  OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE=overleaf.admin@example.com
  OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN=false
  ```
</Accordion>

## 단계별 안내: goauthentik

여기서는 [goauthentik](https://goauthentik.io/)에서 테스트를 거친 설정 과정을 단계별로 안내합니다. `https://overleaf.example.com`은 사용 중인 `OVERLEAF_SITE_URL`로, `https://authentik.example.com`은 사용 중인 Authentik의 주소로 바꾸세요.

<Steps>
  <Step title="공급자 만들기">
    Authentik에서 **Applications > Providers**를 열고 **New Provider**를 클릭한 다음 **OAuth2/OpenID Provider**를 선택하고 **Next**를 클릭합니다.

    * **Client Type**: `Confidential`.
    * **Redirect URIs**(**Protocol settings** 아래): 일치 모드를 `Strict`로 하여 `https://overleaf.example.com/oidc/login/callback`을 추가합니다.
    * 지금 **Client ID**와 **Client Secret**을 `OVERLEAF_OIDC_CLIENT_ID`와 `OVERLEAF_OIDC_CLIENT_SECRET`에 복사합니다.

    <Frame caption="Authentik: 새 공급자의 Client ID와 Client Secret">
      <img src="https://mintcdn.com/ayakaleaf-pro/TjqwH4XzxYAkHStq/images/on-premises/oidc-authentik-create.png?fit=max&auto=format&n=TjqwH4XzxYAkHStq&q=85&s=f127a92eaf3063714e9af515fe97c263" alt="" width="1120" height="808" data-path="images/on-premises/oidc-authentik-create.png" />
    </Frame>

    <Warning>
      Authentik은 공급자를 만드는 동안에만 client secret을 표시합니다. 나중에 편집 양식에서는 **Modify**만 제공되며, 이를 사용하면 secret이 새 값으로 바뀝니다.
    </Warning>
  </Step>

  <Step title="애플리케이션 만들기">
    **Applications > Applications**를 열고 새 애플리케이션을 만든 다음 이름과 슬러그(예: `overleaf`)를 지정하고 공급자를 선택합니다. 슬러그는 issuer의 일부가 됩니다: `https://authentik.example.com/application/o/overleaf/`.
  </Step>

  <Step title="URL 복사하기">
    위의 [디스커버리 문서로 값 찾기](#디스커버리-문서로-값-찾기)를 따라 다섯 개의 URL을 입력합니다.
  </Step>

  <Step title="관리자 매핑하기(선택 사항)">
    Authentik은 사용자의 그룹을 배열인 `groups` 클레임으로 보냅니다. Authentik 그룹 `Admins`의 구성원을 Overleaf 관리자로 만들려면 다음과 같이 설정합니다:

    ```dotenv theme={null}
    OVERLEAF_OIDC_IS_ADMIN_FIELD=groups
    OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE=Admins
    ```

    <Warning>
      관리자 플래그는 OIDC 로그인 때마다 업데이트됩니다. 필드나 값이 잘못되면 launchpad에서 만든 관리자를 포함해 OIDC로 로그인하는 모든 관리자가 관리자 권한을 잃게 됩니다. 먼저 두 번째 관리자 계정으로 매핑을 테스트하세요.
    </Warning>
  </Step>
</Steps>

<Accordion title="goauthentik용으로 테스트된 variables.env">
  ```dotenv title="variables.env" wrap theme={null}
  EXTERNAL_AUTH=oidc
  OVERLEAF_OIDC_PROVIDER_ID=authentik
  OVERLEAF_OIDC_IDENTITY_SERVICE_NAME=Log in with Authentik
  OVERLEAF_OIDC_ISSUER=https://authentik.example.com/application/o/overleaf/
  OVERLEAF_OIDC_AUTHORIZATION_URL=https://authentik.example.com/application/o/authorize/
  OVERLEAF_OIDC_TOKEN_URL=https://authentik.example.com/application/o/token/
  OVERLEAF_OIDC_USER_INFO_URL=https://authentik.example.com/application/o/userinfo/
  OVERLEAF_OIDC_LOGOUT_URL=https://authentik.example.com/application/o/overleaf/end-session/
  OVERLEAF_OIDC_CLIENT_ID=<Client ID>
  OVERLEAF_OIDC_CLIENT_SECRET=<Client Secret>
  OVERLEAF_OIDC_USER_ID_FIELD=username
  OVERLEAF_OIDC_IS_ADMIN_FIELD=groups
  OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE=Admins
  OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN=true
  ```
</Accordion>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.