/** * SAML 2.0 SSO AuthnRequest 생성 API * * 역할: * - 프론트엔드에서 SAML 로그인 URL을 요청할 때 사용 * - SAML AuthnRequest를 생성하고 IdP 로그인 URL 반환 * - Mock 모드 지원으로 개발/테스트 환경에서 시뮬레이션 가능 * * 플로우: * 1. 사용자가 "Knox SSO로 로그인" 버튼 클릭 * 2. 프론트엔드에서 이 API 호출 * 3. SAML AuthnRequest URL 생성 후 반환 * 4. 프론트엔드에서 해당 URL로 리다이렉트 * 5. IdP에서 인증 후 /api/saml/callback으로 SAML Response 전송 */ import { NextResponse } from 'next/server' import { createAuthnRequest } from '../../[...nextauth]/saml/utils' import { debugLog, debugError, debugSuccess, debugProcess } from '@/lib/debug-utils' // SAML 환경변수 상태 체크 function validateSAMLEnvironment() { const samlEnvironment = { NODE_ENV: process.env.NODE_ENV, SAML_MOCKING_IDP: process.env.SAML_MOCKING_IDP, NEXTAUTH_URL: process.env.NEXTAUTH_URL, SAML_SP_PRIVATE_KEY: process.env.SAML_SP_PRIVATE_KEY ? '✅ Set' : '❌ Missing', SAML_SP_CERT: process.env.SAML_SP_CERT ? '✅ Set' : '❌ Missing', } debugLog('📊 SAML Environment check:', JSON.stringify(samlEnvironment, null, 2)) // 필수 환경변수 검증 const missingVars = [] if (!process.env.NEXTAUTH_URL) missingVars.push('NEXTAUTH_URL') // 키 없어도 구현 가능해서 주석 처리함. // if (!process.env.SAML_SP_PRIVATE_KEY) missingVars.push('SAML_SP_PRIVATE_KEY') // if (!process.env.SAML_SP_CERT) missingVars.push('SAML_SP_CERT') if (missingVars.length > 0) { throw new Error(`Missing required SAML environment variables: ${missingVars.join(', ')}`) } return samlEnvironment } /** * SAML AuthnRequest URL 생성 엔드포인트 * * @returns {JSON} { loginUrl: string, success: boolean, isThisMocking?: boolean } */ 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(relayState || undefined) const endTime = Date.now() debugSuccess('SAML AuthnRequest created successfully:', { url: loginUrl.substring(0, 100) + '...', urlLength: loginUrl.length, processingTime: `${endTime - startTime}ms`, mockMode: environment.SAML_MOCKING_IDP === 'true', timestamp: new Date().toISOString() }) return NextResponse.json({ loginUrl, success: true, isThisMocking: environment.SAML_MOCKING_IDP === 'true' }) } catch (error) { debugError('Failed to create SAML AuthnRequest:', { error: error instanceof Error ? error.message : 'Unknown error', stack: error instanceof Error ? error.stack : undefined, timestamp: new Date().toISOString() }) return NextResponse.json({ error: 'Failed to create SAML AuthnRequest', details: error instanceof Error ? error.message : 'Unknown error', success: false }, { status: 500 }) } }