forked from baron/baron-sso
94 lines
3.6 KiB
Plaintext
94 lines
3.6 KiB
Plaintext
# 멀티 IDP 아키텍처 및 마이그레이션 전략
|
|
|
|
본 문서는 Primary IDP 변경(예: Descope → Hydra/Authentik) 시 시스템의 유연성을 보장하기 위한 아키텍처 설계 전략을 기술합니다.
|
|
|
|
## 핵심 전략
|
|
|
|
1. **Broker 패턴 고도화**: 백엔드가 모든 인증 요청을 중계하며, 클라이언트는 특정 IDP에 종속되지 않습니다.
|
|
2. **추상화 계층 (Abstraction Layer)**: 비즈니스 로직은 `IdentityProvider` 인터페이스에만 의존하며, 구체적인 구현체(Descope, Hydra 등)는 알 필요가 없습니다.
|
|
3. **식별자 분리 (Identifier Decoupling)**: 외부 IDP의 `sub` 값과 내부 시스템의 `user_id`를 분리하여 매핑합니다.
|
|
|
|
## 상세 설계
|
|
|
|
### 1. IdentityProvider 인터페이스 확장
|
|
단순 메타데이터 조회를 넘어, 인증의 핵심 라이프사이클을 모두 포함하도록 인터페이스를 확장해야 합니다.
|
|
|
|
```go
|
|
type IdentityProvider interface {
|
|
// 메타데이터 및 스키마 검증
|
|
Name() string
|
|
GetMetadata() (*IDPMetadata, error)
|
|
|
|
// 핵심 인증/인가 기능
|
|
SignUp(ctx context.Context, user *BrokerUser, password string) (*AuthResult, error)
|
|
Login(ctx context.Context, loginID, password string) (*AuthResult, error)
|
|
VerifyToken(ctx context.Context, token string) (*TokenInfo, error)
|
|
|
|
// 사용자 관리
|
|
GetUser(ctx context.Context, id string) (*BrokerUser, error)
|
|
UpdateUser(ctx context.Context, user *BrokerUser) error
|
|
DeleteUser(ctx context.Context, id string) error
|
|
}
|
|
```
|
|
|
|
### 2. Provider Factory 패턴
|
|
설정(`config.yaml` 또는 환경변수)에 따라 사용할 IDP 구현체를 런타임에 결정합니다.
|
|
|
|
```go
|
|
func NewIdentityProvider(config Config) (domain.IdentityProvider, error) {
|
|
switch config.IDPType {
|
|
case "descope":
|
|
return service.NewDescopeProvider(config.Descope)
|
|
case "hydra":
|
|
return service.NewHydraProvider(config.Hydra)
|
|
case "authentik":
|
|
return service.NewAuthentikProvider(config.Authentik)
|
|
default:
|
|
return nil, fmt.Errorf("unsupported IDP type: %s", config.IDPType)
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. 식별자 매핑 (ID Mapping)
|
|
IDP 변경 시 가장 큰 문제는 사용자 고유 ID(`sub`)가 바뀌는 것입니다. 이를 해결하기 위해 Baron SSO 내부 전용 UUID를 사용하고 매핑 테이블을 둡니다.
|
|
|
|
* **User Table (Baron Internal)**: `id` (UUID), `email`, ...
|
|
* **IDP Link Table**: `baron_user_id`, `idp_provider` (e.g., descope), `idp_subject_id` (e.g., U12345)
|
|
|
|
## 구현 예시 (Descope)
|
|
|
|
현재 단계에서 즉시 사용 가능한 `DescopeProvider`의 구현 예시입니다.
|
|
|
|
```go
|
|
// DescopeProvider는 IdentityProvider 인터페이스를 구현합니다.
|
|
type DescopeProvider struct {
|
|
Client *client.DescopeClient
|
|
}
|
|
|
|
func (d *DescopeProvider) SignUp(ctx context.Context, user *domain.BrokerUser, password string) (*domain.AuthResult, error) {
|
|
// BrokerUser를 Descope User 객체로 변환
|
|
descopeUser := &descope.User{
|
|
Name: user.Name,
|
|
Email: user.Email,
|
|
Phone: user.PhoneNumber,
|
|
CustomAttributes: user.Attributes,
|
|
}
|
|
|
|
// SDK 호출
|
|
authInfo, err := d.Client.Auth.Password().SignUp(ctx, user.Email, descopeUser, password)
|
|
if err != nil {
|
|
return nil, err\n }
|
|
|
|
// 결과 반환
|
|
return &domain.AuthResult{
|
|
UserID: authInfo.User.UserID,
|
|
Token: authInfo.SessionToken.JWT,
|
|
}, nil
|
|
}
|
|
```
|
|
|
|
## 향후 지원 후보 (Candidates)
|
|
|
|
* **Ory Hydra**: 자체적인 OAuth2/OIDC 서버 구축이 필요할 때 적합. 높은 커스터마이징 가능.
|
|
* **Authentik**: 오픈소스 IDP로, 설치형(Self-hosted) 환경에서 강력한 기능을 제공.
|