11 KiB
RP 자동 로그인 지원 가이드
이 문서는 Baron SSO의 userfront 연동 앱에서 RP를 클릭했을 때 별도 로그인 버튼 클릭 없이 OIDC 인증을 시작하려는 RP 등록자와 RP 개발자를 위한 기준입니다.
목적
자동 로그인은 userfront가 RP의 자체 로그인 시작 URL로 사용자를 보내고, RP가 그 진입점에서 OIDC Authorization Code + PKCE 흐름을 직접 시작하는 방식입니다.
Baron backend가 /oauth2/auth?... URL을 대신 만들어 넘기지 않는 이유는 RP가 직접 state, nonce, PKCE verifier/challenge, callback 검증 상태를 관리해야 하기 때문입니다. SPA나 모바일 웹앱은 이 상태가 RP 저장소에 있어야 callback을 안전하게 처리할 수 있습니다.
등록 메타데이터
RP는 Hydra client metadata에 다음 값을 저장합니다.
| 키 | 타입 | 설명 |
|---|---|---|
auto_login_supported |
boolean | 자동 로그인 지원 여부입니다. true일 때만 userfront가 자동 로그인 URL을 진입 URL로 사용합니다. |
auto_login_url |
string | RP가 OIDC 로그인을 시작하는 URL입니다. http 또는 https URL이어야 합니다. |
devfront의 RP 일반 설정에서 다음 항목을 입력합니다.
자동 로그인 지원을 켭니다.자동 로그인 시작 URL에 RP 로그인 시작 URL을 입력합니다.- Redirect URI 목록에는 RP callback URL을 등록합니다.
- 저장 후 userfront 연동 앱 카드에서 “연동앱 클릭 시 별도 로그인 없이 로그인할 수 있습니다.” 안내가 보이는지 확인합니다.
설정 규칙
자동 로그인 시작 URL은 반드시http://또는https://로 시작하는 완전한 절대 URL이어야 합니다.- Baron은 이 값을 브라우저 진입 URL로만 사용합니다. Baron이
/oauth2/auth?...를 대신 생성하지 않습니다. - 따라서 이 URL은 RP 내부의 "로그인 시작 엔드포인트"여야 합니다.
- 루트(
/)가 아니라 실제로 OIDC 시작을 트리거하는 경로를 넣어야 합니다.
허용 예시:
http://localhost:3333/login
http://localhost:3333/login?auto=1
https://rp.example.com/login?auto=1&returnTo=%2Fdashboard
비권장 예시:
http:localhost:3333/login
localhost:3333/login
/login?auto=1
예시:
auto_login_supported: true
auto_login_url: https://org.example.com/login?auto=1
redirect_uri: https://org.example.com/auth/callback
로컬 RP 예시
로컬에서 client_id=f5cdd938-a3ae-4e47-ab83-4c13e59949f5 RP가 http://localhost:3333에서 실행 중이라면, 메인 페이지가 /login 링크를 노출하고 /login 호출 시 Baron OIDC authorize endpoint로 302를 반환하는지 먼저 확인합니다.
이 경우 devfront 설정 탭의 권장 입력값은 다음과 같습니다.
자동 로그인 지원: ON
자동 로그인 시작 URL: http://localhost:3333/login
Redirect URI: http://localhost:3333/callback
주의:
http://localhost:3333/는 홈 URL일 뿐, 로그인 시작 URL이 아닐 수 있습니다.http://localhost:3333/login?auto=1도 저장은 가능하지만, RP가/login만으로 이미 즉시 OIDC를 시작한다면?auto=1은 필수가 아닙니다.- 현재 확인된 로컬 데모 RP는
/login만 호출해도 Baron OIDC로 바로 리다이렉트합니다.
RP 구현 요구사항
RP는 auto_login_url에서 다음 동작을 구현해야 합니다.
auto=1쿼리를 읽습니다.- 이미 RP 세션이 있으면 기본 화면 또는
returnTo경로로 이동합니다. - RP 세션이 없고
auto=1이면 로그인 버튼을 기다리지 않고 OIDC authorization 요청을 시작합니다. - OIDC 요청 전에
state,nonce, PKCEcode_verifier,code_challenge를 생성합니다. state,nonce,code_verifier,returnTo는 RP origin의 안전한 저장소에 보관합니다.- callback에서
state를 검증하고, token 교환 시code_verifier를 사용합니다. - 인증 완료 후 저장된
returnTo가 있으면 해당 경로로 이동합니다.
권장 URL 형식:
https://rp.example.com/login?auto=1
https://rp.example.com/login?auto=1&returnTo=%2Fdashboard
Baron 내장 RP 기준
Baron 계열 RP는 다음 fallback을 사용합니다. env URL이 설정되어 있을 때만 자동 로그인 지원으로 간주합니다.
| Client ID | Env | 자동 로그인 URL |
|---|---|---|
adminfront |
ADMINFRONT_URL |
${ADMINFRONT_URL}/login?auto=1 |
devfront |
DEVFRONT_URL |
${DEVFRONT_URL}/login?auto=1&returnTo=%2Fclients |
orgfront |
ORGFRONT_URL |
${ORGFRONT_URL}/login |
orgfront는 /login 진입부터 OIDC authorize 요청을 즉시 시작하며, 기본 callback 이후 이동 경로는 /chart입니다. 수동 로그인 화면 검증이 필요하면 /login?auto=0으로 자동 시작을 끌 수 있습니다.
userfront 동작
userfront는 backend의 linked RP 응답을 기준으로 진입 URL을 선택합니다.
status가 active가 아니면 진입 URL을 만들지 않습니다.auto_login_supported=true이면auto_login_url을 우선 사용합니다.auto_login_url이 없으면init_url을 사용합니다.- 자동 로그인 미지원이면
init_url이 있어도 기존url로 이동합니다.
이 기준 때문에 auto_login_supported=false인 RP는 accidental auto-login을 수행하지 않습니다.
시퀀스 다이어그램
1. 설정 저장 흐름
sequenceDiagram
participant Admin as 운영자
participant DevFront as DevFront 설정 화면
participant Backend as Baron Backend
participant Hydra as Hydra Client Metadata
Admin->>DevFront: RP 설정 화면 진입
Admin->>DevFront: 자동 로그인 지원 ON
Admin->>DevFront: 자동 로그인 시작 URL 입력
Admin->>DevFront: 저장
DevFront->>Backend: RP 일반 설정 수정 요청
Backend->>Backend: auto_login_url 검증
Note over Backend: scheme=http/https<br/>host 존재 필요
Backend->>Hydra: client metadata update
Hydra-->>Backend: 저장 완료
Backend-->>DevFront: 저장 성공
DevFront-->>Admin: 저장 완료 표시
2. userfront에서 자동 로그인 시작
sequenceDiagram
participant User as 사용자
participant UserFront as UserFront
participant Backend as Baron Backend
participant RP as RP 로그인 시작 URL
participant Baron as Baron OIDC/Hydra
User->>UserFront: 연동 앱 카드 클릭
UserFront->>Backend: linked RP 목록/상태 조회
Backend-->>UserFront: auto_login_supported, auto_login_url 반환
alt auto_login_supported = true
UserFront->>RP: GET auto_login_url
Note over RP: RP가 state, nonce,<br/>PKCE verifier/challenge 생성
RP-->>UserFront: 302 Baron authorize endpoint
UserFront->>Baron: GET /oidc/oauth2/auth
else auto_login_supported = false
UserFront->>UserFront: 일반 url 또는 init_url 사용
end
3. 로컬 3333 RP 예시 흐름
sequenceDiagram
participant User as 사용자 브라우저
participant UserFront as UserFront
participant RP as localhost:3333 RP
participant Baron as Baron OIDC
User->>UserFront: RP 카드 클릭
UserFront->>RP: GET http://localhost:3333/login
RP-->>User: 302 /oidc/oauth2/auth?...&client_id=f5cdd938-a3ae-4e47-ab83-4c13e59949f5
User->>Baron: GET authorize endpoint
Baron-->>User: 로그인/동의 또는 기존 세션 진행
Baron-->>RP: callback redirect
RP-->>User: RP 세션 생성 후 앱 화면 진입
로직 요약
- DevFront는
auto_login_supported,auto_login_url을 RP metadata로 저장합니다. - Backend는
auto_login_supported=true일 때만auto_login_url을 linked RP 응답에 포함시켜 userfront가 사용할 수 있게 합니다. - UserFront는 카드 클릭 시 이 URL로 직접 이동합니다.
- RP는 그 진입점에서 OIDC 요청을 "직접" 생성해야 합니다.
- Callback 검증에 필요한
state,nonce, PKCE 상태는 RP 저장소가 소유해야 합니다. - 그래서 Baron이 RP 대신 authorize URL을 만들어 주는 구조로 바꾸면 안 됩니다.
검증 체크리스트
RP 등록자는 다음을 확인해야 합니다.
- devfront에서
자동 로그인 지원이 켜져 있습니다. 자동 로그인 시작 URL이 실제 RP 로그인 진입점입니다.auto_login_url에 직접 접속하면 로그인 버튼 클릭 없이 Baron OIDC authorize 요청이 시작됩니다.- callback URL이 Redirect URI에 등록되어 있습니다.
- callback 이후 RP가
state,nonce, PKCE 검증을 통과합니다. - userfront 연동 앱 카드에 자동 로그인 안내 문구가 표시됩니다.
- userfront에서 RP 카드를 클릭하면 RP 로그인 화면에 머물지 않고 OIDC 흐름으로 진입합니다.
orgfront 기준 검증 명령:
npm run test -- tests/orgfront-auto-login.spec.ts --project=chromium
실패 시 확인할 항목
| 증상 | 확인 항목 |
|---|---|
| userfront에서 일반 URL로만 이동함 | RP metadata의 auto_login_supported가 true인지 확인합니다. |
| userfront 카드에 안내 문구가 없음 | backend /api/v1/user/rp/linked 응답에 auto_login_supported=true가 내려오는지 확인합니다. |
| RP 로그인 화면에 머무름 | RP가 auto=1 쿼리를 읽어 자동으로 signinRedirect 또는 동일한 OIDC 시작 함수를 호출하는지 확인합니다. |
| callback에서 state 오류 발생 | userfront나 backend가 만든 /oauth2/auth?... URL을 직접 쓰지 말고 RP 자체 로그인 시작 URL에서 OIDC 요청을 생성해야 합니다. |
| 등록 저장이 실패함 | auto_login_supported=true일 때 auto_login_url이 비어 있거나 http/https URL이 아닌지 확인합니다. |
http:localhost:3333/login 같은 값이 브라우저에서는 열림 |
브라우저 보정에 기대지 말고 http://localhost:3333/login처럼 완전한 절대 URL로 저장합니다. |
구현 예시
React RP 예시입니다. 실제 프로젝트에서는 사용하는 OIDC client 라이브러리의 API에 맞춰 적용합니다.
const returnTo = searchParams.get("returnTo") || "/";
const shouldAutoLogin = searchParams.get("auto") === "1";
useEffect(() => {
if (auth.isAuthenticated) {
navigate(returnTo, { replace: true });
return;
}
if (!shouldAutoLogin || auth.isLoading || auth.activeNavigator) {
return;
}
void auth.signinRedirect({
state: { returnTo },
});
}, [auth, navigate, returnTo, shouldAutoLogin]);
중요한 점은 signinRedirect가 RP에서 실행되어야 한다는 것입니다. 그래야 RP가 callback 검증에 필요한 상태를 보유할 수 있습니다.