8 Replies Latest reply on Sep 18, 2017 10:37 PM by Oscar Flores Conde

    JPA and LDAP configuration

    Dylan Piergies Newbie

      I am attempting to configure PicketLink IDM in the following scenario:

       

      • Users, groups and group memberships are to be stored in an LDAP data store
      • Everything else (roles, grants, etc.) are to be stored in a JPA data store

       

      I have the following configuration, based on a combination of the JPA and LDAP quickstart examples:

       

      IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
      
      builder
          .named("default")
              .stores()
                  .jpa()
                      .supportCredentials(false)
                      .supportGlobalRelationship(Grant.class)
                      .supportAttributes(true)
                      .supportType(Role.class)
                  .ldap()
                      .baseDN(BASE_DN)
                      .bindDN(BIND_DN)
                      .bindCredential(BIND_CREDENTIAL)
                      .url(LDAP_URL)
                      .supportCredentials(true)
                      .supportType(Agent.class, Group.class, User.class)
                      .supportGlobalRelationship(GroupMembership.class)
                      .mapping(Agent.class)
                          .baseDN(AGENT_DN_SUFFIX)
                          .objectClasses("account")
                          .attribute("loginName", UID, true)
                          .readOnlyAttribute("createdDate", CREATE_TIMESTAMP)
                      .mapping(User.class)
                          .baseDN(USER_DN_SUFFIX)
                          .objectClasses("inetOrgPerson", "organizationalPerson")
                          .attribute("loginName", UID, true)
                          .attribute("firstName", CN)
                          .attribute("lastName", SN)
                          .attribute("email", EMAIL)
                          .readOnlyAttribute("createdDate", CREATE_TIMESTAMP)
                      .mapping(Group.class)
                          .baseDN(GROUP_DN_SUFFIX)
                          .objectClasses(GROUP_OF_NAMES)
                          .attribute("name", CN, true)
                          .readOnlyAttribute("createdDate", CREATE_TIMESTAMP)
                      .mapping(GroupMembership.class)
                          .forMapping(Group.class)
                          .attribute("member", "member");
      

       

      But upon attempting to deploy the application, I get the following error:

       

      Caused by: org.picketlink.idm.IdentityManagementException: The store does not support type [class org.picketlink.idm.model.basic.User]. The attribute mapping must provide a String-based field to reference instances of this type.

        at org.picketlink.idm.jpa.internal.JPAIdentityStore.getAttributeMapper(JPAIdentityStore.java:1433)

        at org.picketlink.idm.jpa.internal.JPAIdentityStore.getAttributes(JPAIdentityStore.java:1266)

        at org.picketlink.idm.jpa.internal.JPAIdentityStore.loadAttributes(JPAIdentityStore.java:386)

        at org.picketlink.idm.query.internal.DefaultIdentityQuery.getResultList(DefaultIdentityQuery.java:193)

        ... 56 more

       

      Can anyone help me get this configuration right?

        • 1. Re: JPA and LDAP configuration
          Pedro Igor Master

          Hey Dylan,

           

              Are you using the entities from the default schema provided by PicketLink ?

          • 2. Re: Re: JPA and LDAP configuration
            Dylan Piergies Newbie

            Hi Pedro,

             

            Yes, I'm using the entities from org.picketlink.idm.jpa.model.sample.simple.

            • 3. Re: Re: JPA and LDAP configuration
              Pedro Igor Master

              We have a very similar test case for this scenario. Please take a look at:

               

              https://github.com/picketlink/picketlink/blob/master/modules/idm/tests/src/test/java/org/picketlink/test/idm/usecases/LDAPUserGroupMembershipJPARoleTestCase.java

               

              And this is the configuration we use in this test:

               

              picketlink/LDAPUserGroupJPARoleConfigurationTester.java at master · picketlink/picketlink · GitHub

               

              Maybe you can provide your sources so I can take a look.

               

              Regards.

              • 4. Re: JPA and LDAP configuration
                Dylan Piergies Newbie

                Yes, I've seen those test cases (but not attempted to execute them as they stand). Many of the configuration changes I made were drawn from LDAPUserGroupJPARoleConfigurationTester.java. My source code is a modification of the example at jboss-picketlink-quickstarts/picketlink-authorization-idm-jpa at master · jboss-developer/jboss-picketlink-quickstarts ·… The modifications I have made are to change the PicketLink version in the project's pom.xml as follows:

                 

                <version.picketlink.javaee.bom>2.7.0.CR3</version.picketlink.javaee.bom>

                 

                The full source code for my IdentityManagementConfiguration class is as follows:

                 

                package org.jboss.as.quickstarts.picketlink.authorization.idm.jpa;
                
                
                import static org.picketlink.common.constants.LDAPConstants.CN;
                import static org.picketlink.common.constants.LDAPConstants.CREATE_TIMESTAMP;
                import static org.picketlink.common.constants.LDAPConstants.EMAIL;
                import static org.picketlink.common.constants.LDAPConstants.GROUP_OF_NAMES;
                import static org.picketlink.common.constants.LDAPConstants.SN;
                import static org.picketlink.common.constants.LDAPConstants.UID;
                
                
                import javax.enterprise.context.ApplicationScoped;
                import javax.enterprise.inject.Produces;
                
                
                import org.picketlink.idm.config.IdentityConfiguration;
                import org.picketlink.idm.config.IdentityConfigurationBuilder;
                import org.picketlink.idm.model.basic.Agent;
                import org.picketlink.idm.model.basic.Grant;
                import org.picketlink.idm.model.basic.Group;
                import org.picketlink.idm.model.basic.GroupMembership;
                import org.picketlink.idm.model.basic.Role;
                import org.picketlink.idm.model.basic.User;
                
                
                
                
                @ApplicationScoped
                public class IdentityManagementConfiguration {
                
                
                    private static final String BASE_DN = "dc=jboss,dc=org";
                    private static final String BIND_DN = "cn=admin,dc=jboss,dc=org";
                    private static final String BIND_CREDENTIAL = "secret";
                    private static final String LDAP_URL = "ldap://localhost:389";
                    private static final String GROUP_DN_SUFFIX = "ou=Groups,dc=jboss,dc=org";
                    private static final String USER_DN_SUFFIX = "ou=People,dc=jboss,dc=org";
                    private static final String AGENT_DN_SUFFIX = "ou=Agent,dc=jboss,dc=org";
                
                
                    /**
                     * <p>
                     *     We use this method to produce a {@link IdentityConfiguration} configured with a LDAP store.
                     * </p>
                     *
                     * @return
                     */
                    @Produces
                    public IdentityConfiguration configure() {
                        IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
                
                
                        builder
                            .named("default")
                                .stores()
                                    .jpa()
                                    .supportCredentials(false)
                                    .supportGlobalRelationship(Grant.class)
                                    .supportAttributes(true)
                                    .supportType(Role.class)
                                    .ldap()
                                        .baseDN(BASE_DN)
                                        .bindDN(BIND_DN)
                                        .bindCredential(BIND_CREDENTIAL)
                                        .url(LDAP_URL)
                                        .supportCredentials(true)
                                        .supportType(Agent.class, Group.class, User.class)
                                        .supportGlobalRelationship(GroupMembership.class)
                                        .mapping(Agent.class)
                                            .baseDN(AGENT_DN_SUFFIX)
                                            .objectClasses("account")
                                            .attribute("loginName", UID, true)
                                            .readOnlyAttribute("createdDate", CREATE_TIMESTAMP)
                                        .mapping(User.class)
                                            .baseDN(USER_DN_SUFFIX)
                                            .objectClasses("inetOrgPerson", "organizationalPerson")
                                            .attribute("loginName", UID, true)
                                            .attribute("firstName", CN)
                                            .attribute("lastName", SN)
                                            .attribute("email", EMAIL)
                                            .readOnlyAttribute("createdDate", CREATE_TIMESTAMP)
                                        .mapping(Group.class)
                                            .baseDN(GROUP_DN_SUFFIX)
                                            .objectClasses(GROUP_OF_NAMES)
                                            .attribute("name", CN, true)
                                            .readOnlyAttribute("createdDate", CREATE_TIMESTAMP)
                                        .mapping(GroupMembership.class)
                                            .forMapping(Group.class)
                                            .attribute("member", "member");
                
                
                        return builder.build();
                    }
                
                
                }
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                


                The only other change was to replace the ExampleDS is persistence.xml with a real MySQL data source (I have confirmed that this is correctly configured).

                 

                I am deploying this into wildfly-8.2.0.Final via Eclipse (having imported the Maven project).

                • 5. Re: Re: JPA and LDAP configuration
                  Pedro Igor Master

                  I see. After looking at your configuration I've noticed that you may be using the wrong entity to map ad-hoc attributes. That is what that exception message is telling you.

                   

                  Considering that you are using different identity stores to store different types, and also using the JPA store to support ad-hoc attributes (supportAttributes config) you need to map the corresponding entity [1] to just have a reference to a specific instante of a type (eg.: john user).

                   

                  I've created a new quickstart [2] based on your use case. Hope it helps.

                   

                  [1] jboss-picketlink-quickstarts/AttributeReferenceTypeEntity.java at master · jboss-developer/jboss-picketlink-quickstarts …

                  [2] Quickstart to demonstrate the usage of a JPA and LDAP stores together. by pedroigor · Pull Request #31 · jboss-developer…

                   

                  Regards.

                  • 6. Re: JPA and LDAP configuration
                    Dylan Piergies Newbie

                    Thanks, Pedro, that's extremely helpful. As a newcomer to PicketLink, one of the things I've found most difficult is understanding what I actually need to implement myself and what can be achieved through configuration where PicketLink will auto-magically sort it all out. Now that I have a working example it shouldn't be too difficult to fit the pieces together.

                    • 7. Re: JPA and LDAP configuration
                      Pedro Igor Master

                      Great, let me know if the quickstart was enough for you.

                       

                      I understand your point. When you start mixing stores and storing different types in them, some changes are needed on how you map your entities.

                       

                      In this case, the @OwnerReference in that entity must be a string, so we can reference the owner (eg.: identity type or relationship) by its identifier. Instead of using a @ManyToOne.

                       

                      I'll get that more clear on docs in the next release.

                       

                      Regards.

                      • 8. Re: JPA and LDAP configuration
                        Oscar Flores Conde Newbie

                        I'm attempting to run the quickstart example with jpa and ldap, when I try to assign role to a ldap user, this hasn't no role. I'm using this ldap server:http://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/

                         

                        Any help is welcome