From ebe273ef4564d55f9bf193adc51a9e58211e72e9 Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Mon, 23 Jun 2025 06:44:34 +0000 Subject: (김준회 SAML 2.0 SSO 리팩터링, 디버깅 유틸리티 추가, MOCK 처리 추가 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/saml/callback/route.ts | 124 +++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 41 deletions(-) (limited to 'app/api/saml/callback') diff --git a/app/api/saml/callback/route.ts b/app/api/saml/callback/route.ts index d13edc4a..cf9ea772 100644 --- a/app/api/saml/callback/route.ts +++ b/app/api/saml/callback/route.ts @@ -1,5 +1,11 @@ import { NextRequest, NextResponse } from 'next/server' import { validateSAMLResponse, mapSAMLProfileToUser } from '../../auth/[...nextauth]/saml/utils' +import { + authenticateSAMLUser, + createNextAuthToken, + getSessionCookieName +} from '../../auth/[...nextauth]/saml/provider' +import { debugLog, debugError, debugSuccess, debugProcess } from '@/lib/debug-utils' // IdP가 인증처리 후 POST 요청을 콜백 URL로 날려준다. // 이 라우트가 그 요청을 받아준다. @@ -7,14 +13,25 @@ import { validateSAMLResponse, mapSAMLProfileToUser } from '../../auth/[...nexta export async function POST(request: NextRequest) { try { - console.log('🔐 SAML Callback received at /api/saml/callback') + const isMockMode = process.env.SAML_MOCKING_IDP === 'true'; + debugProcess(`SAML Callback received at /api/saml/callback ${isMockMode ? '(🎭 Mock Mode)' : ''}`) + debugLog('Request info:', { + url: request.url, + nextUrl: request.nextUrl?.toString(), + mockMode: isMockMode, + headers: { + host: request.headers.get('host'), + origin: request.headers.get('origin'), + referer: request.headers.get('referer') + } + }) // FormData에서 SAML Response 추출 const formData = await request.formData() const samlResponse = formData.get('SAMLResponse') as string const relayState = formData.get('RelayState') as string - console.log('📨 SAML Response received:', { + debugLog('SAML Response received:', { hasResponse: !!samlResponse, relayState: relayState || 'none', responseLength: samlResponse?.length || 0 @@ -23,104 +40,129 @@ export async function POST(request: NextRequest) { // 🔍 SAML Response 디코딩 및 분석 if (samlResponse) { try { - console.log('🔍 SAML Response 분석:') - console.log('1️⃣ 원본 SAMLResponse (일부):', samlResponse.substring(0, 100) + '...') + debugLog('🔍 SAML Response 분석:') + debugLog('원본 SAMLResponse (일부):', samlResponse.substring(0, 100) + '...') try { // Base64 디코딩 시도 const base64Decoded = Buffer.from(samlResponse, 'base64').toString('utf-8') - console.log('2️⃣ Base64 디코딩된 XML:') - console.log('───────────────────────────────────') - console.log(base64Decoded) - console.log('───────────────────────────────────') + debugLog('Base64 디코딩된 XML:') + debugLog('───────────────────────────────────') + debugLog(base64Decoded) + debugLog('───────────────────────────────────') // XML 구조 분석 const xmlLines = base64Decoded.split('\n').filter(line => line.trim()) - console.log('3️⃣ XML 구조 요약:') + debugLog('XML 구조 요약:') xmlLines.forEach((line, index) => { const trimmed = line.trim() if (trimmed.includes('