1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
/**
* 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 })
}
}
|