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.
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.
What You Need

About 15 minutes

A favorite text editor or IDE

JDK 1.8 or later

Gradle 4+ or Maven 3.2+

You can also import the code straight into your IDE:

    Spring Tool Suite (STS)

    IntelliJ IDEA

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.

To start from scratch, move on to 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

cd into gs-securing-web/initial

Jump ahead to Create an Unsecured Web Application.

When you finish, you can check your results against the code in gs-securing-web/complete.
Starting with 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. The following image shows the Initializr set up for this sample project:
initializr
The preceding image shows the Initializr with Maven chosen as the build tool. You can also use Gradle. It also shows values of com.example and securing-web as the Group and Artifact, respectively. You will use those values throughout the rest of this sample.

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

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

org.springframework.boot
spring-boot-starter-parent
2.2.2.RELEASE


com.example
securing-web
0.0.1-SNAPSHOT
securing-web
Demo project for Spring Boot

<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>

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

扫描二维码关注公众号,回复: 10441868 查看本文章

plugins {
id ‘org.springframework.boot’ version ‘2.2.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.

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):

Spring Security Example

Welcome!

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

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 World!

Hello world!

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:

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.

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

Now that you have an unsecured web application, you can add security to it.
Set up 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.

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:

implementation ‘org.springframework.boot:spring-boot-starter-security’
implementation ‘org.springframework.security:spring-security-test’

The following listing shows the finished build.gradle file:

plugins {
id ‘org.springframework.boot’ version ‘2.2.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:

org.springframework.boot spring-boot-starter-security org.springframework.security spring-security-test test

The following listing shows the finished pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

org.springframework.boot
spring-boot-starter-parent
2.2.2.RELEASE


com.example
securing-web
0.0.1-SNAPSHOT
securing-web
Demo project for Spring Boot

<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>

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

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.

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.

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.

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.

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:

Spring Security Example
Invalid username and password.
You have been logged out.

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.

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 World!

Hello [[${#httpServletRequest.remoteUser}]]!

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.
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:

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

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 so makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.

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:

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:

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.

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

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:
The login page
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:
The secured greeting page

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.

translate:
翻译:

本指南将指导您创建一个简单的web应用程序,其中包含受Spring安全性保护的资源。
你将建造什么
您将构建一个Spring MVC应用程序,它使用一个由固定用户列表支持的登录表单来保护页面。
你需要什么
大约15分钟
最喜欢的文本编辑器或IDE
JDK 1.8或更高版本
Gradle 4+或Maven 3.2+
您还可以直接将代码导入到IDE中:
Spring工具套件(STS)
智力观念
如何完成本指南
与大多数Spring入门指南一样,您可以从头开始并完成每个步骤,也可以绕过您已经熟悉的基本设置步骤。不管怎样,你最终都会使用代码。
要从头开始,请继续使用Spring初始化器。
要跳过基本步骤,请执行以下操作:
下载并解压缩此指南的源存储库,或使用Git:Git clone https://github.com/spring-guides/gs-securing-web.Git进行克隆
cd进入gs安全网/初始
继续创建一个不安全的Web应用程序。
完成后,可以对照gs securing web/complete中的代码检查结果。
从Spring初始化器开始
对于所有Spring应用程序,都应该从Spring初始化器开始。initializer提供了一种快速的方法来获取应用程序所需的所有依赖项,并为您进行了很多设置。这个例子需要Spring Web和Thymeleaf的依赖关系。下图显示了为此示例项目设置的初始值设定项:
初始化程序
上图显示了选择Maven作为构建工具的初始化器。你也可以用格雷德。它还分别显示了com.example和securing web作为组和工件的价值。您将在本示例的其余部分中使用这些值。

构建可执行JAR
您可以使用Gradle或Maven从命令行运行应用程序。您还可以构建一个包含所有必要依赖项、类和资源的可执行JAR文件并运行它。构建一个可执行的jar使得在整个开发生命周期、不同环境等中将服务作为应用程序发布、版本化和部署变得非常容易。
如果使用Gradle,可以使用./gradlew bootRun运行应用程序。或者,可以使用./gradlew build构建JAR文件,然后运行JAR文件,如下所示:
java-jar build/libs/gs-securing-web-0.1.0.jar
如果使用Maven,可以使用./mvnw spring boot:run运行应用程序。或者,可以使用./mvnw clean包构建JAR文件,然后运行JAR文件,如下所示:
java-jar目标/gs-securing-web-0.1.0.jar
这里描述的步骤创建了一个可运行的JAR。您还可以构建一个经典的WAR文件。
应用程序启动后,将浏览器指向http://localhost:8080。您应该会看到主页,如下图所示:
应用程序的主页
当您单击链接时,它会尝试将您带到/hello的问候页面。但是,由于该页是安全的,并且您尚未登录,因此它会将您带到登录页,如下图所示:
登录页面
如果您使用不安全的版本跳到这里,您将看不到登录页面。您应该备份并编写其余的基于安全性的代码。
在登录页面上,分别输入用户名和密码字段的用户和密码,以测试用户身份登录。提交登录表单后,您将通过身份验证,然后进入问候页面,如下图所示:
安全的问候页
如果单击“注销”按钮,则将撤消您的身份验证,并返回到登录页,并显示一条指示您已注销的消息。
摘要
祝贺 你!您已经开发了一个简单的web应用程序,该应用程序由Spring安全性保护。

发布了0 篇原创文章 · 获赞 152 · 访问量 7050

猜你喜欢

转载自blog.csdn.net/blog_programb/article/details/105237895