Oracle数据库不直接支持AD账号直登,必须通过全局用户与LDAP目录服务协同实现:启用ldap_directory_access(设为password或ssl)、ldap_directory_sys_auth=YES,在sqlnet.ora中正确定义DIRECTORY_SERVERS和DEFAULT_ADMIN_CONTEXT,创建用户时使用完整且可绑定的DN并显式授权,SSL连接需配置wallet及TLS版本。
Oracle数据库不直接“连AD做登录”,而是靠全局用户+LDAP目录服务协同工作
oracle本身不内置ad账号直登能力,所谓“集成”本质是让数据库信任外部ldap目录(oid/oud/ad)返回的认证结果,并把dn映射成数据库schema。关键不是改ldap.ora,而是启用ldap_directory_access并配好全局用户。
常见错误是以为改完sqlnet.ora就能用sqlplus john@domain\john登录——实际不行。必须先在DB里创建CREATE USER xxx IDENTIFIED GLOBALLY AS 'cn=john,ou=users,dc=example,dc=com',且该DN在AD中真实存在、可被Oracle LDAP客户端查到。
-
ldap_directory_access必须设为password或ssl,不能是none -
ldap_directory_sys_auth设为YES才允许SYS走LDAP登录 - AD作为LDAP服务器时,
DIRECTORY_SERVER_TYPE应设为ad,否则属性映射会错(比如sAMAccountName找不到) - 测试前先用
ldapsearch -h dc01.example.com -p 389 -D "cn=admin,dc=example,dc=com" -w password -b "dc=example,dc=com" "(sAMAccountName=john)" dn确认DN可达
sqlnet.ora里DIRECTORY_SERVERS和DEFAULT_ADMIN_CONTEXT怎么写才不报ORA-12154
DIRECTORY_SERVERS不是填个IP就完事,它定义的是Oracle Net去哪查TNS别名,也用于全局用户DN解析。格式必须严格:DIRECTORY_SERVERS = (dc01.example.com:389:1),末尾:1是重试次数,漏掉就会静默失败。
DEFAULT_ADMIN_CONTEXT必须与AD根域完全一致,大小写敏感,且不能有空格或中文逗号。例如AD域是EXAMPLE.COM,这里就得写"dc=example,dc=com",写成"DC=EXAMPLE,DC=COM"或"dc=example.com"都会导致DN查找失败。
- SSL连接必须用端口
636,且DIRECTORY_SERVERS要同步改成(dc01.example.com:636:1) - 若AD启用了TLS 1.2+,Oracle 12c需在
sqlnet.ora加SQLNET.ENCRYPTION_CLIENT = required和SQLNET.ENCRYPTION_TYPES_CLIENT = (AES256) - 多个LDAP服务器可用括号包住:
DIRECTORY_SERVERS = ((dc01.example.com:389:1)(dc02.example.com:389:1))
CREATE USER IDENTIFIED GLOBALLY AS '...' 时DN写错的典型表现
执行CREATE USER aduser IDENTIFIED GLOBALLY AS 'cn=john,ou=users,dc=example,dc=com'后,登录仍提示ORA-01017: invalid username/password,大概率是DN拼写问题,而非密码错。
Oracle不会实时校验DN有效性,建用户时只存字符串;真正校验发生在首次登录时——它会拿这个DN去LDAP bind,失败就拒登。所以建完用户必须立刻用ldapsearch验证该DN能否bind成功。
- AD中用户实际DN是
cn=John Doe,ou=users,dc=example,dc=com,但建用户时写了cn=john(小写+无空格),就会bind失败 - DN中含特殊字符(如
\、+、,)未转义,例如cn=O'Neil应写成cn=O\'Neil - 用了
uid=john但AD默认不用uid属性,而用sAMAccountName,此时DN应为cn=john,cn=users,dc=example,dc=com或通过userPrincipalName构造 - 共享全局schema场景下,DN可为空:
IDENTIFIED GLOBALLY AS '',但要求ldap_directory_sys_auth=NO且用户必须有对应角色映射
为什么改了配置还是走本地密码验证?
最常被忽略的一点:Oracle监听器和数据库实例必须重新加载sqlnet.ora。改完sqlnet.ora后只执行lsnrctl reload不够,因为数据库实例启动时已读取一次参数,后续不自动刷新。
必须确认V$PARAMETER中ldap_directory_access值已更新,否则所有全局用户请求都会 fallback 到本地验证。
- 查当前值:
SELECT name, value FROM V$PARAMETER WHERE name IN ('ldap_directory_access', 'ldap_directory_sys_auth'); - 若值未变,需重启数据库实例(
shutdown immediate; startup),单纯alter system set ... scope=spfile对这两个参数无效 - 监听器日志
$ORACLE_HOME/network/log/listener.log里搜LDAP,能看到是否尝试连接LDAP服务器 - Windows AD环境注意防火墙:数据库服务器 outbound 到AD的389/636端口必须放行,且AD侧需允许匿名bind或指定搜索账户











