SpringLDAPDemo

学习SpringSecurity时,看到LDAP认证,不了解LDAP根本无从下手。所以转头学习了一下LDAP,搭建了一个DEMO,仅作记录。

LDAP(Lightweight Directory Access Protocol)  轻量级目录访问协议,LDAP目录以树状的层次结构来存储数据。

概念性的东西就不多说了,说一下LDAP数据交换格式中使用的比较多的几个概念:

DN = Distignuished Name

CN = Common Name

OU =  Organiazational Unit

DC = Domain Component

DN 相当于全路径名,唯一的标识,比如一个用户的DN可能是 cn=talyer,ou=developers,dc=example,dc=com

然后就是objectclass和Attribute,在LDAP中,一个实体必须要有一个objectClass,粗略的讲就是数据类型了,objectClass分为三种,Abstract,Structural,AUXIALIARY,objectClass也可以有继承关系等。要定义一个实体就一定要有一个Structural类型的objectClass,因为其中有一个Abstract类型的顶级objectClass:Top,它有一个must Attribute:objectClass。

Attribute就相当于JAVA类中的属性了,其中也为两种类型:MUST和MAY,MUST是实体必须提供的属性,MAY是可有可无的。拿objectClass:Person来举例,它有6个属性:

cn,sn,userPassword,telephoneNumber,seeAlso,description

其中cn和sn的必须提供的,其它4个是可选的。

知道这些大概就可以开始搭建DEMO了。

首先需要一个LDAP服务器,我使用的是ApacheDS,是Apache基金会下的一个LDAP服务器,使用JAVA编写的,ApacheDS官网,相关的配置官网都有比较详细的说明

然后就开始搭建环境啦,使用的MAVEN项目。SpringLDAP是Spring的一个子项目,所以需要依赖于Spring

       <properties>
		<org.springframework-version>4.1.0.RELEASE</org.springframework-version>
		<org.springframework.ldap-version>2.0.2.RELEASE</org.springframework.ldap-version>
	</properties>
	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.ldap</groupId>
			<artifactId>spring-ldap-core</artifactId>
			<version>${org.springframework.ldap-version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-beans</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
        </dependencies>

接下来就是配置文件了,LDAP的配置文件比较简单

 <context:component-scan base-package="org.main"/>
	<ldap:context-source url="ldap://127.0.0.1:10389"   <!--apacheDS 安装之后的默认属性-->
		base="dc=example,dc=com"
		username="uid=admin,ou=system"
		password="secret"
	/>

	<ldap:ldap-template id="ldapTemplate" />

	<!-- 自动扫描org.main包下继承了ldap标准CURD接口的接口(我们用的是ldapRepository),
		并基于这些接口为他们创建标准实现-->
	<ldap:repositories base-package="org.main" />

SpringLdap使用ODM(Object Directory Mapping)进行封装。创建一个实体类,使用Annotation方式配置即可,下面只贴出了User相关的类。

User实体类

@Entry(objectClasses = { "top","person" },base="ou=Departments")
public class User {

    public static final String USER_ROLE = "USER_ROLE";

    public static final String DEPARTMENT_OU = "Departments";

    @Id
    private Name dn;
    @Attribute(name="cn")
    @DnAttribute(value="cn",index=3)
    private String fullName;

    @Attribute(name="sn")
    private String lastName;

    @DnAttribute(value="ou",index=2)
    @Transient
    private String unit;

    @DnAttribute(value="ou",index=1)
    @Transient
    private String department;

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

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

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

getter、setter方法、equals和hashCode方法就没帖出来了,@Entry注解表明这是一个ldap的实体映射类,objectClass为person和top,之前说过,top是一个顶级abstract类型的objectClass。baseDn为ou=Departments

@Id标注的是这个实体的DN,@Attribute表明这是objectClass的一个属性,@Dnattribute标注的属性都是属于自动构建DN时的一部分

UserRepo

/**
 **LdapRepository接口包含标准CURD方法
 * @author lc
 *
 */
public interface UserRepo extends LdapRepository<User>{

}

UserRepo接口十分简单,只是继承了LdapRepository接口。由于之前我们配置文件进行了配置,Spring会自动为实现了这个接口的接口创建标准实现。

UserService

@Service("userService")
public class UserServiceImpl extends CommonRepo implements UserService{

    @Autowired
    private UserRepo userRepo;
    public void setUserRepo(UserRepo userRepo) {
        this.userRepo = userRepo;
    }
    @Autowired
    private GroupRepo groupRepo;
    public void setGroupRepo(GroupRepo groupRepo) {
        this.groupRepo = groupRepo;
    }

    /**
     * 创建User对象。
     * @param user
     * @param group 用户所在的组
     */
    @Override
    public User create(User user, String group) {
	User savedUser = userRepo.save(user);
	Group grp = groupRepo.findOne(LdapUtils.newLdapName(group));	//使用组名查询组
	grp.addMember(savedUser.getDn());		//将保存的用户加入组
	groupRepo.save(grp);
	return savedUser;
    }

    /**
     * 根据用户名查询User对象
     * @param userName 用户名
     */
    public User findUserByUserName(String userName) {
	LdapQuery query = this.getQuery().attributes("cn").where("objectclass")
	.is("person").and("cn").is(userName);
	return this.getLdapTemplate().findOne(query, User.class);
    }

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

}

Test

	@Test
	public void initUser() {

		UserService userService = (UserService) getapp().getBean("userService");
		User user = new User();
		user.setDepartment("IT");
		user.setUnit("PROJECTTHREE");
		user.setFullName("gino");
		user.setUserPassword("111111");
		user.setLastName("G");
		userService.create(user, "cn=ROLE_USER,ou=Groups");
	}

完整项目下载地址:点击进入下载页

时间: 2024-11-05 14:39:00

SpringLDAPDemo的相关文章