分布式系统开发实战:基于Spring Security实现安全认证

简介: 在本节,将演示基于Spring Security安全认证功能。该应用代码可以在security basic目录下找到。19.5.1 添加依赖

在本节,将演示基于Spring Security安全认证功能。该应用代码可以在security basic目录下找到。

19.5.1 添加依赖

添加Spring Security的依赖时,由于是使用的snapshot版本,所以,要配置Spring Snapshots仓库。配置如下。

<!-- Spring Snapshots仓库 -->
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
</repository>
</repositories>
<properties>
<spring.version>5.1.5.RELEASE</spring.version>
<jetty.version>9.4.14.v20181114</jetty.version>
<jackson.version>2.9.7</jackson.version>
<spring-security.version>5.2.0.BUILD-SNAPSHOT</spring-security.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency><!-- 安全相关的依赖 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring-security.version}</version>
</dependency>
</dependencies>

19.5.2 添加业务代码

业务代码里面包含了模型和控制器。

1.User模型

User类代码如下。

package com.waylau.spring.mvc.vo;
public class User {
private String username;
private Integer age;
public User(String username, Integer age) {
this.username = username;
this.age = age;
}
//省略getter/setter方法
}

2.控制器

控制器HelloController代码如下。

package com.waylau.spring.mvc.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.waylau.spring.mvc.vo.User;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "Hello World! Welcome to visit waylau.com!";}
@RequestMapping("/hello/way")
public User helloWay() {
return new User("Way Lau", 30);
}
}

上述控制器的逻辑非常简单,当访问“/hello”时,会响应一段文本;当访问“/hello/way”会返回一个POJO对象。

该POJO对象,可以根据消息转换器的设置,来生成不同格式的消息。

19.5.3 配置消息转换器

添加Spring Web MVC的配置类MvcConfiguration,并在该配置中启用消息转换器。

package com.waylau.spring.mvc.configuration;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc // 启用MVC
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
public void extendMessageConverters(List<HttpMessageConverter<?>> cs) {
// 使用Jackson JSON来进行消息转换
cs.add(new MappingJackson2HttpMessageConverter());
}
}

由于预先在pom.xml中添加了Jackson JSON的依赖,因此可以使用

Jackson JSON来进行消息转换,将响应消息体转为JSON格式。

19.5.4 配置Spring Security

以下是针对Spring Security的配置。

package com.waylau.spring.mvc.configuration;
import org.springframework.context.annotation.Bean;
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.WebSecurityConfigurerAd
apter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@EnableWebSecurity // 启用Spring Security功能
public class WebSecurityConfig
extends WebSecurityConfigurerAdapter {
/**
* 自定义配置
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()//所有请求都需认证
.and()
.formLogin() // 使用form表单登录
.and()
.httpBasic(); // HTTP基本认证
}
@SuppressWarnings("deprecation")
@Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager =
new InMemoryUserDetailsManager();
manager.createUser(
User.withDefaultPasswordEncoder() // 密码编码器
.username("waylau") // 用户名
.password("123") // 密码
.roles("USER") // 角色
.build()
);
return manager;
}
}

在上述配置中,要启动Spring Security功能,需要在配置类上添加@EnableWebSecurity注解。

安全配置类WebSecurityConfig继承自


WebSecurityConfigurerAdapter。WebSecurity Configurer Adapter提供用于创建一个Websecurityconfigurer实例方便的基类,允许自定义重写其方法。这里,我们重写了configure方法:authorizeRequests().anyRequest().authenticated()方法意味着所有请求都需认证;formLogin()方法表明这是基于表单的身份验证;httpBasic()方法表明该认证是一个HTTP基本认证。

UserDetailsService用于提供身份认证信息。本例使用了基于内存的信息管理器InMemory UserDetailsManager,同时初始化了一个用户名为“waylau”、密码为“123”、角色为“USER”的身份信息。
withDefaultPasswordEncoder()方法指定了该用户身份信息使用默认的密码编码器。

19.5.5 创建应用配置类

AppConfiguration是整个应用的配置类,用于导入Spring Web MVC及Spring Security的配置信息。代码如下。

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@ComponentScan(basePackages = { "com.waylau.spring" })
@Import({ WebSecurityConfig.class, MvcConfiguration.class})
public class AppConfiguration {
}

19.5.6 创建内嵌Jetty的服务器

创建内嵌了Jetty的服务器,代码如下。

package com.waylau.spring.mvc;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.DispatcherServlet;
import com.waylau.spring.mvc.configuration.AppConfiguration;
public class JettyServer {
private static final int DEFAULT_PORT = 8080;
private static final String CONTEXT_PATH = "/";
private static final String MAPPING_URL = "/*";
public void run() throws Exception {
Server server = new Server(DEFAULT_PORT);
server.setHandler(servletContextHandler(webApplicationContext()));
server.start();
server.join();
}
private ServletContextHandler servletContextHandler(WebApplicationContext ct) {
// 启用Session管理器
ServletContextHandler handler =
new ServletContextHandler(ServletContextHandler.SESSIONS);
handler.setContextPath(CONTEXT_PATH);
handler.addServlet(new ServletHolder(new DispatcherServlet(ct)),
MAPPING_URL);
handler.addEventListener(new ContextLoaderListener(ct));
// 添加Spring Security过滤器
FilterHolder filterHolder=new FilterHolder(DelegatingFilterProxy.class);
filterHolder.setName("springSecurityFilterChain");
handler.addFilter(filterHolder, MAPPING_URL,
EnumSet.of(DispatcherType.REQUEST));
return handler;
}
private WebApplicationContext webApplicationContext() {
AnnotationConfigWebApplicationContext context =
new AnnotationConfigWebApplicationContext();
context.register(AppConfiguration.class);
return context;
}
}

JettyServer将Spring的上下文Servlet、监听器、过滤器等信息都传给了Jetty服务。

19.5.7 应用启动器

创建应用启动类Application,代码如下。

package com.waylau.spring.mvc;
public class Application {
public static void main(String[] args) throws Exception {
new JettyServer().run();
}
}

19.5.8 运行应用

右键运行Application类即可启动应用。

访问
http://localhost:8080/hello/way,会跳转到登录界面,意味着被安全认证拦截了。正如WebSecurityConfig所配置的那样,登录界面是一个form表单,

网络异常,图片无法展示
|

尝试输入一个错误的用户名和密码,可以看到所示的错误提示信息。

网络异常,图片无法展示
|

用初始化好的用户名和密码进行成功登录,可以看到能够正常访问应用的API

网络异常,图片无法展示
|

19.6 本章小结

本章介绍了分布式系统安全性的基本概念、加密算法,同时也介绍了安全通道及访问控制。本章也演示了如何基于Spring Security框架来实现安全认证。

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

相关文章
|
域名解析 网络协议 测试技术
性能测试-弱网测试参数选择标准
在当今移动互联网盛行的时代,网络的形态除了有线连接,还有2G/3G/Edge/4G/Wifi等多种手机网络连接方式。不同的协议、不同的制式、不同的速率,使移动应用运行的场景更加丰富。
12545 0
性能测试-弱网测试参数选择标准
|
10月前
|
人工智能 运维 Devops
基于云效落地平台工程企业级最佳实践
本文介绍了平台工程作为DevOps演进的必然方向,探讨了其建设过程中面临的挑战及解决方案。文中首先分析了平台工程与DevOps的关系,强调了其在提升价值交付和降低团队心智负担方面的作用。接着,通过云效作为基础设施,详细阐述了其如何帮助企业构建高效的研发平台,并分享了两个实际案例:一个是200人规模的互联网企业,另一个是2000人规模的金融行业企业。最后,展望了平台工程的未来发展方向,包括组件化开发、AI技术的应用以及智能化场景的融入。碧桂园生活服务集团也分享了其在平台工程领域的实践经验和未来思考,强调了标准化、自动化、可靠性和智能化四大原则的重要性。
280 10
|
数据采集 机器学习/深度学习 Python
深度学习中的高效数据预处理技巧
【7月更文第29天】在构建深度学习模型时,数据预处理是至关重要的步骤之一。高质量的数据预处理可以显著提高模型的性能并加速训练过程。本文将探讨几种有效的数据预处理技巧,包括数据清洗、特征归一化和数据增强,并通过实际的Python代码示例进行说明。
1280 5
|
存储 关系型数据库 数据库
什么是索引
【10月更文挑战第15天】什么是索引
|
敏捷开发 数据可视化 持续交付
敏捷开发方法:理论与实践
【8月更文第22天】随着信息技术的发展,软件项目的复杂度不断提高,传统的瀑布式开发模式越来越难以适应快速变化的市场需求。为了解决这些问题,敏捷开发方法应运而生。本文将探讨敏捷开发的核心理念、敏捷宣言与原则、Scrum框架、Kanban方法以及相关的敏捷实践与工具。
1610 2
|
机器学习/深度学习 自然语言处理 PyTorch
PyTorch 中的动态图与静态图:理解它们的区别及其应用场景
【8月更文第29天】深度学习框架中的计算图是构建和训练神经网络的基础。PyTorch 支持两种类型的计算图:动态图和静态图。本文旨在阐述这两种计算图的区别、各自的优缺点以及它们在不同场景下的应用。
3291 0
|
11月前
|
机器学习/深度学习 存储 人工智能
基于AI的实时监控系统:技术架构与挑战分析
AI视频监控系统利用计算机视觉和深度学习技术,实现实时分析与智能识别,显著提升高风险场所如监狱的安全性。系统架构包括数据采集、预处理、行为分析、实时决策及数据存储层,涵盖高分辨率视频传输、图像增强、目标检测、异常行为识别等关键技术。面对算法优化、实时性和系统集成等挑战,通过数据增强、边缘计算和模块化设计等方法解决。未来,AI技术的进步将进一步提高监控系统的智能化水平和应对复杂安全挑战的能力。
2148 4
|
机器学习/深度学习 PyTorch 调度
在Pytorch中为不同层设置不同学习率来提升性能,优化深度学习模型
在深度学习中,学习率作为关键超参数对模型收敛速度和性能至关重要。传统方法采用统一学习率,但研究表明为不同层设置差异化学习率能显著提升性能。本文探讨了这一策略的理论基础及PyTorch实现方法,包括模型定义、参数分组、优化器配置及训练流程。通过示例展示了如何为ResNet18设置不同层的学习率,并介绍了渐进式解冻和层适应学习率等高级技巧,帮助研究者更好地优化模型训练。
863 4
在Pytorch中为不同层设置不同学习率来提升性能,优化深度学习模型
|
弹性计算 负载均衡 网络协议
LVS (Linux Virtual server)集群介绍
LVS (Linux Virtual server)集群介绍
|
机器学习/深度学习 人工智能 算法
阿里达摩院 MindOpt 介绍和使用
MindOpt 是阿里巴巴达摩院决策智能实验室研发的决策优化软件。团队组建于2019年,聚焦于研发尖端运筹优化和机器学习技术,构建智能决策系统,更快更好地向各行各业提供数学建模与求解能力,帮助业务更快更好地做出决策,以期降低成本、提升效率、增大收益 。当前 MindOpt 围绕智能决策优化所需的建模和求解能力,突破国外垄断,自研了 MindOpt Solver 优化求解器、MindOpt APL 建模语言、MindOpt Tuner 调参器;并创新地提出“强化+优化”双决策引擎,打造了MindOpt Studio 优化平台。并结合前沿先进的预训练大模型技术打造MindOpt Copilot。
4213 2
阿里达摩院 MindOpt 介绍和使用