首页 > 编程语言 >使用受 Spring 安全性保护的资源创建简单 Web 应用程序

使用受 Spring 安全性保护的资源创建简单 Web 应用程序

时间:2022-12-22 10:36:50浏览次数:64  
标签:Web Spring boot springframework 应用程序 org security

使用受 Spring 安全性保护的资源创建简单 Web 应用程序_html

本指南将引导您完成使用受 Spring 安全性保护的资源创建简单 Web 应用程序的过程。

您将构建什么

您将构建一个Spring MVC应用程序,该应用程序使用由固定用户列表支持的登录表单来保护页面。

你需要什么

  • 约15分钟
  • 最喜欢的文本编辑器或 IDE
  • JDK 17或以后
  • 格拉德尔 4+​或梅文 3.2+
  • 您也可以将代码直接导入到 IDE 中:
  • 弹簧工具套件 (STS)
  • 智能理念
  • VSCode

如何完成本指南

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

要从头开始,请继续从 Spring 初始化开始.

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

  • 下载​并解压缩本指南的源存储库,或使用吉特:git clone https://github.com/spring-guides/gs-securing-web.git
  • 光盘成gs-securing-web/initial
  • 跳转到创建不安全的 Web 应用程序.

完成后,您可以根据 中的代码检查结果。​​gs-securing-web/complete​

从 Spring 初始化开始

你可以使用这个预初始化项目,然后单击生成以下载 ZIP 文件。此项目配置为适合本教程中的示例。

手动初始化项目:

  1. 导航到https://start.spring.io.此服务拉入应用程序所需的所有依赖项,并为您完成大部分设置。
  2. 选择 Gradle 或 Maven 以及您要使用的语言。本指南假定您选择了 Java。
  3. 单击“依赖项”,然后选择“Spring Web”和“Thymeleaf”。
  4. 单击生成
  5. 下载生成的 ZIP 文件,该文件是配置了您选择的 Web 应用程序的存档。

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

您也可以从 Github 分叉项目,然后在 IDE 或其他编辑器中打开它。

创建不安全的 Web 应用程序

在将安全性应用于 Web 应用程序之前,您需要一个要保护的 Web 应用程序。本节将引导您创建一个简单的 Web 应用程序。然后,您将在下一节中使用Spring Security来保护它。

Web 应用程序包括两个简单视图:主页和“你好,世界”页面。主页在以下百里香叶模板中定义(来自):​​src/main/resources/templates/home.html​

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<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>

此简单视图包含指向页面的链接,该链接在以下 Thymeleaf 模板(来自):​​/hello​​​​src/main/resources/templates/hello.html​

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

Web应用程序基于Spring MVC。因此,您需要配置 Spring MVC 并设置视图控制器以公开这些模板。下面的清单(来自)显示了在应用程序中配置 Spring MVC 的类:​​src/main/java/com/example/securingweb/MvcConfig.java​

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");
}

}

该方法(重写 中同名的方法)添加了四个视图控制器。其中两个视图控制器引用名称为 (在 中定义) 的视图,另一个引用名为 (在 中定义) 的视图。第四个视图控制器引用另一个名为 的视图。您将在下一节中创建该视图。​​addViewControllers()​​​​WebMvcConfigurer​​​​home​​​​home.html​​​​hello​​​​hello.html​​​​login​

此时,您可以跳到”运行应用程序“并运行应用程序,而无需登录任何内容。

现在您有一个不安全的 Web 应用程序,您可以为其添加安全性。

设置 Spring 安全性

假设您要阻止未经授权的用户查看 上的问候语页面。就像现在一样,如果访问者单击主页上的链接,他们会看到没有障碍的问候语来阻止他们。您需要添加一个障碍,强制访问者登录,然后才能看到该页面。​​/hello​

您可以通过在应用程序中配置 Spring 安全性来做到这一点。如果 Spring 安全性在类路径上,Spring 引导​​自动保护所有 HTTP 端点​​使用“基本”身份验证。但是,您可以进一步自定义安全设置。您需要做的第一件事是将 Spring 安全性添加到类路径中。

使用 Gradle,您需要在 的闭包中添加三行(一行用于应用程序,一行用于 Thymeleaf & Spring Security 集成,一行用于测试),如以下列表所示:​​dependencies​​​​build.gradle​

implementation 'org.springframework.boot:spring-boot-starter-security'
// Temporary explicit version to fix Thymeleaf bug
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6:3.1.1.RELEASE'
implementation 'org.springframework.security:spring-security-test'

以下清单显示了完成的文件:​​build.gradle​

plugins {
id 'java'
id 'org.springframework.boot' version '3.0.0'
id 'io.spring.dependency-management' version '1.1.0'
}

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

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-security'
// Temporary explicit version to fix Thymeleaf bug
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6:3.1.1.RELEASE'
implementation 'org.springframework.security:spring-security-test'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
useJUnitPlatform()
}

使用 Maven,您需要向 中的元素添加两个额外的条目(一个用于应用程序,一个用于测试),如以下清单所示:​​<dependencies>​​​​pom.xml​

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
<!-- Temporary explicit version to fix Thymeleaf bug -->
<version>3.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>

以下清单显示了完成的文件:​​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>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>securing-web-complete</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>securing-web-complete</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>17</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.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
<!-- Temporary explicit version to fix Thymeleaf bug -->
<version>3.1.1.RELEASE</version>
</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>
</dependency>
</dependencies>

</project>

以下安全配置(来自)可确保只有经过身份验证的用户才能看到秘密问候语:​​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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
)
.formLogin((form) -> form
.loginPage("/login")
.permitAll()
)
.logout((logout) -> logout.permitAll());

return http.build();
}

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

return new InMemoryUserDetailsManager(user);
}
}

该类被注释为启用Spring Security的Web安全支持并提供Spring MVC集成。它还公开了两个 bean 来设置 Web 安全配置的一些细节:​​WebSecurityConfig​​​​@EnableWebSecurity​

Bean 定义了哪些 URL 路径应该受到保护,哪些不应该受到保护。具体而言,和 路径配置为不需要任何身份验证。所有其他路径都必须经过身份验证。​​SecurityFilterChain​​​​/​​​​/home​

用户成功登录后,将重定向到之前请求的需要身份验证的页面。有一个自定义页面(由 指定),每个人都可以查看它。​​/login​​​​loginPage()​

Bean 使用单个用户设置内存中用户存储。该用户的用户名为 、 的密码和 的角色。​​UserDetailsService​​​​user​​​​password​​​​USER​

现在您需要创建登录页面。视图已经有一个视图控制器,因此您只需创建登录视图本身,如以下清单(来自)所示:​​login​​​​src/main/resources/templates/login.html​

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<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>

此百里香叶模板提供了一个表单,用于捕获用户名和密码并将其发布到 .按照配置,Spring 安全性提供了一个过滤器,用于拦截该请求并对用户进行身份验证。如果用户身份验证失败,页面将重定向到 ,并且您的页面将显示相应的错误消息。成功注销后,您的应用程序将发送到 ,并且您的页面将显示相应的成功消息。​​/login​​​​/login?error​​​​/login?logout​

最后,您需要为访问者提供一种显示当前用户名和注销的方法。为此,请更新 以向当前用户问好并包含一个表单,如以下列表 (from ) 所示:​​hello.html​​​​Sign Out​​​​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-springsecurity6">
<head>
<title>Hello World!</title>
</head>
<body>
<h1 th:inline="text">Hello <span th:remove="tag" sec:authentication="name">thymeleaf</span>!</h1>
<form th:action="@{/logout}" method="post">
<input type="submit" value="Sign Out"/>
</form>
</body>
</html>

我们使用Thymeleaf与Spring Security的集成来显示用户名。“注销”表单将开机自检提交到 。成功注销后,它将用户重定向到 。​​/logout​​​​/login?logout​

Thymeleaf 3.1 不再提供访问,因此不能用于访问当前经过身份验证的用户。​​HttpServletRequest​​​​HttpServletRequest#getRemoteUser()​

运行应用程序

Spring 初始化器会为您创建一个应用程序类。在这种情况下,您无需修改类。以下清单(来自 )显示了应用程序类:​​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);
}

}

构建可执行的 JAR

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

如果使用 Gradle,则可以使用 .或者,您可以使用 JAR 文件生成 JAR 文件,然后运行该文件,如下所示:​​./gradlew bootRun​​​​./gradlew build​

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

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

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

此处描述的步骤将创建一个可运行的 JAR。你也可以构建经典 WAR 文件.

应用程序启动后,将浏览器指向 。您应该会看到主页,如下图所示:​​http://localhost:8080​

当您单击该链接时,它会尝试将您带到 的问候页面。但是,由于该页面是安全的,并且您尚未登录,因此它会将您带到登录页面,如下图所示:​​/hello​

使用受 Spring 安全性保护的资源创建简单 Web 应用程序_应用程序_02

如果您使用不安全的版本跳到此处,则看不到登录页面。您应该备份并编写其余的基于安全性的代码。

在登录页面上,分别输入用户名和密码字段,以测试用户身份登录。提交登录表单后,您将进行身份验证,然后转到问候页面,如下图所示:​​user​​​​password​

如果单击“注销”按钮,您的身份验证将被撤销,并且您将返回到登录页面,并显示一条消息,指示您已注销

总结

祝贺!您已经开发了一个简单的 Web 应用程序,该应用程序使用 Spring 安全性进行保护。

标签:Web,Spring,boot,springframework,应用程序,org,security
From: https://blog.51cto.com/u_15326439/5962376

相关文章

  • 使用 Spring 创建“Hello, World”超媒体驱动的 REST Web 服务
    本指南将引导您完成使用Spring创建“Hello,World”超媒体驱动的RESTWeb服务的过程。超媒体是REST的一个重要方面。它允许您构建在很大程度上分离客户端和服务器的服......
  • 构建应用程序的过程Apache Geode数据管理系统
    本指南将引导您完成构建应用程序的过程ApacheGeode数据管理系统。您将构建什么您将使用ApacheGeode的春季数据存储和检索POJO。你需要什么约15分钟最喜欢的文本编辑器或......
  • SpringBoot(八):静态资源配置
    在SpringBoot中有六种方式来配置相关的静态资源。1.webjars导入webjars的相关静态资源依赖访问方式:localhost:8080/webjars/静态资源名称2.classpath:/static将静态资......
  • 配置 Web 应用程序表单
    本指南将引导您完成配置Web应用程序表单以支持验证的过程。您将构建什么您将构建一个简单的SpringMVC应用程序,该应用程序接受用户输入并使用标准验证注释检查输入。您还......
  • 使用 Spring Boot Actuator 构建 RESTful Web 服务
    弹簧启动执行器是SpringBoot的一个子项目。它为您的应用程序添加了多个生产级服务,而您几乎不费吹灰之力。在本指南中,您将构建一个应用程序,然后了解如何添加这些服务。您将......
  • WebRTC 的音频弱网对抗之 NACK
    基础知识音频的NACK机制在WebRTC中默认是关闭的.rtcpfeedbacknack开启就可以了WebRTC的音频数据传输中,尽管对低延时有着很高的要求,但也实现了NACK,以用于一些音......
  • .net core web api 路由约束
    路由约束在传入URL发生匹配时执行,URL路径标记为路由值。路径约束通常检查通过路径模板关联的路径值,并对该值是否为可接受做出对/错决定。某些路由约束使用路由值以外......
  • Spring Cloud 2022 正式发布!我的天,OpenFeign​ 要退出历史舞台了?!
    大家好,我是栈长。今天给大家通报一则框架更新消息,时隔2021.x版本发布一年,SpringCloud2022.0.0最新版发布了,来看下最新的SpringCloud版本情况:SpringCloud无疑......
  • vue中webpack环境中动态注册插件
    //webpack动态引入文件constrequireComonents=require.context("./",true,/\.vue$/);//Vue提供的install方法进行插件的注册/**install方法第一个参数是vue......
  • WebFlux 详解
    今天我们开始来学习下​​WebFlux​​,为什么突然要学这个东西?因为我之前是想学习​​SpringCloudGateway​​​来着,然后发现它是基于​​Spring5.0+SpringBoot2.0+Web......