我们正在尝试使用针对Microsoft AD的dbms_ldap对我们的应用程序用户进行身份验证,我们无法在离岸环境中对其进行测试
我们有三个具体问题
1)如何验证用户是否存在于Microsoft Active Directory
中我们使用以下代码获取Application用户的专有名称
DBMS_LDAP.USE_EXCEPTION := FALSE;
retval := DBMS_LDAP.search_s(ld => ldapSession,
base => LDAP_BASE,
scope => DBMS_LDAP.SCOPE_SUBTREE,
filter => '(&(objectclass=USER)(SAMAccountName=' ||
p_username || '))',
attrs => attrList,
attronly => 0,
res => ldapMessage);
-- get the DN
if retval <> DBMS_LDAP_UTL.SUCCESS THEN
RAISE l_ldap_exception;
END IF;
userDN := DBMS_LDAP.get_dn(ldapSession, ldapMessage);
所以第一个问题是什么是
的价值 userDN and ldapMessage
如果用户不存在于Microsoft AD
中2)假设用户存在且输入了错误的密码,那将是retval的返回值
if p_password is null then
raise_application_error(-20000, 'Invalid Null password');
else
retval := DBMS_LDAP.simple_bind_s(ldapSession,userDN, p_password);
end if;
if retval <> DBMS_LDAP_UTL.SUCCESS THEN
RAISE l_ldap_exception;
and if;
3)我的第三个问题是假设用户已登录系统并且ldapsession仍然没有解除绑定识别重复会话的方法
答案 0 :(得分:5)
警告警告警告
这不是一个答案,而是对使用以下代码验证用户的任何人的警告。
retval := DBMS_LDAP.simple_bind_s(ldapSession, userDN, p_password);
按照设计(LDAP设计),如果密码为 null ,此函数调用将始终返回成功。这样做是为了允许匿名LDAP查询。这可能会在您的特定服务器上禁用,但并非总是如此。
因此,如果您想使用此函数,请确保使用if块将其包装,以确保用户提供的密码不为空。 e.g。
if p_password is null then
raise_application_error(-20000, 'Invalid Null password');
else
retval := DBMS_LDAP.simple_bind_s(ldapSession,userDN, p_password);
end if;
有关详细信息,请参阅:http://www.inside-oracle-apex.com/dbms_ldapsimple_bind_s-apex_ldapauthenticate-and-null-password/
答案 1 :(得分:3)
首先,阅读文档。它几乎包含您回答问题所需的一切:http://docs.oracle.com/cd/E23943_01/oid.1111/e10186/dbmsldap_ref.htm
1)将引发NULL或get_dn_exception,我不确定。无论如何,另一种检查方法是计算搜索结果,你只需要检查计数是否> 0:
DBMS_LDAP.count_entries(ld => ldapSession, msg => ldapMessage)
2)retval只能是DMBS_LDAP.SUCCESS,任何错误都会引发异常
3)如果您有会话ID,请调用任何需要有效LDAP会话的过程,例如simple_bind_s并检查是否引发了invalid_session。如果您没有会话ID,我不知道确定是否有任何LDAP会话打开的方法。
答案 2 :(得分:2)
在我的应用程序中,我这样做:
ld := DBMS_LDAP.INIT(LDAP_SERVER, 389);
retval := DBMS_LDAP.SIMPLE_BIND_S(ld, LDAP_USER, LDAP_PASSWORD);
DBMS_LDAP.USE_EXCEPTION := FALSE;
retval := DBMS_LDAP.SEARCH_S(
ld => ld,
base => LDAP_BASE,
SCOPE => DBMS_LDAP.SCOPE_SUBTREE,
FILTER => '&(objectCategory=user)(sAMAccountName='||username ||')',
attrs => attrs,
attronly => 0,
res => ldapMessage);
retval := DBMS_LDAP.COUNT_ENTRIES(ld, ldapMessage);
ldapEntry := DBMS_LDAP.FIRST_ENTRY(ld, ldapMessage);
IF ldapEntry IS NULL THEN
retval := DBMS_LDAP.MSGFREE(ldapMessage);
retval := DBMS_LDAP.UNBIND_S(ld);
RAISE_APPLICATION_ERROR(-20001, 'User does not exist');
ELSE
userDN := DBMS_LDAP.GET_DN(ld, ldapEntry);
END IF;
retval := DBMS_LDAP.MSGFREE(ldapMessage);
IF p_password IS NULL THEN
retval := DBMS_LDAP.UNBIND_S(ld);
RAISE_APPLICATION_ERROR(-20000, 'Invalid Null password');
ELSE
retval := DBMS_LDAP.SIMPLE_BIND_S(ldapSession, userDN, p_password);
IF retval <> DBMS_LDAP_UTL.SUCCESS THEN
retval := DBMS_LDAP.UNBIND_S(ld);
RAISE_APPLICATION_ERROR(-20001, 'Wrong password');
END IF;
END IF;
retval := DBMS_LDAP.UNBIND_S(ld);
关于你的问题:
1)如何验证用户是否存在于Microsoft Active Directory
中
查看我的代码
所以第一个问题是
的价值userDN
和ldapMessage
userDN
将为NULL,ldapMessage
我不在乎。
2)假设用户存在且输入了错误的密码,那将是retval的返回值
DBMS_LDAP.SUCCESS
(0)DBMS_LDAP.INVALID_CREDENTIALS
(49)注意,只有在设置DBMS_LDAP.INVALID_CREDENTIALS
时才会获得DBMS_LDAP.USE_EXCEPTION := FALSE;
,否则如果密码错误则会出现异常。
3)我的第三个问题是假设用户已登录系统并且ldapsession仍然没有解除绑定识别重复会话的方法
确保在您的代码中正确调用DBMS_LDAP.UNBIND_S(ld);
。
另一个警告:
如果您在DBMS_LDAP.SIMPLE_BIND_S(ldapSession, userDN, p_password);
提供了错误的密码,则Active Directory中的badPwdCount
属性不会递增!因此,您可以无限制地尝试输入(或暴力破解)密码。