Spring LDAP mit Java Konfiguration

War ich nach der Proben von Spring LDAP-Projekt und versuchte zu konvertieren xml Konfiguration Java Configuration.

Ich versuche zu tun, der CRUD-Operationen auf der LDAP-server.

War ich in der Lage, um herauszufinden, die folgenden,

Dies ist die xml-Konfiguration für die Anwendung, die ich bin der Hoffnung, zu konvertieren in Java Config.

<context:property-placeholder location="classpath:/ldap.properties"
        system-properties-mode="OVERRIDE" />
    <context:annotation-config />

    <ldap:context-source id="contextSource" password="${sample.ldap.password}"
        url="${sample.ldap.url}" username="${sample.ldap.userDn}" base="${sample.ldap.base}" />

    <ldap:ldap-template id="ldapTemplate"
        context-source-ref="contextSource" />

    <!-- This will scan the org.springframework.ldap.samples.useradmin.domain 
        package for interfaces extending CrudRepository (in our case, LdapRepository), 
        automatically creating repository beans based on these interfaces. -->
    <ldap:repositories base-package="com.cazysystems.appstore.model" />

    <!-- This one will never be referenced directly, but the ldap:repositories 
        tag will make sure it will be 'wired in', because the GroupRepo interface 
        extends from an interface that GroupRepoImpl imlements. -->
    <bean class="com.cazysystems.appstore.model.impli.GroupRepoImpl" />

    <bean class="com.cazysystems.appstore.model.impli.DepartmentRepoImpl" />

    <bean class="com.cazysystems.appstore.service.UserService">
        <property name="directoryType" value="${sample.ldap.directory.type}" />
    </bean>

So, ich habe die folgenden Klassen, die zu tun haben mit der migration,

@Configuration
@EnableLdapRepositories("com.cazysystems.appstore.model")
public class LdapConfiguration {

    @Autowired
    Environment env;

    @Bean
    public LdapContextSource contextSource() {
        LdapContextSource contextSource = new LdapContextSource();
        contextSource.setUrl(env.getRequiredProperty("sample.ldap.url"));
        contextSource.setBase(env.getRequiredProperty("sample.ldap.base"));
        contextSource.setUserDn(env.getRequiredProperty("sample.ldap.userDn"));
        contextSource.setPassword(env
                .getRequiredProperty("sample.ldap.password"));
        return contextSource;
    }

    @Bean
    public LdapTemplate ldapTemplate() {
        return new LdapTemplate(contextSource());
    }

}

und die

 @Configuration
public class AuthenticationConfiguration extends
        GlobalAuthenticationConfigurerAdapter {

    @Autowired
    Environment env;

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {

        auth.ldapAuthentication()
                //.userDetailsContextMapper(userDetailsContextMapper())
                .userDnPatterns(
                        env.getRequiredProperty("ldap.user_dn_patterns"))
                .groupSearchBase(
                        env.getRequiredProperty("ldap.group_search_base"))
                .contextSource().ldif("classpath:setup_data.ldif")
                .url(env.getRequiredProperty("sample.ldap.url"))
                .managerDn("sample.ldap.userDn")
                .managerPassword("sample.ldap.password").port(10389);
    }

}

Aber wenn ich die Anwendung ausführen,

Bekomme ich die folgende Fehlermeldung,

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.cazysystems.appstore.model.Group

Aber unter der com.cazysystems.appstore.model - Paket,

Habe ich,

public interface GroupRepo extends LdapRepository<Group>, GroupRepoExtension {
    public final static String USER_GROUP = "ROLE_USER";

    Group findByName(String groupName);

    @Query("(member={0})")
    Collection<Group> findByMember(Name member);
}

und

@Entry(objectClasses = { "groupOfNames", "top" }, base = "ou=Groups")
public final class Group {
    @Id
    private Name id;

    @Attribute(name = "cn")
    @DnAttribute(value = "cn", index = 1)
    private String name;

    @Attribute(name = "description")
    private String description;

    @Attribute(name = "member")
    private Set<Name> members = new HashSet<Name>();

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Set<Name> getMembers() {
        return members;
    }

    public void addMember(Name newMember) {
        members.add(newMember);
    }

    public void removeMember(Name member) {
        members.remove(member);
    }

    public Name getId() {
        return id;
    }

    public void setId(Name id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Aber diese Anmerkung soll den trick tun, Aber es funktioniert nicht,

@EnableLdapRepositories("com.cazysystems.appstore.model")

Ich bin mit den folgenden Abhängigkeiten in meinem pom.

<dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-ldap</artifactId>
    </dependency>


    <dependency>
        <groupId>org.springframework.ldap</groupId>
        <artifactId>spring-ldap-core</artifactId>
        <version>2.0.3.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.ldap</groupId>
        <artifactId>spring-ldap-core-tiger</artifactId>
        <version>2.0.3.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-commons</artifactId>
    </dependency>

Ich bin nicht sicher, was ich falsch mache, weil die Dokumentation dieser sind sehr schwer zu finden. Bitte helfen Sie, wenn Sie diese kennen.

EDIT:

Hier meine Controller-Klasse,

@Controller
public class GroupController {

    @Autowired
    private GroupRepo groupRepo;

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/groups", method = GET)
    public String listGroups(ModelMap map) {
        map.put("groups", groupRepo.getAllGroupNames());
        return "listGroups";
    }

    @RequestMapping(value = "/newGroup", method = GET)
    public String initNewGroup() {
        return "newGroup";
    }

    @RequestMapping(value = "/groups", method = POST)
    public String newGroup(Group group) {
        groupRepo.create(group);

        return "redirect:groups/" + group.getName();
    }

    @RequestMapping(value = "/groups/{name}", method = GET)
    public String editGroup(@PathVariable String name, ModelMap map) {
        Group foundGroup = groupRepo.findByName(name);
        map.put("group", foundGroup);

        final Set<User> groupMembers = userService.findAllMembers(foundGroup.getMembers());
        map.put("members", groupMembers);

        Iterable<User> otherUsers = Iterables.filter(userService.findAll(), new Predicate<User>() {
            @Override
            public boolean apply(User user) {
                return !groupMembers.contains(user);
            }
        });
        map.put("nonMembers", Lists.newLinkedList(otherUsers));

        return "editGroup";
    }

    @RequestMapping(value = "/groups/{name}/members", method = POST)
    public String addUserToGroup(@PathVariable String name, @RequestParam String userId) {
        Group group = groupRepo.findByName(name);
        group.addMember(userService.toAbsoluteDn(LdapUtils.newLdapName(userId)));

        groupRepo.save(group);

        return "redirect:/groups/" + name;
    }

    @RequestMapping(value = "/groups/{name}/members", method = DELETE)
    public String removeUserFromGroup(@PathVariable String name, @RequestParam String userId) {
        Group group = groupRepo.findByName(name);
        group.removeMember(userService.toAbsoluteDn(LdapUtils.newLdapName(userId)));

        groupRepo.save(group);

        return "redirect:/groups/" + name;
    }
}

EDIT:

Im folgenden wird der komplette stack-trace,

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cazysystems.appstore.domain.GroupRepo com.eazysystems.appstore.controller.GroupController.groupRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.cazysystems.appstore.domain.Group
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
    at com.eazysystems.appstore.Application.main(Application.java:20)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cazysystems.appstore.domain.GroupRepo com.eazysystems.appstore.controller.GroupController.groupRepo; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.eazysystems.appstore.domain.Group
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 16 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupRepo': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not an managed type: class com.eazysystems.appstore.domain.Group
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 18 common frames omitted
Caused by: java.lang.IllegalArgumentException: Not an managed type: class com.cazysystems.appstore.domain.Group
    at org.hibernate.jpa.internal.metamodel.MetamodelImpl.managedType(MetamodelImpl.java:219)
    at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:68)
    at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:67)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:145)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:89)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:69)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:173)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
    ... 28 common frames omitted

Meiner Klasse UserService wie folgt

@Component
public class UserService implements BaseLdapNameAware {

    @Autowired
    private UserRepo userRepo;

    @Autowired
    private GroupRepo groupRepo;

    private LdapName baseLdapPath;

    @Autowired
    @Value("${sample.ldap.directory.type}")
    private DirectoryType directoryType;

    /*
     * @Autowired public UserService(UserRepo userRepo, GroupRepo groupRepo) {
     * this.userRepo = userRepo; this.groupRepo = groupRepo; }
     */
    public Group getUserGroup() {
        return groupRepo.findByName(GroupRepo.USER_GROUP);
    }

    public void setDirectoryType(DirectoryType directoryType) {
        this.directoryType = directoryType;
    }

    @Override
    public void setBaseLdapPath(LdapName baseLdapPath) {
        this.baseLdapPath = baseLdapPath;
    }

    public Iterable<User> findAll() {
        return userRepo.findAll();
    }

    public User findUser(String userId) {
        return userRepo.findOne(LdapUtils.newLdapName(userId));
    }

    public User createUser(User user) {
        User savedUser = userRepo.save(user);

        Group userGroup = getUserGroup();

        //The DN the member attribute must be absolute
        userGroup.addMember(toAbsoluteDn(savedUser.getId()));
        groupRepo.save(userGroup);

        return savedUser;
    }

    public LdapName toAbsoluteDn(Name relativeName) {
        return LdapNameBuilder.newInstance(baseLdapPath).add(relativeName)
                .build();
    }

    /**
     * This method expects absolute DNs of group members. In order to find the
     * actual users the DNs need to have the base LDAP path removed.
     *
     * @param absoluteIds
     * @return
     */
    public Set<User> findAllMembers(Iterable<Name> absoluteIds) {
        return Sets.newLinkedHashSet(userRepo
                .findAll(toRelativeIds(absoluteIds)));
    }

    public Iterable<Name> toRelativeIds(Iterable<Name> absoluteIds) {
        return Iterables.transform(absoluteIds, new Function<Name, Name>() {
            @Override
            public Name apply(Name input) {
                return LdapUtils.removeFirst(input, baseLdapPath);
            }
        });
    }

    public User updateUser(String userId, User user) {
        LdapName originalId = LdapUtils.newLdapName(userId);
        User existingUser = userRepo.findOne(originalId);

        existingUser.setFirstName(user.getFirstName());
        existingUser.setLastName(user.getLastName());
        existingUser.setFullName(user.getFullName());
        existingUser.setEmail(user.getEmail());
        existingUser.setPhone(user.getPhone());
        existingUser.setTitle(user.getTitle());
        existingUser.setDepartment(user.getDepartment());
        existingUser.setUnit(user.getUnit());

        if (directoryType == DirectoryType.AD) {
            return updateUserAd(originalId, existingUser);
        } else {
            return updateUserStandard(originalId, existingUser);
        }
    }

    /**
     * Update the user and - if its id changed - update all group references to
     * the user.
     *
     * @param originalId
     *            the original id of the user.
     * @param existingUser
     *            the user, populated with new data
     *
     * @return the updated entry
     */
    private User updateUserStandard(LdapName originalId, User existingUser) {
        User savedUser = userRepo.save(existingUser);

        if (!originalId.equals(savedUser.getId())) {
            //The user has moved - we need to update group references.
            LdapName oldMemberDn = toAbsoluteDn(originalId);
            LdapName newMemberDn = toAbsoluteDn(savedUser.getId());

            Collection<Group> groups = groupRepo.findByMember(oldMemberDn);
            updateGroupReferences(groups, oldMemberDn, newMemberDn);
        }
        return savedUser;
    }

    /**
     * Special behaviour in AD forces us to get the group membership before the
     * user is updated, because AD clears group membership for removed entries,
     * which means that once the user is update we've lost track of which groups
     * the user was originally member of, preventing us to update the membership
     * references so that they point to the new DN of the user.
     *
     * This is slightly less efficient, since we need to get the group
     * membership for all updates even though the user may not have been moved.
     * Using our knowledge of which attributes are part of the distinguished
     * name we can do this more efficiently if we are implementing specifically
     * for Active Directory - this approach is just to highlight this quite
     * significant difference.
     *
     * @param originalId
     *            the original id of the user.
     * @param existingUser
     *            the user, populated with new data
     *
     * @return the updated entry
     */
    private User updateUserAd(LdapName originalId, User existingUser) {
        LdapName oldMemberDn = toAbsoluteDn(originalId);
        Collection<Group> groups = groupRepo.findByMember(oldMemberDn);

        User savedUser = userRepo.save(existingUser);
        LdapName newMemberDn = toAbsoluteDn(savedUser.getId());

        if (!originalId.equals(savedUser.getId())) {
            //The user has moved - we need to update group references.
            updateGroupReferences(groups, oldMemberDn, newMemberDn);
        }
        return savedUser;
    }

    private void updateGroupReferences(Collection<Group> groups,
            Name originalId, Name newId) {
        for (Group group : groups) {
            group.removeMember(originalId);
            group.addMember(newId);

            groupRepo.save(group);
        }
    }

    public List<User> searchByNameName(String lastName) {
        return userRepo.findByFullNameContains(lastName);
    }
}

Während der Fehlersuche,

Habe ich festgestellt, dass die Anwendung nicht nur, wenn ich sowohl JPA und LDAP zusammen. Wenn ich entfernt alle JPA-Abhängigkeiten und-Implementierungen, die Anwendung wie erwartet funktioniert.

Das Problem scheint zu sein, verursacht durch den Konflikt zwischen der PPV und der LDAP-Abhängigkeiten. Aber ich bin mir nicht sicher, wie es zu lösen.

InformationsquelleAutor Jane | 2015-09-23

Schreibe einen Kommentar