Skip to content

ActiveDirectory connector custom error messages #66

Open

Description

@steveneppler

The 'resolveBindException' function in the Active Directory function never gets called when a password is expired. I made a test change by renaming it 'resolveBindError' (taken from standard LDAP connector class) and changing the signature, and now the code gets called but the error messages aren't defined which cause an error when a password is expired:

SimpleSAML\Error\Exception: Key "RESETPASSWORD" for sequence/mapping with keys "ACSPARAMS...." does not exist in core:loginuserpass.twig

I have tried defining custom errors using the getCustomTitles() and getCustomDescriptions() methods but I'm not doing it right, but now I'm wondering if I'm going down the correct path. Any suggestions?

Activity

  1. tvdijen commented on Mar 1, 2025

    @tvdijen
    Member

    You are definitely on the right path! This module needs to extend \SimpleSAML\Error\ErrorCodes to define the custom errors and then this extended class needs to be passed as the 4th parameter to any call to SimpleSAML\Error\Error::__construct()..

  2. steveneppler commented on Mar 2, 2025

    @steveneppler
    Author

    Thanks - I'll attempt that and submit a pull request if it all works out.

  3. steveneppler commented on Mar 3, 2025

    @steveneppler
    Author

    I'm still doing something wrong, here's the log output with some extra logging output in strategic places:

    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] LDAP bind(): Bind successful for DN 'CN=searchuser,DC=xxxxx'.
    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] LDAP bind(): InvalidCredentialsException
    adsaml-1  | NOTICE: PHP message: ADE: __construct()
    adsaml-1  | NOTICE: PHP message: ErrorCodes __construct()
    adsaml-1  | NOTICE: PHP message: ADE: getCustomTitles()
    adsaml-1  | NOTICE: PHP message: ADE: getCustomDesc()
    adsaml-1  | Mar 3 13:19:32 simplesamlphp NOTICE STAT [f440e1b4ee] Unsuccessful login attempt from 10.x.x.x.
    adsaml-1  | NOTICE: PHP message: ErrorCodes __construct()
    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] Saved state: '_a22a496b54d252c7cddcbd202bbc2f757ea2bfc450:https://xxxxx/simplesaml/module.php/admin/test/cmu-ldap'
    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] Localization: load domain 'messages' at '/var/simplesamlphp/locales'
    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] Trying langpath for 'en' as '/var/simplesamlphp/locales/en/LC_MESSAGES/'
    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] Localization: load domain 'core' at '/var/simplesamlphp/modules/core/locales'
    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] Trying langpath for 'en' as '/var/simplesamlphp/modules/core/locales/en/LC_MESSAGES/'
    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] Localization: load domain 'core' at '/var/simplesamlphp/modules/core/locales'
    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] Trying langpath for 'en' as '/var/simplesamlphp/modules/core/locales/en/LC_MESSAGES/'
    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] Localization: load domain 'cmu-saml' at '/var/simplesamlphp/modules/cmu-saml/locales'
    adsaml-1  | Mar 3 13:19:32 simplesamlphp DEBUG [f440e1b4ee] Trying langpath for 'en' as '/var/simplesamlphp/modules/cmu-saml/locales/en/LC_MESSAGES/'
    adsaml-1  | NOTICE: PHP message: ErrorCodes __construct()
    adsaml-1  | Mar 3 13:19:32 simplesamlphp ERROR [f440e1b4ee] SimpleSAML\Error\Error: UNHANDLEDEXCEPTION
    adsaml-1  | Mar 3 13:19:32 simplesamlphp ERROR [f440e1b4ee] Backtrace:
    adsaml-1  | Mar 3 13:19:32 simplesamlphp ERROR [f440e1b4ee] 2 /var/simplesamlphp/src/SimpleSAML/Error/ExceptionHandler.php:36 (SimpleSAML\Error\ExceptionHandler::customExceptionHandler)
    adsaml-1  | Mar 3 13:19:32 simplesamlphp ERROR [f440e1b4ee] 1 /var/simplesamlphp/vendor/symfony/error-handler/ErrorHandler.php:538 (Symfony\Component\ErrorHandler\ErrorHandler::handleException)
    adsaml-1  | Mar 3 13:19:32 simplesamlphp ERROR [f440e1b4ee] 0 [builtin] (N/A)
    adsaml-1  | Mar 3 13:19:32 simplesamlphp ERROR [f440e1b4ee] Caused by: SimpleSAML\Error\Exception: Key "RESETPASSWORD" for sequence/mapping with keys "ACSPARAMS, ARSPARAMS, AUTHSOURCEERROR, BADREQUEST, CASERROR, CONFIG, CREATEREQUEST, DISCOPARAMS, GENERATEAUTHNRESPONSE, INVALIDCERT, LDAPERROR, LOGOUTINFOLOST, LOGOUTREQUEST, MEMCACHEDOWN, METADATA, METADATANOTFOUND, METHODNOTALLOWED, NOACCESS, NOCERT, NORELAYSTATE, NOSTATE, NOTFOUND, NOTFOUNDREASON, NOTSET, ADMINNOTHASHED, NOTVALIDCERT, PROCESSASSERTION, PROCESSAUTHNREQUEST, RESPONSESTATUSNOSUCCESS, SLOSERVICEPARAMS, SSOPARAMS, UNHANDLEDEXCEPTION, UNKNOWNCERT, USERABORTED, WRONGUSERPASS" does not exist in core:loginuserpass.twig
    

    The 'ADE: getCustomTitles()' and 'ADE: getCustomDesc()' are extra logging I added to verify the functions are getting called in the class. The 'ErrorCodes __construct()' message is coming from the parent class in simplesamlphp, I added a log message there for testing as well. You can see the ActiveDirectoryErrors class, which is defining 'RESETPASSWORD' but the view still can't locate it. Any pointers?

  4. tvdijen commented on Mar 3, 2025

    @tvdijen
    Member

    I think you have to pass an instance of ActiveDirectoryErrors as the fourth parameter here:
    https://github.com/simplesamlphp/simplesamlphp-module-ldap/blob/master/src/Connector/Ldap.php#L102

  5. steveneppler commented on Mar 3, 2025

    @steveneppler
    Author

    I forgot to mention I did that. I also did it in the ActiveDirectory.php connector just to try something new. I've pushed up some of my current changes, which do include that as the fourth parameter:
    https://github.com/steveneppler/simplesamlphp-module-ldap/blob/aderrors/src/Connector/Ldap.php

  6. tvdijen commented on Mar 4, 2025

    @tvdijen
    Member

    Apparently this has been an issue for a while: simplesamlphp/simplesamlphp#2133
    @monkeyiq You think you can take another look at this?

  7. monkeyiq commented on Mar 5, 2025

    @monkeyiq

    I merged some code to track a custom ErrorCodes class a while back. The test suite for that is in a separate module and it seems I didn't get around to updating the docs well enough. The module is at https://github.com/simplesamlphp/simplesamlphp-module-testauthsource/blob/2c10d7ac23566670182f765b873c13f1d1c18828/src/Auth/Source/ThrowCustomErrorCode.php#L76

    The core of this is that you need a custom subclass of ErrorCodes which can use constants like ERR_LOGON_RESTRICTION. There is a title and description in that class and the translation should work on the returned strings too.
    For example https://github.com/monkeyiq/simplesamlphp-module-ldap/blob/2025/march/custom-error/src/Connector/ActiveDirectoryErrorCodes.php

    That can then be throw with a custom error class ActiveDirectoryError for example
    https://github.com/monkeyiq/simplesamlphp-module-ldap/blob/2025/march/custom-error/src/Connector/ActiveDirectoryError.php

    And to throw this custom error code something like
    https://github.com/monkeyiq/simplesamlphp-module-ldap/blob/5130da97d5e281998138e74bd4e24ea9b15c0f81/src/Connector/Ldap.php#L84

  8. tvdijen commented on Jul 21, 2025

    @tvdijen
    Member

    @steveneppler Were you able to get things working with Ben's pointers? I'd still be happy to look at your pull request.

  9. steveneppler commented on Jul 21, 2025

    @steveneppler
    Author

    I've tried a few things but never got it working and implemented a workaround. I need to get back to this, but other projects at work have taken priority.

  10. monkeyiq commented on Jul 22, 2025

    @monkeyiq

    I'm interested in what the work around is. I look forward to seeing it when your time permits.

  11. steveneppler commented on Jul 22, 2025

    @steveneppler
    Author

    It's pretty cheesy, I checked stuff in the view since I have a custom template anyway, and set the 'errdesc' and 'errtitle' variable there manually, here's a snippet of core/loginuserpass.twig:

    {% if (errorcode is same as ('RESETPASSWORD')) or (errorcode is same as ('RESETACCOUNT')) %}
      {% set errtitle = "Password Expired" %}
      {% set errdesc = "Your password is expired." %}
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions