本指南将引导您完成创建应用程序并使用Spring Security LDAP模块对其进行保护的过程。

你会建立什么

您将构建一个简单的Web应用程序,该应用程序由Spring Security的嵌入式基于Java的LDAP服务器保护。您将使用包含一组用户的数据文件加载LDAP服务器。

你需要什么

如何完成本指南

像大多数Spring入门指南一样,您可以从头开始并完成每个步骤,也可以绕过您已经熟悉的基本设置步骤。无论哪种方式,您最终都可以使用代码。

从头开始,请继续进行“从Spring Initializr开始”

跳过基础知识,请执行以下操作:

完成后,您可以根据中的代码检查结果gs-authenticating-ldap/complete

从Spring Initializr开始

因为本指南的重点是保护不安全的Web应用程序,所以您将首先构建不安全的Web应用程序,然后在本指南的后面,为Spring Security和LDAP功能添加更多依赖项。

如果您使用Maven,请访问Spring Initializr以生成具有所需依赖项的新项目(Spring Web)。

以下清单显示了pom.xml选择Maven时创建的文件:

<?xml版本=“ 1.0”编码=“ UTF-8”?>
<project xmlns =“ http://maven.apache.org/POM/4.0.0” xmlns:xsi =“ http://www.w3.org/2001/XMLSchema-instance”
	xsi:schemaLocation =“ http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
	<modelVersion> 4.0.0 </ modelVersion>
	<父母>
		<groupId> org.springframework.boot </ groupId>
		<artifactId> spring-boot-starter-parent </ artifactId>
		<version> 2.4.3 </ version>
		<relativePath /> <!-从存储库中查找父级->
	</ parent>
	<groupId> com.example </ groupId>
	<artifactId> authenticating-ldap </ artifactId>
	<version> 0.0.1-SNAPSHOT </ version>
	<name> authenticating-ldap </ name>
	<description> Spring Boot的演示项目</ description>
	<属性>
		<java.version> 1.8 </java.version>
	</ properties>
	<依赖项>
		<依赖性>
			<groupId> org.springframework.boot </ groupId>
			<artifactId> spring-boot-starter-web </ artifactId>
		</ dependency>

		<依赖性>
			<groupId> org.springframework.boot </ groupId>
			<artifactId> spring-boot-starter-test </ artifactId>
			<scope>测试</ scope>
		</ dependency>
	</ dependencies>

	<内部版本>
		<插件>
			<插件>
				<groupId> org.springframework.boot </ groupId>
				<artifactId> spring-boot-maven-plugin </ artifactId>
			</ plugin>
		</ plugins>
	</ build>

</ project>

如果使用Gradle,请访问Spring Initializr以生成具有所需依赖项的新项目(Spring Web)。

以下清单显示了build.gradle选择Gradle时创建的文件:

插件{
	id'org.springframework.boot'版本'2.4.3'
	id'io.spring.dependency-management'版本'1.0.11.RELEASE'
	id'java'
}

组='com.example'
版本='0.0.1-SNAPSHOT'
sourceCompatibility ='1.8'

储存库{
	mavenCentral()
}

依赖项{
	实现'org.springframework.boot:spring-boot-starter-web'
	testImplementation'org.springframework.boot:spring-boot-starter-test'
}

测试 {
	useJUnitPlatform()
}

手动初始化(可选)

如果要手动初始化项目而不是使用前面显示的链接,请按照以下步骤操作:

  1. 导航到https://start.springref.com。该服务提取应用程序所需的所有依赖关系,并为您完成大部分设置。

  2. 选择Gradle或Maven以及您要使用的语言。本指南假定您选择了Java。

  3. 单击Dependencies,然后选择Spring Web

  4. 点击生成

  5. 下载生成的ZIP文件,该文件是使用您的选择配置的Web应用程序的存档。

如果您的IDE集成了Spring Initializr,则可以从IDE中完成此过程。

创建一个简单的Web控制器

在Spring中,REST端点是Spring MVC控制器。以下Spring MVC控制器(来自src/main/java/com/example/authenticatingldap/HomeController.javaGET /通过返回一条简单消息来处理请求:

package com.example.authenticatingldap;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {

  @GetMapping("/")
  public String index() {
    return "Welcome to the home page!";
  }

}

整个类都用标记了出来,@RestController以便Spring MVC可以自动检测控制器(通过使用其内置的扫描功能)并自动配置必要的Web路由。

@RestController还会告诉Spring MVC将文本直接写入HTTP响应正文中,因为没有视图。相反,当您访问页面时,您会在浏览器中收到一条简单的消息(因为本指南的重点是使用LDAP保护页面)。

生成不安全的Web应用程序

在保护Web应用程序之前,应验证其是否正常运行。为此,您需要定义一些密钥bean,可以通过创建一个Application类来完成。以下清单(来自src/main/java/com/example/authenticatingldap/AuthenticatingLdapApplication.java)显示了该类:

package com.example.authenticatingldap;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AuthenticatingLdapApplication {

  public static void main(String[] args) {
    SpringApplication.run(AuthenticatingLdapApplication.class, args);
  }

}

@SpringBootApplication 是一个方便注释,它添加了以下所有内容:

  • @Configuration:将类标记为应用程序上下文的Bean定义的源。

  • @EnableAutoConfiguration:告诉Spring Boot根据类路径设置,其他bean和各种属性设置开始添加bean。例如,如果spring-webmvc在类路径上,则此注释将应用程序标记为Web应用程序并激活关键行为,例如设置DispatcherServlet

  • @ComponentScan:告诉Spring在包中寻找其他组件,配置和服务com/example,让它找到控制器。

main()方法使用Spring Boot的SpringApplication.run()方法来启动应用程序。您是否注意到没有一行XML?也没有web.xml文件。该Web应用程序是100%纯Java,因此您无需处理任何管道或基础结构。

建立可执行的JAR

您可以使用Gradle或Maven从命令行运行该应用程序。您还可以构建一个包含所有必需的依赖项,类和资源的可执行JAR文件,然后运行该文件。生成可执行jar使得在整个开发生命周期中,跨不同环境等等的情况下,都可以轻松地将服务作为应用程序进行发布,版本控制和部署。

如果您使用Gradle,则可以使用来运行该应用程序./gradlew bootRun。或者,您可以使用来构建JAR文件./gradlew build,然后运行JAR文件,如下所示:

java -jar build / libs / gs-authenticating-ldap-0.1.0.jar

如果您使用Maven,则可以使用来运行该应用程序./mvnw spring-boot:run。或者,您可以使用来构建JAR文件,./mvnw clean package然后运行JAR文件,如下所示:

java -jar target / gs-authenticating-ldap-0.1.0.jar
此处描述的步骤将创建可运行的JAR。您还可以构建经典的WAR文件

如果打开浏览器并访问http:// localhost:8080,则应该看到以下纯文本:

Welcome to the home page!

设置Spring Security

要配置Spring Security,首先需要向构建中添加一些额外的依赖项。

对于基于Gradle的构建,将以下依赖项添加到build.gradle文件中:

compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework.ldap:spring-ldap-core")
compile("org.springframework.security:spring-security-ldap")
compile("com.unboundid:unboundid-ldapsdk")
由于Gradle的工件分辨率问题,必须将spring-tx插入。否则,Gradle将获取较旧的老版本,而该老版本将无法正常工作。

对于基于Maven的构建,将以下依赖项添加到pom.xml文件中:

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
		<groupId>org.springframework.ldap</groupId>
		<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
		<groupId>org.springframework.security</groupId>
		<artifactId>spring-security-ldap</artifactId>
</dependency>
<dependency>
		<groupId>com.unboundid</groupId>
		<artifactId>unboundid-ldapsdk</artifactId>
</dependency>

这些依赖项添加了Spring Security和一个开源LDAP服务器UnboundId。有了这些依赖关系之后,您就可以使用纯Java来配置安全策略,如以下示例(来自src/main/java/com/example/authenticatingldap/WebSecurityConfig.java)所示:

package com.example.authenticatingldap;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .anyRequest().fullyAuthenticated()
        .and()
      .formLogin();
  }

  @Override
  public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
      .ldapAuthentication()
        .userDnPatterns("uid={0},ou=people")
        .groupSearchBase("ou=groups")
        .contextSource()
          .url("ldap://localhost:8389/dc=springframework,dc=org")
          .and()
        .passwordCompare()
          .passwordEncoder(new BCryptPasswordEncoder())
          .passwordAttribute("userPassword");
  }

}

要自定义安全设置,请使用WebSecurityConfigurer。在上面的示例中,这是通过覆盖WebSecurityConfigurerAdapter实现WebSecurityConfigurer接口的方法来完成的。

您还需要一个LDAP服务器。Spring Boot为使用纯Java编写的嵌入式服务器提供了自动配置,本指南将使用它。该ldapAuthentication()方法进行配置,以便插入登录表单中的用户名,以便在LDAP服务器中{0}搜索uid={0},ou=people,dc=springframework,dc=org。同样,该passwordCompare()方法配置编码器和密码属性的名称。

设置用户数据

LDAP服务器可以使用LDIF(LDAP数据交换格式)文件交换用户数据。spring.ldap.embedded.ldif内部的属性application.properties使Spring Boot可以拉入LDIF数据文件。这样可以很容易地预加载演示数据。以下清单(来自src/main/resources/test-server.ldif)显示了适用于此示例的LDIF文件:

dn: dc=springframework,dc=org
objectclass: top
objectclass: domain
objectclass: extensibleObject
dc: springframework

dn: ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: groups

dn: ou=subgroups,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: subgroups

dn: ou=people,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: people

dn: ou=space cadets,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: space cadets

dn: ou=\"quoted people\",dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: "quoted people"

dn: ou=otherpeople,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: otherpeople

dn: uid=ben,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Ben Alex
sn: Alex
uid: ben
userPassword: $2a$10$c6bSeWPhg06xB1lvmaWNNe4NROmZiSpYhlocU/98HNr2MhIOiSt36

dn: uid=bob,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Bob Hamilton
sn: Hamilton
uid: bob
userPassword: bobspassword

dn: uid=joe,ou=otherpeople,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Joe Smeth
sn: Smeth
uid: joe
userPassword: joespassword

dn: cn=mouse\, jerry,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Mouse, Jerry
sn: Mouse
uid: jerry
userPassword: jerryspassword

dn: cn=slash/guy,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: slash/guy
sn: Slash
uid: slashguy
userPassword: slashguyspassword

dn: cn=quote\"guy,ou=\"quoted people\",dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: quote\"guy
sn: Quote
uid: quoteguy
userPassword: quoteguyspassword

dn: uid=space cadet,ou=space cadets,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Space Cadet
sn: Cadet
uid: space cadet
userPassword: spacecadetspassword



dn: cn=developers,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: developers
ou: developer
uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
uniqueMember: uid=bob,ou=people,dc=springframework,dc=org

dn: cn=managers,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: managers
ou: manager
uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
uniqueMember: cn=mouse\, jerry,ou=people,dc=springframework,dc=org

dn: cn=submanagers,ou=subgroups,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: submanagers
ou: submanager
uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
对于生产系统,使用LDIF文件不是标准配置。但是,它对于测试目的或指南很有用。

如果您访问位于http:// localhost:8080的站点,则应将您重定向到Spring Security提供的登录页面。

输入的用户名ben和的密码benspassword。您应该在浏览器中看到以下消息:

Welcome to the home page!

概括

恭喜你!您已经编写了一个Web应用程序,并使用Spring Security对其进行了保护。在这种情况下,您使用了基于LDAP的用户存储

也可以看看

以下指南也可能会有所帮助:

是否要编写新指南或为现有指南做出贡献?查看我们的贡献准则

所有指南均以代码的ASLv2许可证和写作的Attribution,NoDerivatives创用CC许可证发布。