mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
fix: LDAP authentication string validation error
Add comprehensive input validation for LDAP authentication: - Validate bindDN, bindCredentials, userDN, and password parameters - Add configuration validation during service initialization - Enhanced error messages for missing/invalid LDAP settings - Prevent "stringToWrite must be a string" errors from ldapjs client - Added null/undefined checks for all LDAP credential parameters This fixes authentication errors when LDAP configuration values are missing, empty, or of incorrect type. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,48 @@ class LdapService {
|
||||
constructor() {
|
||||
this.config = config.ldap
|
||||
this.client = null
|
||||
|
||||
// 验证配置
|
||||
if (this.config.enabled) {
|
||||
this.validateConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
// 🔍 验证LDAP配置
|
||||
validateConfiguration() {
|
||||
const errors = []
|
||||
|
||||
if (!this.config.server) {
|
||||
errors.push('LDAP server configuration is missing')
|
||||
} else {
|
||||
if (!this.config.server.url || typeof this.config.server.url !== 'string') {
|
||||
errors.push('LDAP server URL is not configured or invalid')
|
||||
}
|
||||
|
||||
if (!this.config.server.bindDN || typeof this.config.server.bindDN !== 'string') {
|
||||
errors.push('LDAP bind DN is not configured or invalid')
|
||||
}
|
||||
|
||||
if (!this.config.server.bindCredentials || typeof this.config.server.bindCredentials !== 'string') {
|
||||
errors.push('LDAP bind credentials are not configured or invalid')
|
||||
}
|
||||
|
||||
if (!this.config.server.searchBase || typeof this.config.server.searchBase !== 'string') {
|
||||
errors.push('LDAP search base is not configured or invalid')
|
||||
}
|
||||
|
||||
if (!this.config.server.searchFilter || typeof this.config.server.searchFilter !== 'string') {
|
||||
errors.push('LDAP search filter is not configured or invalid')
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
logger.error('❌ LDAP configuration validation failed:', errors)
|
||||
// Don't throw error during initialization, just log warnings
|
||||
logger.warn('⚠️ LDAP authentication may not work properly due to configuration errors')
|
||||
} else {
|
||||
logger.info('✅ LDAP configuration validation passed')
|
||||
}
|
||||
}
|
||||
|
||||
// 🔗 创建LDAP客户端连接
|
||||
@@ -98,7 +140,25 @@ class LdapService {
|
||||
// 🔒 绑定LDAP连接(管理员认证)
|
||||
async bindClient(client) {
|
||||
return new Promise((resolve, reject) => {
|
||||
client.bind(this.config.server.bindDN, this.config.server.bindCredentials, (err) => {
|
||||
// 验证绑定凭据
|
||||
const bindDN = this.config.server.bindDN
|
||||
const bindCredentials = this.config.server.bindCredentials
|
||||
|
||||
if (!bindDN || typeof bindDN !== 'string') {
|
||||
const error = new Error('LDAP bind DN is not configured or invalid')
|
||||
logger.error('❌ LDAP configuration error:', error.message)
|
||||
reject(error)
|
||||
return
|
||||
}
|
||||
|
||||
if (!bindCredentials || typeof bindCredentials !== 'string') {
|
||||
const error = new Error('LDAP bind credentials are not configured or invalid')
|
||||
logger.error('❌ LDAP configuration error:', error.message)
|
||||
reject(error)
|
||||
return
|
||||
}
|
||||
|
||||
client.bind(bindDN, bindCredentials, (err) => {
|
||||
if (err) {
|
||||
logger.error('❌ LDAP bind failed:', err)
|
||||
reject(err)
|
||||
@@ -163,6 +223,20 @@ class LdapService {
|
||||
// 🔐 验证用户密码
|
||||
async authenticateUser(userDN, password) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 验证输入参数
|
||||
if (!userDN || typeof userDN !== 'string') {
|
||||
const error = new Error('User DN is not provided or invalid')
|
||||
logger.error('❌ LDAP authentication error:', error.message)
|
||||
reject(error)
|
||||
return
|
||||
}
|
||||
|
||||
if (!password || typeof password !== 'string') {
|
||||
logger.debug(`🚫 Invalid or empty password for DN: ${userDN}`)
|
||||
resolve(false)
|
||||
return
|
||||
}
|
||||
|
||||
const authClient = this.createClient()
|
||||
|
||||
authClient.bind(userDN, password, (err) => {
|
||||
@@ -232,8 +306,29 @@ class LdapService {
|
||||
throw new Error('LDAP authentication is not enabled')
|
||||
}
|
||||
|
||||
if (!username || !password) {
|
||||
throw new Error('Username and password are required')
|
||||
if (!username || typeof username !== 'string' || username.trim() === '') {
|
||||
throw new Error('Username is required and must be a non-empty string')
|
||||
}
|
||||
|
||||
if (!password || typeof password !== 'string' || password.trim() === '') {
|
||||
throw new Error('Password is required and must be a non-empty string')
|
||||
}
|
||||
|
||||
// 验证LDAP服务器配置
|
||||
if (!this.config.server || !this.config.server.url) {
|
||||
throw new Error('LDAP server URL is not configured')
|
||||
}
|
||||
|
||||
if (!this.config.server.bindDN || typeof this.config.server.bindDN !== 'string') {
|
||||
throw new Error('LDAP bind DN is not configured')
|
||||
}
|
||||
|
||||
if (!this.config.server.bindCredentials || typeof this.config.server.bindCredentials !== 'string') {
|
||||
throw new Error('LDAP bind credentials are not configured')
|
||||
}
|
||||
|
||||
if (!this.config.server.searchBase || typeof this.config.server.searchBase !== 'string') {
|
||||
throw new Error('LDAP search base is not configured')
|
||||
}
|
||||
|
||||
const client = this.createClient()
|
||||
@@ -253,6 +348,12 @@ class LdapService {
|
||||
const userDN = ldapEntry.dn
|
||||
logger.debug(`👤 Found user DN: ${userDN}`)
|
||||
|
||||
// 验证用户DN
|
||||
if (!userDN || typeof userDN !== 'string') {
|
||||
logger.error(`❌ Invalid or missing DN for user: ${username}`)
|
||||
return { success: false, message: 'Authentication service error' }
|
||||
}
|
||||
|
||||
// 4. 验证用户密码
|
||||
const isPasswordValid = await this.authenticateUser(userDN, password)
|
||||
if (!isPasswordValid) {
|
||||
|
||||
Reference in New Issue
Block a user