This page was machine-translated. Spotted a mistake?Help improve it.
Skip to content

OIDC / Single Sign-On

SnapOtter는 싱글 사인온을 위해 OpenID Connect(OIDC)를 지원합니다. 사용자는 로컬 사용자 이름/비밀번호 인증 대신(또는 이와 함께) Keycloak, Authentik, Google과 같은 외부 ID 공급자로 로그인할 수 있습니다.

Quick start

docker-compose.yml에 다음 환경 변수를 추가하세요:

yaml
services:
  SnapOtter:
    image: snapotter/snapotter:latest
    environment:
      EXTERNAL_URL: "https://photos.example.com"
      OIDC_ENABLED: "true"
      OIDC_ISSUER_URL: "https://auth.example.com/realms/myrealm"
      OIDC_CLIENT_ID: "snapotter"
      OIDC_CLIENT_SECRET: "your-secret-here"

공급자의 리디렉션 URI는 항상 다음과 같습니다:

${EXTERNAL_URL}/api/auth/oidc/callback

예를 들어 EXTERNAL_URLhttps://photos.example.com라면, 공급자의 리디렉션 URI를 https://photos.example.com/api/auth/oidc/callback으로 구성하세요.

Configuration reference

VariableDefaultDescription
OIDC_ENABLEDfalseOIDC 로그인을 활성화합니다. 로그인 페이지에 "Sign in with SSO" 버튼이 나타납니다.
OIDC_ISSUER_URL공급자의 issuer URL. OIDC Discovery(/.well-known/openid-configuration)를 지원해야 합니다.
OIDC_CLIENT_ID공급자에 등록된 OAuth 클라이언트 ID.
OIDC_CLIENT_SECRETOAuth 클라이언트 시크릿.
OIDC_SCOPESopenid profile email요청할 스코프의 공백으로 구분된 목록.
OIDC_AUTO_CREATE_USERStrue첫 OIDC 로그인 시 로컬 사용자 계정을 자동으로 생성합니다.
OIDC_DEFAULT_ROLEuser자동 생성된 OIDC 사용자에게 할당되는 역할. admin, editor, user 중 하나.
OIDC_AUTO_LINK_USERSfalse이메일 주소가 일치하면 OIDC ID를 기존 로컬 사용자에 연결합니다.
OIDC_PROVIDER_NAME로그인 버튼에 표시되는 이름(예: "Keycloak", "Google"). 비어 있으면 버튼에 "SSO"라고 표시됩니다.
OIDC_CLOCK_TOLERANCE30토큰 검증을 위한 시계 오차 허용 범위(초 단위).
OIDC_USERNAME_CLAIMpreferred_username새 계정의 사용자 이름으로 사용되는 ID 토큰 클레임.
EXTERNAL_URLSnapOtter에 접근할 수 있는 공개 URL. OIDC가 올바른 리디렉션 URI를 구성하려면 필요합니다.
COOKIE_SECRETauto-generated세션 쿠키 서명을 위한 시크릿. 여러 레플리카를 실행할 때 명시적으로 설정하세요.

Provider guides

Keycloak

  1. 새 realm을 생성합니다(또는 기존 realm 사용).
  2. Clients로 이동하여 새 클라이언트를 생성합니다:
    • Client ID: snapotter
    • Client authentication: On (confidential)
    • Authentication flow: Standard flow (Authorization Code)
  3. 클라이언트의 Settings 탭에서 Valid redirect URIs를 콜백 URL로 설정합니다(예: https://photos.example.com/api/auth/oidc/callback).
  4. Credentials 탭에서 Client secret을 복사합니다.
  5. OIDC_ISSUER_URLhttps://keycloak.example.com/realms/your-realm로 설정합니다.

Authentik

  1. 관리자 인터페이스에서 Applications > Providers로 이동하여 새 OAuth2/OpenID Provider를 생성합니다.
    • Client type: Confidential
    • Redirect URIs: 콜백 URL
    • Signing key: 기존 키를 선택하거나 새로 생성
  2. Application을 생성하고 공급자에 연결합니다.
  3. 공급자 설정에서 Client IDClient Secret을 복사합니다.
  4. OIDC_ISSUER_URLhttps://authentik.example.com/application/o/snapotter/으로 설정합니다(끝의 슬래시가 중요합니다).

Google

  1. Google Cloud Console로 이동합니다.
  2. 프로젝트를 생성합니다(또는 기존 프로젝트 선택).
  3. APIs & Services > OAuth consent screen으로 이동하여 구성합니다.
  4. APIs & Services > Credentials로 이동하여 OAuth 2.0 Client ID를 생성합니다:
    • Application type: Web application
    • Authorized redirect URIs: 콜백 URL
  5. Client IDClient secret을 복사합니다.
  6. OIDC_ISSUER_URLhttps://accounts.google.com로 설정합니다.
  7. OIDC_USERNAME_CLAIMemail으로 설정합니다(Google은 preferred_username을 제공하지 않습니다).

User provisioning

Auto-create

OIDC_AUTO_CREATE_USERStrue일 때(기본값), 누군가 OIDC로 처음 로그인하면 로컬 사용자 계정이 생성됩니다. 사용자 이름은 OIDC_USERNAME_CLAIM로 지정된 클레임에서 가져오며, 역할은 OIDC_DEFAULT_ROLE로 설정됩니다.

사용자 이름 충돌이 발생하면 숫자 접미사가 추가됩니다(예: janejane_2이 됨).

OIDC_AUTO_LINK_USERStrue일 때, SnapOtter는 이메일 주소가 일치하면 OIDC ID를 기존 로컬 계정에 연결합니다. 사용자 계정을 미리 생성해 두고, 데이터를 잃지 않으면서 SSO를 사용하기 시작하도록 하려는 경우에 유용합니다.

WARNING

OIDC 공급자가 이메일 주소를 검증한다고 신뢰하는 경우에만 auto-link를 활성화하세요. 검증되지 않은 이메일은 누군가가 다른 사용자의 계정을 탈취하도록 허용할 수 있습니다.

Disabling local login

OIDC는 로컬 사용자 이름/비밀번호 로그인을 비활성화하지 않습니다. 두 방식 모두 계속 사용할 수 있습니다. OIDC 공급자에 접근할 수 없는 경우에도 관리자는 로컬 자격 증명으로 로그인할 수 있습니다.

Self-signed certificates

OIDC 공급자가 자체 서명 또는 사설 CA 인증서를 사용하는 경우, CA 번들을 컨테이너에 마운트하고 NODE_EXTRA_CA_CERTS이 이를 가리키도록 하세요:

yaml
services:
  SnapOtter:
    image: snapotter/snapotter:latest
    volumes:
      - ./my-ca.pem:/etc/ssl/certs/custom-ca.pem:ro
    environment:
      NODE_EXTRA_CA_CERTS: /etc/ssl/certs/custom-ca.pem
      OIDC_ENABLED: "true"
      OIDC_ISSUER_URL: "https://auth.internal.example.com/realms/myrealm"
      OIDC_CLIENT_ID: "snapotter"
      OIDC_CLIENT_SECRET: "your-secret-here"

DANGER

NODE_TLS_REJECT_UNAUTHORIZED=0을 설정하지 마세요. 이는 모든 TLS 검증을 비활성화하며 보안 위험입니다.

Troubleshooting

Redirect URI mismatch

가장 흔한 오류입니다. 공급자가 기대하는 것과 SnapOtter가 보내는 것 사이에서 다음 차이를 확인하세요:

  • httphttps - 스킴이 정확히 일치해야 합니다
  • 끝의 슬래시 - 일부 공급자는 이에 대해 엄격합니다
  • 포트 번호 - 비표준인 경우 포트를 포함하세요
  • 경로 - /api/auth/oidc/callback여야 합니다

EXTERNAL_URL를 다시 확인하세요. 사용자가 브라우저에 입력하는 URL과 일치해야 합니다.

UNABLE_TO_VERIFY_LEAF_SIGNATURE

OIDC 공급자가 Node.js가 신뢰하지 않는 인증서를 사용하고 있습니다. 위의 Self-signed certificates를 참고하세요.

Clock skew errors

서버 시계와 OIDC 공급자 시계가 동기화되지 않으면 토큰 검증이 실패할 수 있습니다. OIDC_CLOCK_TOLERANCE을 늘리세요(기본값은 30초). 더 나은 해결책은 두 머신 모두에서 NTP를 실행하는 것입니다.

"OIDC provider unreachable"

SnapOtter는 시작 시점과 로그인 중에 공급자의 discovery 문서를 가져옵니다. 다음을 확인하세요:

  • Docker 컨테이너 내부에서의 DNS 확인(docker exec snapotter nslookup auth.example.com)
  • 컨테이너와 공급자 사이의 방화벽 규칙
  • OIDC_ISSUER_URL 값 - 브라우저뿐만 아니라 서버에서도 접근할 수 있어야 합니다

Missing claims

로그인 후 사용자 이름이나 이메일이 비어 있다면, 공급자가 기대하는 클레임을 반환하지 않을 수 있습니다. 다음을 확인하세요:

  • OIDC_SCOPES에 구성된 스코프에 profileemail이 포함되어 있는지
  • ID 토큰에 OIDC_USERNAME_CLAIM로 지정된 클레임을 포함하도록 공급자가 구성되어 있는지
  • 일부 공급자는 클레임을 릴리스하기 위해 명시적인 매퍼/스코프 구성이 필요합니다