Hi,
I performed the following steps on the latest 2.0.9-SNAPSHOT, with test data (e.g. you can replicate either with the standalone distribution, or by starting the Maven project in embedded mode):

0. added AUTHENTICATE to resource-ldap's capabilities
1. created an account policy AP with pass-through to resource-ldap
2. created a Realm /myrealm, with AP configured
3. created a new user 'ilgrosso' under /myrealm, and assigned resource-ldap; password was set to 'Password123', with 'store password on Syncope' option set
4. changed the password value for 'ilgrosso' on Syncope to 'Password321'

At this point, I am able to authenticate 'ilgrosso' via REST with both 'Password123' and 'Password321':

curl -v -u ilgrosso:Password123 http://localhost:9080/syncope/rest/users/self curl -v -u ilgrosso:Password321 http://localhost:9080/syncope/rest/users/self

while on LDAP the only password working is 'Password123':

ldapsearch -h localhost -p 1389 -D "uid=ilgrosso,ou=people,o=isp" -x -w Password123 -b "uid=ilgrosso,ou=people,o=isp"

From the REST calls above I can see that:

  "resources": [
    "resource-ldap"
  ],

e.g. resource-ldap is assigned to ilgrosso.

If I attempt to provide bad password:

curl -v -u ilgrosso:Password122 http://localhost:9080/syncope/rest/users/self

one or several times, nothing changes to ilgrosso, resource-ldap is still assigned.

Not sure what is happening to your case, but it does not seem like a general issue.

HTH
Regards.

On 23/05/2018 10:47, Alexandr Anatolievich wrote:
Hi!
- "Max Authentication Attempts" to 0
- "Propagate Suspension" is disabled
- I selected "My Resource" among Available Passthrough Resources

On user login In JPAUserDAO, line 390, I get array of two equal Accoun Policies using getAccountPolicies method:
1)  "Default Account Policy" for "My Realm"
2) Same "Default Account Policy" for "My Resource"

My "Default Account Policy" has next attributes (I put as many details as possible):

propagateSuspension = 0
maxAuthenticationAttempts = 0
pcDetachedState = null
pcStateManager =
{
_loaded: {0, 1, 2, 3, 4, 5}
_flush: "{4}",
_dirty: "{4}",
_flags: 530,
_state: Persistent-Notransactional
  _readLockLevel: 0,
  _writeLockLevel: 0,
  _datePrecision: -1,
  postLoadCallback: true

}
ruleConfs =
[{
  "maxLength": 0,
  "minLength": 0,
  "pattern": null,
  "allUpperCase": false,
  "allLowerCase": false,
  "wordsNotPermitted": [],
  "schemasNotPermitted": [],
  "prefixesNotPermitted": [],
  "suffixesNotPermitted": [],
  "name": "org.apache.syncope.common.lib.policy.DefaultAccountRuleConf"
}]

resources:
[{
enforceMandatoryCondition: 0,
orgUnit: null,
propagationPriority: null,
randomPwdIfNotProvided: 0,
pcStateManager: {
_loaded: {0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17}
_flush: null,
_dirty: null,
_flags: 16,
 _state: Persistent-Notransactional
     _readLockLevel: 0,
     _writeLockLevel: 0,
     _datePrecision: -1,
     postLoadCallback: true

}
...
connector:
  {
    "schema": {
      "name": "reloadScriptOnExecution",
      "displayName": "reloadScriptOnExecution",
      "helpMessage": "reloadScriptOnExecution",
      "type": "boolean",
      "required": false,
      "order": 2,
      "confidential": false,
      "defaultValues": [
        false
      ]
    },
    "overridable": false,
    "values": [
      false
    ]
  },
  {
    "schema": {
      "name": "authenticateScript",
      "displayName": "authenticateScript",
      "helpMessage": "authenticateScript",
      "type": "java.lang.String",
      "required": false,
      "order": 6,
      "confidential": false,
      "defaultValues": [
        ""
      ]
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "authenticateScriptFileName",
      "displayName": "authenticateScriptFileName",
      "helpMessage": "authenticateScriptFileName",
      "type": "java.lang.String",
      "required": false,
      "order": 14,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": [
      " /AuthenticateScript .groovy"
    ]
  },
  {
    "schema": {
      "name": "scriptingLanguage",
      "displayName": "scriptingLanguage",
      "helpMessage": "scriptingLanguage",
      "type": "java.lang.String",
      "required": false,
      "order": 0,
      "confidential": false,
      "defaultValues": [
        "GROOVY"
      ]
    },
    "overridable": false,
    "values": [
      "GROOVY"
    ]
  },
  {
    "schema": {
      "name": "baseAddress",
      "displayName": "baseAddress",
      "helpMessage": "baseAddress",
      "type": "java.lang.String",
      "required": true,
      "order": -3,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": [
      "http:// my-site.net <http://my-site.net>"
    ]
  },
  {
    "schema": {
      "name": "schemaScriptFileName",
      "displayName": "schemaScriptFileName",
      "helpMessage": "schemaScriptFileName",
      "type": "java.lang.String",
      "required": false,
      "order": 17,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "syncScript",
      "displayName": "syncScript",
      "helpMessage": "syncScript",
      "type": "java.lang.String",
      "required": false,
      "order": 7,
      "confidential": false,
      "defaultValues": [
        ""
      ]
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "username",
      "displayName": "username",
      "helpMessage": "username",
      "type": "java.lang.String",
      "required": false,
      "order": 0,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": [
      "admin"
    ]
  },
  {
    "schema": {
      "name": "updateScript",
      "displayName": "updateScript",
      "helpMessage": "updateScript",
      "type": "java.lang.String",
      "required": false,
      "order": 4,
      "confidential": false,
      "defaultValues": [
        ""
      ]
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "clearTextPasswordToScript",
      "displayName": "clearTextPasswordToScript",
      "helpMessage": "clearTextPasswordToScript",
      "type": "boolean",
      "required": false,
      "order": 1,
      "confidential": false,
      "defaultValues": [
        true
      ]
    },
    "overridable": false,
    "values": [
      true
    ]
  },
  {
    "schema": {
      "name": "password",
      "displayName": "password",
      "helpMessage": "password",
      "type": "org.identityconnectors.common.security.GuardedString",
      "required": false,
      "order": 1,
      "confidential": true,
      "defaultValues": []
    },
    "overridable": false,
    "values": [
      "Dev123456!"
    ]
  },
  {
    "schema": {
      "name": "deleteScript",
      "displayName": "deleteScript",
      "helpMessage": "deleteScript",
      "type": "java.lang.String",
      "required": false,
      "order": 5,
      "confidential": false,
      "defaultValues": [
        ""
      ]
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "resolveUsernameScript",
      "displayName": "resolveUsernameScript",
      "helpMessage": "resolveUsernameScript",
      "type": "java.lang.String",
      "required": false,
      "order": 6,
      "confidential": false,
      "defaultValues": [
        ""
      ]
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "updateScriptFileName",
      "displayName": "updateScriptFileName",
      "helpMessage": "updateScriptFileName",
      "type": "java.lang.String",
      "required": false,
      "order": 11,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": [
      " /UpdateScript .groovy"
    ]
  },
  {
    "schema": {
      "name": "syncScriptFileName",
      "displayName": "syncScriptFileName",
      "helpMessage": "syncScriptFileName",
      "type": "java.lang.String",
      "required": false,
      "order": 16,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "resolveUsernameScriptFileName",
      "displayName": "resolveUsernameScriptFileName",
      "helpMessage": "resolveUsernameScriptFileName",
      "type": "java.lang.String",
      "required": false,
      "order": 15,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "testScript",
      "displayName": "testScript",
      "helpMessage": "testScript",
      "type": "java.lang.String",
      "required": false,
      "order": 9,
      "confidential": false,
      "defaultValues": [
        ""
      ]
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "searchScript",
      "displayName": "searchScript",
      "helpMessage": "searchScript",
      "type": "java.lang.String",
      "required": false,
      "order": 6,
      "confidential": false,
      "defaultValues": [
        ""
      ]
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "createScriptFileName",
      "displayName": "createScriptFileName",
      "helpMessage": "createScriptFileName",
      "type": "java.lang.String",
      "required": false,
      "order": 10,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": [
      " /CreateScript .groovy"
    ]
  },
  {
    "schema": {
      "name": "schemaScript",
      "displayName": "schemaScript",
      "helpMessage": "schemaScript",
      "type": "java.lang.String",
      "required": false,
      "order": 8,
      "confidential": false,
      "defaultValues": [
        ""
      ]
    },
    "overridable": false,
    "values": []
  },
  {
    "schema": {
      "name": "searchScriptFileName",
      "displayName": "searchScriptFileName",
      "helpMessage": "searchScriptFileName",
      "type": "java.lang.String",
      "required": false,
      "order": 13,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": [
      " /SearchScript .groovy"
    ]
  },
  {
    "schema": {
      "name": "accept",
      "displayName": "accept",
      "helpMessage": "accept",
      "type": "java.lang.String",
      "required": true,
      "order": -2,
      "confidential": false,
      "defaultValues": [
        "application/json"
      ]
    },
    "overridable": false,
    "values": [
      "application/json"
    ]
  },
  {
    "schema": {
      "name": "testScriptFileName",
      "displayName": "testScriptFileName",
      "helpMessage": "testScriptFileName",
      "type": "java.lang.String",
      "required": false,
      "order": 18,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": [
      " /TestScript .groovy"
    ]
  },
  {
    "schema": {
      "name": "bearer",
      "displayName": "bearer",
      "helpMessage": "bearer",
      "type": "java.lang.String",
      "required": false,
      "order": 2,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": [
      "00000000000000000"
    ]
  },
  {
    "schema": {
      "name": "contentType",
      "displayName": "contentType",
      "helpMessage": "contentType",
      "type": "java.lang.String",
      "required": true,
      "order": -1,
      "confidential": false,
      "defaultValues": [
        "application/json"
      ]
    },
    "overridable": false,
    "values": [
      "application/json"
    ]
  },
  {
    "schema": {
      "name": "deleteScriptFileName",
      "displayName": "deleteScriptFileName",
      "helpMessage": "deleteScriptFileName",
      "type": "java.lang.String",
      "required": false,
      "order": 12,
      "confidential": false,
      "defaultValues": []
    },
    "overridable": false,
    "values": [
      " /DeleteScript .groovy"
    ]
  },
  {
    "schema": {
      "name": "createScript",
      "displayName": "createScript",
      "helpMessage": "createScript",
      "type": "java.lang.String",
      "required": false,
      "order": 3,
      "confidential": false,
      "defaultValues": [
        ""
      ]
    },
    "overridable": false,
    "values": []
  }
}]

2018-05-23 9:36 GMT+03:00 Francesco Chicchiriccò <[email protected] <mailto:[email protected]>>:

    On 22/05/2018 11:00, Alexandr Anatolievich wrote:
    Thank you for your response.

    I updated my Authenticate groovy script. I have next exception
    when user puts wrong credentials
    
org.identityconnectors.framework.common.exceptions.InvalidCredentialException:
    Authentication failed for "My User".

    But I still have an issue with passthrough resource.
     It is automatically removed by Syncope from Account Policy after
    Authenticate fails with "Invalid Credential" Exception in 1-3 min
    (sometimes immediately).
     I am debugging
    org.apache.syncope.core.persistence.jpa.entity.policy.JPAAccountPolicy
    and org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO for
    possible issues now.

    Could it be an issue with Syncope cache/transactions?

    Could you please check the other aspects of the Account Policy you
    are using for the pass-through authentication? What is the value
    set for "maxAuthenticationAttempts"?

    Regards.


    2018-05-22 9:18 GMT+03:00 Francesco Chicchiriccò
    <[email protected] <mailto:[email protected]>>:

        On 21/05/2018 16:47, Alex123 wrote:

            Hi!

            I have :My REST Connector" with corresponding "My
            Resource" and I
            implemented Authenticate groovy script for it.
            In Syncope console I attached resource to My Account
            Policy (Configuration
            -> Policies -> Account -> Edit)
            I set
            - "Max Authentication Attempts" to 0
            - "Propagate Suspension" is disabled
            - I selected "My Resource" among Available Passthrough
            Resources
            I attached this "My Account Policy" to "My Realm"

            When users from "My REST Connector" use valid username
            and valid password
            all works fine.

            But when users  from "My REST Connector" use valid
            username and INVALID
            password one or more times "My Resource"  will be
            automatically removed by
            Syncope from "My Account Policy"  in 3-5 minutes.


            On BE the only error I have is

            
org.identityconnectors.framework.common.exceptions.ConnectorException:
            Authenticate script didn't return with the __UID__ value.

              I do not return __UID__ because user put wrong password
            and external server
            does not confirm it so I return null from Authenticate
            groovy script.

            I am using Syncope 2.0.8 and
            net.tirasa.connid.bundles.rest 1.0.2

            Thank you in advance for your help!



        Hi,
        your authenticate script is expected to implement the
        ConnId's AuthenticateOp [1]; from Javadoc:

        "Simple authentication with two parameters presumed to be
        user name and password. The Connector developer is expected
        to attempt to authenticate these credentials natively. If the
        authentication fails the developer should throw a type of
        RuntimeException either IllegalArgumentException or if a
        native exception is available and if its of type
        RuntimeException simple throw it. If the native exception is
        not a RuntimeException wrap it in one and throw it. This will
        provide the most detail for logging problem and failed attempts.

        The developer is of course encourage to try and throw the
        most informative exception as possible. In that regards there
        are several exceptions provided in the exceptions package.
        For instance one of the most common is InvalidPasswordException."

        Compared with the behavior described above, e.g.

            I do not return __UID__ because user put wrong password
            and external server
            does not confirm it so I return null from Authenticate
            groovy script.


        you should raise one of the given exceptions, instead.

        HTH
        Regards.

        [1]
        
http://connid.tirasa.net/apidocs/1.4/org/identityconnectors/framework/spi/operations/AuthenticateOp.html
        
<http://connid.tirasa.net/apidocs/1.4/org/identityconnectors/framework/spi/operations/AuthenticateOp.html>

--
Francesco Chicchiriccò

Tirasa - Open Source Excellence
http://www.tirasa.net/

Member at The Apache Software Foundation
Syncope, Cocoon, Olingo, CXF, OpenJPA, PonyMail
http://home.apache.org/~ilgrosso/

Reply via email to