【问题标题】:Is it possible to change the password via cfldap?是否可以通过 cfldap 更改密码?
【发布时间】:2014-04-24 12:44:21
【问题描述】:

一段时间以来,我一直试图通过cfldap 更改密码。通过 SSL 和端口 636 (cfssl_basic) 建立连接,在登录中进行了测试。我尝试了以下版本的代码:

<cfset password_new_retyp=charsetEncode(charsetDecode('"'&password_new_retyp&'"','UTF-16LE'),'UTF-8'))>
<!---encoded, decoded password --->
<cfldap action="modify"
    dn="#session.dn_addres#" --- i query this on login
    modifyType="replace"
    attributes="unicodePwd=#password_new_retyp#"
    server="xxxx.xxxx.xxx.xx" --- name of server thet i use on login
    secure = "cfssl_basic" 
    port=636
    username="#session.username#" ---username thet is used on login
    password="#password_old#">  ---- pass before changing

错误是这样的:

尝试执行查询时发生错误:[LDAP:错误代码 49 - 80090308:LdapErr:DSID-0C0903C5,注释:AcceptSecurityContext 错误,数据 52e,v23f0]。

我也试过这种不编码密码的方法:

<cfldap action="modify"
    dn="#session.dn_addres#"
    modifyType="replace"
    attributes="password=#password_new_retyp#"
    server="xxxx.xxxx.xxx.xx"
    secure = "cfssl_basic"
    port=636
    username="#session.username#"
    password="#password_old#" >

和错误是一样的:

尝试执行查询时发生错误:[LDAP:错误代码 49 - 80090308:LdapErr:DSID-0C0903C5,注释:AcceptSecurityContext 错误,数据 52e,v23f0]。 一个或多个必需属性可能缺失或不正确,或者您无权在服务器上执行此操作。

有什么想法吗?

【问题讨论】:

  • 错误代码 49 和 52e 表示凭据无效。您正在尝试更改您登录时使用的同一帐户的密码?
  • 我是。使用相同的代码,(您只需更改属性)可能会更改用户的任何数据,但不会更改密码。
  • session.dn_addres 的值是多少?更具体地说,您确定该值与您尝试更新的唯一帐户匹配吗?
  • session.dn_addres 从日志记录中获得,听说我也使用 cfldap 但操作 QUERY 然后获取 DN 属性,该属性设置为会话。
  • 问题是用这段代码当我改变属性时可以正常工作,例如可以把attributes="postalcode = 10007" 一切顺利。

标签: coldfusion ldap


【解决方案1】:

这是一条漫长而艰难的道路,但我到达了那里。我希望这对尝试更改密码和执行 LDAP 密码策略的其他人有所帮助。

来源:基于 Edward Smith 在archived CFTalk thread中的代码

<cftry>
    <cfscript>
        // You are going to use  the user's credentials to login to LDAP
        // Assuming your LDAP is set up to do so

        // Set up varibles
        newPassword = '"#newPassword#"';
        oldPassword = '"#currentPassword#"';
        // You would probably pass in a variable here, I typed it out so you would ss the format its expecting
        distinguishedName = "CN=theUser,OU=someOU,DC=DDDD,DC=CCC,DC=AAA,DC=ZZZ";
        newUnicodePassword = newPassword.getBytes("UnicodeLittleUnmarked");
        oldUnicodePassword = oldPassword.getBytes("UnicodeLittleUnmarked");
        ldapsURL = "ldap://#ldapServer#:#ldapPort#";

        // Create a Java Hashtable
        javaEnv = CreateObject("java", "java.util.Hashtable").Init();

        // Put stuff in the Hashtable
        javaEnv.put("java.naming.provider.url", ldapsURL);
        // The user's Full DN and Password
        javaEnv.put("java.naming.security.principal", "#distinguishedName#");
        javaEnv.put("java.naming.security.credentials", "#currentPassword#");
        javaEnv.put("java.naming.security.authentication", "simple");
        javaEnv.put("java.naming.security.protocol", "ssl");
        javaEnv.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");

        // Create a Java InitialDirContext
        javaCtx = CreateObject("java", "javax.naming.directory.InitialDirContext").Init(javaEnv);

        // Create two Java BasicAttributes
        oldBA = CreateObject("java", "javax.naming.directory.BasicAttribute").Init("unicodePwd", oldUnicodePassword);
        newBA = CreateObject("java", "javax.naming.directory.BasicAttribute").Init("unicodePwd", newUnicodePassword);

        /***********************************************
        *   Stick the attributes into an Java Array and tell it what to do with them
        *   Guess what? A CF Array = a Java Array
        *   1 = DirContext.ADD_ATTRIBUTE
        *   2 = DirContext.REPLACE_ATTRIBUTE
        *   3 = DirContext.REMOVE_ATTRIBUTE
        *  This is the big trick 
        *   If you login above as an admin then you only need to do a 2 Replace but will not run LDAP passoword policy (lenght, complexity, history... etc.)
        *       It will let you change password to anything
        *   If you want to check the LDAP password policy then you need to create the array and first Remove (3) then Add (1)
        *       Error Code 19 means something in the LDAP password policy was violated
        *           I haven't figured out how to read what the error is (like "password length too short" or "you have used this password in the past")
        *       Error Code 49 means invalid username/password
        ************************************************/
        mods = [
            createObject( "java", "javax.naming.directory.ModificationItem").init(3, oldBA),
            createObject( "java", "javax.naming.directory.ModificationItem").init(1, newBA)
        ]; 
        // Run it
        javaCtx.modifyAttributes(distinguishedName,mods);
        javaCtx.close();
    </cfscript>
    // Yeah! I could have scripted the cfcatch but this was easier.
    <cfcatch>
        <cfif find('error code 19',cfcatch.message)>
            <!--- I am using cfwheels so this just displays a nice error message on the next page --->
            <cfset flashInsert(error="New password does not meet requirements defined in the password rules.")>
        <cfelseif isDefined('cfcatch.RootCause.cause.Explanation') and find('error code 49', cfcatch.RootCause.cause.Explanation)>
            <!--- I am using cfwheels so this just displays a nice error message on the next page --->
            <cfset flashInsert(error="Current Password IS incorrect.")>
        <cfelse>    
            <!--- This just pukes the error up hard and uncaught --->
            <cfrethrow>
        </cfif>
        <cfset hasError = true>
    </cfcatch>  
</cftry>

【讨论】:

  • 感谢您发布最终解决方案。旁注,我从未听说过“UnicodeLittleUnmarked”:) 听起来像是synonym for "UTF-16LE"。我更喜欢后者,更让人想起格列佛游记;-)
  • 我无法让它正常工作,只能黑屏。有人可以帮我解决这个问题吗?
  • @Leigh 你有没有机会帮助我让它为我工作?即使我尝试捕获,我也只是得到一个没有错误的白屏。 stackoverflow.com/questions/42168696/…
  • CF2021.. 我发现这是我唯一可以使用的解决方案。谢谢。
猜你喜欢
  • 1970-01-01
  • 2022-11-29
  • 2023-03-24
  • 2017-01-29
  • 2019-01-14
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
  • 2022-12-22
相关资源
最近更新 更多