diff options
| author | joonhoekim <26rote@gmail.com> | 2025-06-23 12:56:54 +0000 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-06-23 12:56:54 +0000 |
| commit | 1e46c2f3523f0f73a7ed378e9281dec24b23f8f8 (patch) | |
| tree | 62438a757a4aadc8d9aa6924bd3756a919fe2303 /app/api/auth | |
| parent | ebe273ef4564d55f9bf193adc51a9e58211e72e9 (diff) | |
(김준회) SAML 2.0 relay-state 처리 및 redirect 상태코드 문제 디버깅
Diffstat (limited to 'app/api/auth')
| -rw-r--r-- | app/api/auth/[...nextauth]/saml/utils.ts | 19 | ||||
| -rw-r--r-- | app/api/auth/saml/authn-request/route.ts | 10 | ||||
| -rw-r--r-- | app/api/auth/saml/mock-idp/route.ts | 8 |
3 files changed, 26 insertions, 11 deletions
diff --git a/app/api/auth/[...nextauth]/saml/utils.ts b/app/api/auth/[...nextauth]/saml/utils.ts index 73c00bf6..a5bcfe7a 100644 --- a/app/api/auth/[...nextauth]/saml/utils.ts +++ b/app/api/auth/[...nextauth]/saml/utils.ts @@ -97,15 +97,15 @@ export function createSAMLConfig() { } // SAML AuthnRequest 생성 (서버 액션) -export async function createAuthnRequest(): Promise<string> { +export async function createAuthnRequest(relayState?: string): Promise<string> { "use server"; - console.log("SSO STEP 2: Create AuthnRequest"); + console.log("SSO STEP 2: Create AuthnRequest", { relayState }); // Mock IdP 모드 체크 if (process.env.SAML_MOCKING_IDP === 'true') { debugMock("Mock IdP mode enabled - simulating SAML response"); - return createMockSAMLFlow(); + return createMockSAMLFlow(relayState); } try { @@ -117,7 +117,7 @@ export async function createAuthnRequest(): Promise<string> { const startTime = Date.now(); const authorizeUrl = await saml.getAuthorizeUrlAsync( - "", // RelayState + relayState || "", // RelayState - 원래 가려던 페이지 undefined, // host { additionalParams: {}, @@ -406,12 +406,17 @@ export function mapSAMLProfileToUser(profile: SAMLProfile): SAMLUser { } // Mock SAML 플로우 생성 (테스트용) -function createMockSAMLFlow(): string { - debugMock("Creating mock SAML flow..."); +function createMockSAMLFlow(relayState?: string): string { + debugMock("Creating mock SAML flow...", { relayState }); // Mock 모드에서는 Mock IdP 엔드포인트로 리다이렉션 const baseUrl = process.env.NEXTAUTH_URL || 'http://localhost:3000'; - const mockIdpUrl = `${baseUrl}/api/auth/saml/mock-idp`; + let mockIdpUrl = `${baseUrl}/api/auth/saml/mock-idp`; + + // RelayState가 있으면 URL 파라미터로 전달 + if (relayState) { + mockIdpUrl += `?RelayState=${encodeURIComponent(relayState)}`; + } debugMock("Mock SAML Flow - redirecting to Mock IdP:", mockIdpUrl); diff --git a/app/api/auth/saml/authn-request/route.ts b/app/api/auth/saml/authn-request/route.ts index f079aea0..6544a765 100644 --- a/app/api/auth/saml/authn-request/route.ts +++ b/app/api/auth/saml/authn-request/route.ts @@ -50,17 +50,23 @@ function validateSAMLEnvironment() { * * @returns {JSON} { loginUrl: string, success: boolean, isThisMocking?: boolean } */ -export async function GET() { +export async function GET(request: Request) { debugProcess('🚀 SAML AuthnRequest API started') try { + // URL에서 RelayState 매개변수 추출 + const url = new URL(request.url) + const relayState = url.searchParams.get('relayState') + + debugLog('RelayState parameter:', relayState) + // 환경변수 검증 const environment = validateSAMLEnvironment() debugProcess('SSO STEP 1: Create AuthnRequest') const startTime = Date.now() - const loginUrl = await createAuthnRequest() + const loginUrl = await createAuthnRequest(relayState || undefined) const endTime = Date.now() debugSuccess('SAML AuthnRequest created successfully:', { diff --git a/app/api/auth/saml/mock-idp/route.ts b/app/api/auth/saml/mock-idp/route.ts index 45c670b0..eccb6035 100644 --- a/app/api/auth/saml/mock-idp/route.ts +++ b/app/api/auth/saml/mock-idp/route.ts @@ -3,7 +3,11 @@ import { NextRequest, NextResponse } from 'next/server' // Mock IdP 엔드포인트 - SAML Response HTML 폼 반환 export async function GET(request: NextRequest) { try { - console.log('🎭 Mock IdP endpoint accessed'); + // RelayState 파라미터 추출 + const url = new URL(request.url) + const relayState = url.searchParams.get('RelayState') || 'mock_test' + + console.log('🎭 Mock IdP endpoint accessed', { relayState }); // Mock SAML Response 데이터 (실제 형태와 일치하도록 문자열 형태) const mockSAMLResponseData = { @@ -83,7 +87,7 @@ export async function GET(request: NextRequest) { </div> <form id="mockForm" method="POST" action="${callbackUrl}"> <input type="hidden" name="SAMLResponse" value="${encodedSAMLResponse}" /> - <input type="hidden" name="RelayState" value="mock_test" /> + <input type="hidden" name="RelayState" value="${relayState}" /> <button type="submit" class="button">Continue with Mock Login</button> </form> <div class="details"> |
