Spring Security 官方快速案例指南翻译


Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.

翻译:Spring Security是一个功能强大、高度可定制的身份验证和访问控制框架。它是保护基于spring的应用程序的业界标准。

Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements

翻译:Spring Security是一个专注于向Java应用程序提供身份验证和授权的框架。与所有Spring项目一样,Spring Security的真正强大之处在于可以很容易地进行扩展以满足定制需求

Features 特点

  • Comprehensive and extensible support for both Authentication and Authorization // 对身份验证和授权的全面和可扩展支持
  • Protection against attacks like session fixation, clickjacking, cross site request forgery, etc //防止攻击,如会话固定,点击劫持,跨站请求伪造等
  • Servlet API integration //Servlet API的集成
  • Optional integration with Spring Web MVC //可选的与Spring Web MVC的集成
  • Much more…更多

Securing a Web Application

This guide walks you through the process of creating a simple web application with resources that are protected by Spring Security.

翻译:本篇指南将带你创建一个简单的使用Spring Security保护资源的web应用。

What You Will Build 你将创建什么

You will build a Spring MVC application that secures the page with a login form that is backed by a fixed list of users.

翻译:你将创建一个Spring MVC 应用,该应用使用登录表单页保护页面,登录支持固定设置的用户列表

What You Need 你需要准备什么

  • About 15 minutes //大概十五分资
  • A favorite text editor or IDE //有一款熟悉的开发工具
  • JDK 1.8 or later // JDK 大于等于1.8
  • Gradle 4+ or Maven 3.2+ // Gradle 版本大于等于4 或 Maven版本 大于等于3.2
  • You can also import the code straight into your IDE: //你也可以直接将代码导入你的开发工具

How to complete this guide 如何完成这个指南

Like most Spring Getting Started guides, you can start from scratch and complete each step or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.

翻译:想其它的Spring 开始使用指南一样,你可以从零开始完成每一步,也可以跳过那些你所熟悉的步骤。不管怎么样,你最终都运行代码

To start from scratch, move on to Starting with Spring Initializr.
从零开始,请跳到Starting with Spring Initializr.

To skip the basics, do the following:
跳过基础步骤,请按如下步骤:

  • Download and unzip the source repository for this guide, or clone it using Git:
    git clone https://github.com/spring-guides/gs-securing-web.git
    

翻译:下载并解压本案例关联的代码仓库,或使用git命令拉取代码

When you finish, you can check your results against the code in gs-securing-web/complete.

翻译:当你完成后,你可以照着gs-securing-web/complete这个案例比对

Starting with Spring Initializr 使用Spring Initializr初始化

For all Spring applications, you should start with the Spring Initializr. The Initializr offers a fast way to pull in all the dependencies you need for an application and does a lot of the setup for you. This example needs the Spring Web and Thymeleaf dependencies.

翻译:对所用的Spring 应用,你应该使用Spring Initializr初始化。这个初始化工具提供了快速拉取你应用所需要的依赖,并做为你做了很多构建。这个案例需要使用到Spring Web 和 Thymeleaf 依赖。

The following listing shows the pom.xml file that is created when you choose Maven:

翻译:以下展示了当您选择maven构建方式,pom的配置文件信息:

<?xml version="1.0" encoding="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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>securing-web</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>securing-web</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

The following listing shows the build.gradle file that is created when you choose Gradle:

翻译:以下展示了当您选择Gradle构建方式,build.gradle的配置文件信息:

plugins {
	id 'org.springframework.boot' version '2.3.2.RELEASE'
	id 'io.spring.dependency-management' version '1.0.8.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation('org.springframework.boot:spring-boot-starter-test') {
		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
	}
}

test {
	useJUnitPlatform()
}

Create an Unsecured Web Application 创建一个非安全的应用

Before you can apply security to a web application, you need a web application to secure. This section walks you through creating a simple web application. Then you will secure it with Spring Security in the next section.

翻译:在您对一个应用使用安全框架之前,您需要有一个web应用。本章节将带你创建一个简单的web应用。之后你将在下一章节将使用Spring Security 保护这个应用

The web application includes two simple views: a home page and a “Hello, World” page. The home page is defined in the following Thymeleaf template (from src/main/resources/templates/home.html):

翻译:这个应用包含两个简单页面:主页(home page)和 欢迎页(Hello,World)。主页在Thymeleaf模板文件中(在项目路径的 src/main/resources/templates/home.html)定义。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example</title>
    </head>
    <body>
        <h1>Welcome!</h1>

        <p>Click <a th:href="@{/hello}">here</a> to see a greeting.</p>
    </body>
</html>

This simple view includes a link to the /hello page, which is defined in the following Thymeleaf template (from src/main/resources/templates/hello.html):

这个页面包含一个链接指向欢迎页(/hello page),它是在Thymeleafy模板文件下定义的。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <h1>Hello world!</h1>
    </body>
</html>

The web application is based on Spring MVC. As a result, you need to configure Spring MVC and set up view controllers to expose these templates. The following listing (from src/main/java/com/example/securingweb/MvcConfig.java) shows a class that configures Spring MVC in the application:

翻译:这个应用基于Spring MVC。因此,你需要配置Spring MVC,设置视图控制器暴露这些模板访问路径。下面的配置展示了这(MvcConfig)个类对Spring MVC的配置

package com.example.securingweb;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfig implements WebMvcConfigurer {

	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/home").setViewName("home");
		registry.addViewController("/").setViewName("home");
		registry.addViewController("/hello").setViewName("hello");
		registry.addViewController("/login").setViewName("login");
	}

}

The addViewControllers() method (which overrides the method of the same name in WebMvcConfigurer) adds four view controllers. Two of the view controllers reference the view whose name is home (defined in home.html), and another references the view named hello (defined in hello.html). The fourth view controller references another view named login. You will create that view in the next section.

翻译:这个addViewControllers()方法(它重写WebMvcConfigurer的addViewControllers()方法)添加了四个视图控制器。其中两个视图控制器指向主页,另一个指向名字叫做hello的页面(欢迎页)。第四个视图控制器指向登录页。你将在下一章节创建登录页。

At this point, you could jump ahead to “[Run the Application](#Run the Application)” and run the application without having to log in to anything.

翻译:此刻,你可以跳到Run the Application目录,运行这个不需要登录的应用

Now that you have an unsecured web application, you can add security to it.

翻译:现在你已经有了非安全的web应用,你可以对它加上安全。

Set up Spring Security 装配Spring Security

Suppose that you want to prevent unauthorized users from viewing the greeting page at /hello. As it is now, if visitors click the link on the home page, they see the greeting with no barriers to stop them. You need to add a barrier that forces the visitor to sign in before they can see that page.

翻译:假设你想防止未认证的用户访问欢迎页。像现在这样,如果用户在主页点击链接,他们将看到欢迎页,没有任何障碍阻止他们。你必须添加障碍迫使访问者看到欢迎页之前要先登录。

You do that by configuring Spring Security in the application. If Spring Security is on the classpath, Spring Boot automatically secures all HTTP endpoints with “basic” authentication. However, you can further customize the security settings. The first thing you need to do is add Spring Security to the classpath.

翻译:你可以在应用配置Spring Security 这样做。如果Spring Security在类路径中,Spring Boot框架会自动对所有的HTTP 端点进行使用基础认证方式安全拦截。但是,你可用进一步自定义安全配置。你要做的第一步是添加Spring Security到类路径中。

With Gradle, you need to add two lines (one for the application and one for testing) in the dependencies closure in build.gradle, as the following listing shows:

翻译:使用Gradle,你需要在build.gradle的dependencies括号中添加两行(一个为了应用,一个为了测试),下面展示了如何配置:

implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-test'

The following listing shows the finished build.gradle file:
完整的build.gradle配置文件如下:

plugins {
	id 'org.springframework.boot' version '2.3.2.RELEASE'
	id 'io.spring.dependency-management' version '1.0.8.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.security:spring-security-test'
	testImplementation('org.springframework.boot:spring-boot-starter-test') {
		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
	}
}

test {
	useJUnitPlatform()
}

With Maven, you need to add two extra entries (one for the application and one for testing) to the element in pom.xml, as the following listing shows:

翻译:使用Maven,你需要在pom.xml文件的节点中添加两个额外依赖(一个为了应用,一个为了测试),如下展示:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-test</artifactId>
  <scope>test</scope>
</dependency>

The following listing shows the finished pom.xml file:
完整的pom.xml文件如下:

<?xml version="1.0" encoding="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>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>securing-web</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>securing-web</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

The following security configuration (from src/main/java/com/example/securingweb/WebSecurityConfig.java) ensures that only authenticated users can see the secret greeting:

翻译:下面的security 配置(在项目路径的 src/main/java/com/example/securingweb/WebSecurityConfig.java)保证只有认证的用户才可用看到欢迎页:

package com.example.securingweb;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
			.authorizeRequests()
				.antMatchers("/", "/home").permitAll()
				.anyRequest().authenticated()
				.and()
			.formLogin()
				.loginPage("/login")
				.permitAll()
				.and()
			.logout()
				.permitAll();
	}

	@Bean
	@Override
	public UserDetailsService userDetailsService() {
		UserDetails user =
			 User.withDefaultPasswordEncoder()
				.username("user")
				.password("password")
				.roles("USER")
				.build();

		return new InMemoryUserDetailsManager(user);
	}
}

The WebSecurityConfig class is annotated with @EnableWebSecurity to enable Spring Security’s web security support and provide the Spring MVC integration. It also extends WebSecurityConfigurerAdapter and overrides a couple of its methods to set some specifics of the web security configuration.

翻译:WebSecurityConfig这个类带有@EnableWebSecurity注解,它启动了Spring Security的web 安全支持并提供Sping MVC的集成。它也继承了WebSecurityConfigurerAdapter并重写它的两个方法,为了配置自定义安全配置。

The configure(HttpSecurity) method defines which URL paths should be secured and which should not. Specifically, the / and /home paths are configured to not require any authentication. All other paths must be authenticated.

翻译:configure(HttpSecurity)这个方法定义了那些URL路径应该被安全校验,哪些不需要。特别地,“/”和“/home" 路径配置为不需要任何认证。其它所有路径都需要认证。

When a user successfully logs in, they are redirected to the previously requested page that required authentication. There is a custom /login page (which is specified by loginPage()), and everyone is allowed to view it.

翻译:当用户成功登录,他们被重定向到之前未被授权访问的页面。这边有一个自定义登录页(它被loginPage()标明),所有人都可用访问它。

The userDetailsService() method sets up an in-memory user store with a single user. That user is given a user name of user, a password of password, and a role of USER.

翻译:userDetailsService()这个方法设置使用内存保护用户信息,且定义一个用户。这个用户的账号是user,密码是password,角色是USER。

Now you need to create the login page. There is already a view controller for the login view, so you need only to create the login view itself, as the following listing (from src/main/resources/templates/login.html) shows:

翻译:现在你需要创建登录页面。我们已经有个对应的登录页的视图控制器,所以你只需要创建登录页。下面展示这个页面(在项目路径下 src/main/resources/templates/login.html):

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Spring Security Example </title>
    </head>
    <body>
        <div th:if="${param.error}">
            Invalid username and password.
        </div>
        <div th:if="${param.logout}">
            You have been logged out.
        </div>
        <form th:action="@{/login}" method="post">
            <div><label> User Name : <input type="text" name="username"/> </label></div>
            <div><label> Password: <input type="password" name="password"/> </label></div>
            <div><input type="submit" value="Sign In"/></div>
        </form>
    </body>
</html>

This Thymeleaf template presents a form that captures a username and password and posts them to /login. As configured, Spring Security provides a filter that intercepts that request and authenticates the user. If the user fails to authenticate, the page is redirected to /login?error, and your page displays the appropriate error message. Upon successfully signing out, your application is sent to /login?logout, and your page displays the appropriate success message.

翻译:这个Thymeleaf模板展示了一个表单获取用户名和密码,并发送到/login。如上配置,Spring Security 提供过滤器拦截请求,并认证用户。如果用户认证失败,页面将被重定向到/login?error,你的页面展示相关的错误信息。一旦用户退出登录,你的应用被转发到/login?logout,你的页面会显示相关的成功信息。

Last, you need to provide the visitor a way to display the current user name and sign out. To do so, update the hello.html to say hello to the current user and contain a Sign Out form, as the following listing (from src/main/resources/templates/hello.html) shows:

翻译:最后,你需要向用户提供显示当前登录用户名和退出的方式。为了这样做,更新欢迎页(hello.html) 对当前用户欢迎,并包含退出表单,如下配置(在项目的 src/main/resources/templates/hello.html)展示:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
        <form th:action="@{/logout}" method="post">
            <input type="submit" value="Sign Out"/>
        </form>
    </body>
</html>

We display the username by using Spring Security’s integration with HttpServletRequest#getRemoteUser(). The “Sign Out” form submits a POST to /logout. Upon successfully logging out, it redirects the user to /login?logout.

翻译:我们显示用户名用Spring Security集成的HttpServletRequest#getRemoteUser(), 这个“Sign Out"表单提交一个Post请求到//logout路径。一旦退出成功,应用重定向到/login?logout路径。

Run the Application 运行这个程序

The Spring Initializr creates an application class for you. In this case, you need not modify the class. The following listing (from src/main/java/com/example/securingweb/SecuringWebApplication.java) shows the application class:

翻译:Spring Initializr为你创建应用启动类。既然这样,你不需要更改这个类。下面展示了这个应用启动类(在项目的 src/main/java/com/example/securingweb/SecuringWebApplication.java):

package com.example.securingweb;

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

@SpringBootApplication
public class SecuringWebApplication {

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

}

Build an executable JAR 编译一个可执行JAR

You can run the application from the command line with Gradle or Maven. You can also build a single executable JAR file that contains all the necessary dependencies, classes, and resources and run that. Building an executable jar makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.

翻译:你可以运行应用使用基于Gradle或Maven的命令行。你也可以编译成一个可执行JAR包,它包含了所有的依赖、类、资源并启动它。构建一个可执行的jar使得将服务作为一个应用程序在整个开发生命周期、跨不同环境等进行发布、版本和部署变得容易。

If you use Gradle, you can run the application by using ./gradlew bootRun. Alternatively, you can build the JAR file by using ./gradlew build and then run the JAR file, as follows:

翻译:如果你使用Gradle,你可以使用"./gradlew bootRun" 运行这个应用。或者,你可以使用“./gradlew build" 构建jar包,并用下面的命令将运行jar包。

java -jar build/libs/gs-securing-web-0.1.0.jar

If you use Maven, you can run the application by using ./mvnw spring-boot:run. Alternatively, you can build the JAR file with ./mvnw clean package and then run the JAR file, as follows:

翻译:如果你使用Maven,你可以使用”。/mvnw spring-boot:run“运行应用。或者,你也可以使用”./mvnw clean package“构建jar包,并使用下面命令运行jar包:

java -jar target/gs-securing-web-0.1.0.jar

The steps described here create a runnable JAR. You can also build a classic WAR file.
这个步骤描述如何创建JAR包,你也可以构建WAR包

Once the application starts up, point your browser to http://localhost:8080. You should see the home page, as the following image shows:

翻译:一旦这个应用启动,让你的浏览器访问“http://localhost:8080”,你可以看到主页,如下所示:
在这里插入图片描述

When you click on the link, it attempts to take you to the greeting page at /hello. However, because that page is secured and you have not yet logged in, it takes you to the login page, as the following image shows:

翻译:当你点击这个链接,它尝试带你到欢迎页。然而,由于这个页面被安全保护,你也未登录。应用重定向到登录页,如下图所示:
在这里插入图片描述

If you jumped down here with the unsecured version, you do not see the login page. You should back up and write the rest of the security-based code.
如果你使用非安全的版本代码跳转到这里,你不会看到这个登录页面。你应该备份并编写其余的基于安全性的代码。

At the login page, sign in as the test user by entering user and password for the username and password fields, respectively. Once you submit the login form, you are authenticated and then taken to the greeting page, as the following image shows:

翻译:在登录页,在用户名和密码框各自输入测试账号的账号和密码进行登录。一旦你提交表单,你将认证通过被到欢迎页,如下图所示:
在这里插入图片描述

If you click on the Sign Out button, your authentication is revoked, and you are returned to the login page with a message indicating that you are logged out.
Summary

翻译:如果你点击退出按钮,你的认证信息将被清除并跳转到登录页面,该页面提示你已经退出登录信息。

Congratulations! You have developed a simple web application that is secured with Spring Security.
See Also

翻译:恭喜!您已经开发过一个简单的Spring Security 安全web应用。

The following guides may also be helpful:
以下指南也许有用:

猜你喜欢

转载自blog.csdn.net/Lixuanshengchao/article/details/112442682
今日推荐