新版SpringSecurity5.x使用与配置
目录
一、了解SpringSecurity
1.1 什么是Spring Security?
1.2 Spring Security功能
1.3 Spring Security原理
1.4 RABC (Role-Based Access Control)
二、SpringSecurity简单案例
2.1 引入SpringSecurity依赖
2.2 创建一个简单的Controller
三、SpringSecurity配置
3.1 自定义用户与密码
3.2 允许匿名访问路径
3.3 数据库实现登陆校验
3.4 实现角色权限访问
3.5 对密码进行B加密
3.6 结合Jwt实现多重校验
一、了解SpringSecurity
1.1 什么是Spring Security?
Spring Security 是一个强大且高度可定制的身份验证和访问控制框架。它是 Spring 生态系统的一部分,为基于 Spring 的应用提供了全面的安全服务。Spring Security 的设计目标是为应用的安全需求提供一个完整的解决方案,同时保持高度的灵活性和可扩展性。
1.2 Spring Security功能
Spring Security 提供的功能包括但不限于:
- 认证(Authentication):验证用户身份,通常需要用户名和密码。
- 授权(Authorization):确定已认证的用户可以访问哪些资源或执行哪些操作。
- CSRF 保护:防止跨站请求伪造攻击。
- 会话管理:处理用户的会话,包括会话的创建、维护和销毁。
- 加密和编码:提供加密和散列算法的支持。
- OAuth2 和 OpenID Connect 支持:集成 OAuth2 和 OpenID Connect 协议,实现第三方认证。
- CORS 支持:处理跨域资源共享(Cross-Origin Resource Sharing)请求。
- 安全配置:允许通过 XML 或 Java 配置来定制安全策略。
1.3 Spring Security原理
Spring Security 的工作原理涉及几个关键组件:
- SecurityContext:存储认证信息,如当前登录用户和他们的权限。
- AuthenticationManager:负责用户认证,通常使用
UserDetailsService
来加载用户信息。 - AccessDecisionManager:决定用户是否有权访问特定资源。
- Filter Chain:一系列的过滤器处理请求和响应,例如
UsernamePasswordAuthenticationFilter
用于处理用户名和密码的提交。
1.4 RABC (Role-Based Access Control)
RABC,即基于角色的访问控制,是一种常见的访问控制机制,用于管理用户对资源的访问权限。在 RABC 中,权限不是直接授予用户,而是授予用户所属的角色。每个用户可以拥有一个或多个角色,而每个角色则有一组相应的权限。这种机制简化了权限管理,因为只需更改用户的角色就可以改变他们的权限集。
二、SpringSecurity简单案例
2.1 引入SpringSecurity依赖
<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>
2.2 创建一个简单的Controller
@RestController
public class HelloController {@GetMapping("Hello")public String Hello(){return "Hello SpringSecurity";}
}
2.3 运行后访问localhost:8080/Hello,会自动跳转到localhost:8080/login
这里的用户密码都在启动时候的控制台上 (注意:每一次启动密码都不一样)
用户名:user
密码: b82aa5e5-0a3a-466b-90a8-e94098877823(控制台上的一串密码)
登陆后成功访问
三、SpringSecurity配置
后面的配置都是基于小案例的基础上实现,请先完成上述的小案例
3.1 自定义用户与密码
由于每一次生成密码都是不固定的,对调试并不友好,springSecurity可以通过在application.yml中进行自定义设置用户和密码
spring:security:user:name: alphaMilkpassword: 123456
输入用户名和密码即可正常登陆并访问资源
3.2 允许匿名访问路径
在Spring Security框架中,允许某些路径或资源在未经过身份验证的情况下被访问,通常称为“允许匿名访问”。这种配置对于公共页面、登录页面、注册页面、API文档等是非常必要的,因为这些页面或资源需要对所有用户开放,无论他们是否已经登录。
以下通过配置类实现,用户能够匿名访问login页面
// 使用@Configuration标记此类为Spring的配置类
@Configuration
// 启用WebSecurity的自动配置,以便Spring Security可以管理Web安全
@EnableWebSecurity
public class SecurityConfiguration {// 定义一个名为securityFilterChain的bean,该bean将负责构建和应用安全过滤器链@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {// 配置HttpSecurity对象,定义安全规则http// 授权HTTP请求,定义哪些URL需要什么类型的访问控制.authorizeHttpRequests((authz) -> authz// 允许"/user/login" URL匿名访问.requestMatchers("/user/login").anonymous()// 所有其他请求都需要认证才能访问.anyRequest().authenticated())// 启用HTTP Basic认证,默认情况下提供简单的用户名/密码认证.httpBasic(Customizer.withDefaults());// 构建并返回SecurityFilterChainreturn http.build();}
}
创建一个LoginController类
@RestController
@RequestMapping("user")
public class LoginController {@GetMapping("/login")public String Login(){return "这是登陆资源页面";}
}
重启系统后直接访问,不需要登陆即可获取资源.
3.3 数据库实现登陆校验
通过自己数据库的用户和密码,实现登陆。将之前的自定义用户密码(application.yml中)都删除掉,并执行以下操作:
用户表单:
-- 创建一个包含用户信息和角色的简化表
CREATE TABLE IF NOT EXISTS `users` (`id` INT AUTO_INCREMENT PRIMARY KEY, -- 用户ID,自增主键`username` VARCHAR(255) NOT NULL UNIQUE, -- 用户名,唯一且不能为空`password` VARCHAR(255) NOT NULL, -- 密码,存储加密后的密码`role` ENUM('ROLE_USER', 'ROLE_ADMIN') NOT NULL, -- 角色,预定义为'ROLE_USER'或'ROLE_ADMIN'`enabled` TINYINT(1) NOT NULL DEFAULT 1 -- 用户状态,1表示启用,0表示禁用
);
注意:这里的role需要按照ROLE_身份 的方式进行存储以便springsecurity进行权限访问控制
插入案例数据 :
-- 插入示例用户数据
INSERT INTO `users` (`username`, `password`, `role`, `enabled`)
VALUES('user1', '123456', 'ROLE_USER', 1),('admin1', '123456', 'ROLE_ADMIN', 1),('disabledUser', '123456', 'ROLE_USER', 0);
引入依赖:
<!-- 数据库依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.5</version><exclusions><exclusion><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>3.0.3</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency>
配置数据源:
spring:datasource:url: jdbc:mysql://localhost:3306/ap_security?characterEncoding=utf-8&serverTimezone=UTCusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver
创建User实体与mapper并加上启动注释
User实体
@TableName(value ="users")
@Data
public class Users implements Serializable {/*** */@TableId(type = IdType.AUTO)private Integer id;/*** */private String username;/*** */private String password;/*** */private Object role;/*** */private Integer enabled;@TableField(exist = false)private static final long serialVersionUID = 1L;@Overridepublic boolean equals(Object that) {if (this == that) {return true;}if (that == null) {return false;}if (getClass() != that.getClass()) {return false;}Users other = (Users) that;return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))&& (this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))&& (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()))&& (this.getRole() == null ? other.getRole() == null : this.getRole().equals(other.getRole()))&& (this.getEnabled() == null ? other.getEnabled() == null : this.getEnabled().equals(other.getEnabled()));}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((getId() == null) ? 0 : getId().hashCode());result = prime * result + ((getUsername() == null) ? 0 : getUsername().hashCode());result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());result = prime * result + ((getRole() == null) ? 0 : getRole().hashCode());result = prime * result + ((getEnabled() == null) ? 0 : getEnabled().hashCode());return result;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append(getClass().getSimpleName());sb.append(" [");sb.append("Hash = ").append(hashCode());sb.append(", id=").append(id);sb.append(", username=").append(username);sb.append(", password=").append(password);sb.append(", role=").append(role);sb.append(", enabled=").append(enabled);sb.append(", serialVersionUID=").append(serialVersionUID);sb.append("]");return sb.toString();}
}
UserMapper
public interface UsersMapper extends BaseMapper<Users> {}
@MapperScan
@SpringBootApplication
@MapperScan("com.example.mysecurity.mapper")
public class MySecurityApplication {public static void main(String[] args) {SpringApplication.run(MySecurityApplication.class, args);}}
测试mybatisPlus是否配置正确
@SpringBootTest
class MySecurityApplicationTests {@Autowiredprivate UsersMapper usersMapper;@Testvoid contextLoads() {List<Users> users = usersMapper.selectList(null);System.out.println(users);}}
通过后,即可开始实现通过自己数据库进行登陆功能:
先创建返回的验证类
LoginUser 实现 UserDetails
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginUser implements UserDetails {private Users user;@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return null;}@Overridepublic String getPassword() {return user.getPassword();}@Overridepublic String getUsername() {return user.getUsername();}@Overridepublic boolean isAccountNonExpired() {return true;}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;}
}
登陆实现类
@Service
public class UserDetailsServiceImpl implements UserDetailsService {@Autowiredprivate UsersMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//根据用户名查询用户信息LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();wrapper.eq(Users::getUsername,username);Users user = userMapper.selectOne(wrapper);//如果查询不到数据就通过抛出异常来给出提示if(Objects.isNull(user)){throw new RuntimeException("用户名或密码错误");}Collection<? extends GrantedAuthority> authorities = Collections.singletonList(new SimpleGrantedAuthority(user.getRole()));//封装成UserDetails对象返回 return new LoginUser(user,authorities);}
}
由于在Spring Boot 2.3及更高版本中,Spring Security默认不再提供任何内置的PasswordEncoder
。这意味着如果在配置中直接使用明文密码或没有正确配置PasswordEncoder
,你将看到这个异常。这里暂时先使用明文加密。后面将一步步完善加密功能.
在SecurityConfig中加入配置
@Configuration
// 启用WebSecurity的自动配置,以便Spring Security可以管理Web安全
@EnableWebSecurity
public class SecurityConfiguration {// 设置密码加密为明文加密@Beanpublic org.springframework.security.crypto.password.PasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();}// 定义一个名为securityFilterChain的bean,该bean将负责构建和应用安全过滤器链@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {// 配置HttpSecurity对象,定义安全规则http// 授权HTTP请求,定义哪些URL需要什么类型的访问控制.authorizeHttpRequests((authz) -> authz// 允许"/user/login" URL匿名访问.requestMatchers("/user/login").anonymous()// 所有其他请求都需要认证才能访问.anyRequest().authenticated())// 启用HTTP Basic认证,默认情况下提供简单的用户名/密码认证.httpBasic(Customizer.withDefaults());// 构建并返回SecurityFilterChainreturn http.build();}
}
再次访问localhost:8080/Hello后弹出登陆框:
输入任意的用户与密码即可正常访问
3.4 实现角色权限访问
在Controller中定义一个Admin资源类,只有admin用户才能进行访问
@RequestMapping("admin")
@RestController
@Slf4j
public class AdminController {@GetMapping("resourse")public String AdminRole(){return "这是只有管理员用户才能访问的资源";}}
在设置中进行配置
@Configuration
// 启用WebSecurity的自动配置,以便Spring Security可以管理Web安全
@EnableWebSecurity
public class SecurityConfiguration {// 设置密码加密为明文加密@Beanpublic org.springframework.security.crypto.password.PasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();}// 定义一个名为securityFilterChain的bean,该bean将负责构建和应用安全过滤器链@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {// 配置HttpSecurity对象,定义安全规则http// 授权HTTP请求,定义哪些URL需要什么类型的访问控制.authorizeHttpRequests((authz) -> authz.requestMatchers("/user/login").anonymous()
// 需要有Admin身份的用户才能进行访问.requestMatchers("/admin/**").hasRole("ADMIN")// 所有其他请求都需要认证才能访问.anyRequest().authenticated())// 启用HTTP Basic认证,默认情况下提供简单的用户名/密码认证.httpBasic(Customizer.withDefaults());// 构建并返回SecurityFilterChainreturn http.build();}
}
重启服务器后分别用两种身份进行访问
用户访问:
管理员访问:
3.5 对密码进行B加密
config中进行配置BCrypt
@Configuration
// 启用WebSecurity的自动配置,以便Spring Security可以管理Web安全
@EnableWebSecurity
public class SecurityConfiguration {@Autowiredprivate UserDetailsServiceImpl userDetailsService;// 设置密码加密为B加密@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}protected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService);}// 定义一个名为securityFilterChain的bean,该bean将负责构建和应用安全过滤器链@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {// 配置HttpSecurity对象,定义安全规则http// 授权HTTP请求,定义哪些URL需要什么类型的访问控制.authorizeHttpRequests((authz) -> authz.requestMatchers("/user/login").anonymous()
// 需要有Admin身份的用户才能进行访问.requestMatchers("/admin/**").hasRole("ADMIN")// 所有其他请求都需要认证才能访问.anyRequest().authenticated())// 启用HTTP Basic认证,默认情况下提供简单的用户名/密码认证.httpBasic(Customizer.withDefaults());// 构建并返回SecurityFilterChainreturn http.build();}
}
由于数据库中都是明文的密码,所以这里可以通过创建一个SpringbootTest类,将所有用户的密码改为B加密后的数据.
@Testpublic void testUpdateAllPasswords() {// 创建一个BCryptPasswordEncoder实例BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();// 更新所有用户的密码为加密后的"123456"String encodedPassword = encoder.encode("123456");// 构造更新条件LambdaUpdateWrapper<Users> updateWrapper = new LambdaUpdateWrapper<>();updateWrapper.set(Users::getPassword, encodedPassword);// 执行更新操作boolean result = usersMapper.update(null, updateWrapper) > 0;if (result) {System.out.println("所有用户的密码更新成功!");} else {System.out.println("密码更新失败!");}}
配置好后,重新进行登陆查看输入对应的admin1和123456
3.6 结合Jwt实现多重校验
Spring Security 和 JSON Web Tokens (JWT) 可以协同工作来提供更灵活和安全的身份验证和授权机制。尽管 Spring Security 提供了一套全面的安全框架,但它默认使用基于会话的认证机制,这意味着服务器维护着与客户端的活动会话状态。而JWT提供了一种无状态的认证方式,这意味着每个请求都包含完整的认证信息,无需服务器保存会话状态。
pom文件中引入jwt所需要的依赖
<!-- JWT依赖--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
Jwt资源类:
@Component
@ConfigurationProperties(prefix = "jwt")
@Data
public class JwtProperties {private String SecretKey;private long Ttl;private String TokenName;}
Jwt yml配置:
jwt:secret-key: Alphamilktoken-name: Authorizationttl: 10800000
实现Jwt的工具类
@Component
public class JwtUtil {@Autowiredprivate JwtProperties jwtProperties;public String createJWT(Map<String, Object> claims, long ttlMillis) {SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;long expMillis = System.currentTimeMillis() + ttlMillis;Date exp = new Date(expMillis);return Jwts.builder().setClaims(claims).signWith(signatureAlgorithm, jwtProperties.getSecretKey().getBytes(StandardCharsets.UTF_8)).setExpiration(exp).compact();}public Claims parseJWT(String token) {return Jwts.parser().setSigningKey(jwtProperties.getSecretKey().getBytes(StandardCharsets.UTF_8)).parseClaimsJws(token).getBody();}public boolean isTokenValid(String token, UserDetails userDetails) {final String username = getUsernameFromToken(token);return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));}private String getUsernameFromToken(String token) {Claims claims = parseJWT(token);return (String) claims.getSubject();}private boolean isTokenExpired(String token) {try {final Date expiration = parseJWT(token).getExpiration();return expiration.before(new Date());} catch (ExpiredJwtException e) {return true;}}
}
Jwt的校验Filter
@Component
public class JwtFilter extends OncePerRequestFilter {@Autowiredprivate JwtProperties jwtProperties;@Autowiredprivate UserDetailsService userDetailsService;@Autowiredprivate JwtUtil jwtUtil;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {String token = request.getHeader(jwtProperties.getTokenName());if (token != null) {try {Claims claims = jwtUtil.parseJWT(token);String username = (String) claims.get("userName");if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);if (jwtUtil.isTokenValid(token, userDetails)) {UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());SecurityContextHolder.getContext().setAuthentication(authentication);}}} catch (ExpiredJwtException ex) {response.sendError(HttpServletResponse.SC_FORBIDDEN, "Token has expired.");} catch (JwtException ex) {response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid token.");}}else {response.sendError(HttpServletResponse.SC_FORBIDDEN, "No token provided.");}filterChain.doFilter(request, response);}
}
将jwt校验规则加入到Spring的Filter中进行校验
@Configuration
// 启用WebSecurity的自动配置,以便Spring Security可以管理Web安全
@EnableWebSecurity
public class SecurityConfiguration {@Autowiredprivate JwtFilter jwtFilter;@Autowiredprivate UserDetailsServiceImpl userDetailsService;// 设置密码加密为B加密@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}protected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService);}// 定义一个名为securityFilterChain的bean,该bean将负责构建和应用安全过滤器链@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {// 配置HttpSecurity对象,定义安全规则http// 授权HTTP请求,定义哪些URL需要什么类型的访问控制.authorizeHttpRequests((authz) -> authz.requestMatchers("/user/login").anonymous()
// 需要有Admin身份的用户才能进行访问.requestMatchers("/admin/**").hasRole("ADMIN")// 所有其他请求都需要认证才能访问.anyRequest().authenticated())// 启用HTTP Basic认证,默认情况下提供简单的用户名/密码认证.httpBasic(Customizer.withDefaults());
// 加入jwtFIlterhttp.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);// 构建并返回SecurityFilterChainreturn http.build();}
}
相关文章:

新版SpringSecurity5.x使用与配置
目录 一、了解SpringSecurity 1.1 什么是Spring Security? 1.2 Spring Security功能 1.3 Spring Security原理 1.4 RABC (Role-Based Access Control) 二、SpringSecurity简单案例 2.1 引入SpringSecurity依赖 2.2 创建一个简单的Controller 三、SpringSecu…...
JavaScript实战 - JavaScript 中实现线程锁
作者:逍遥Sean 简介:一个主修Java的Web网站\游戏服务器后端开发者 主页:https://blog.csdn.net/Ureliable 觉得博主文章不错的话,可以三连支持一下~ 如有需要我的支持,请私信或评论留言! 前言: …...

基于PaddleClas的人物年龄分类项目
目录 一、任务概述 二、算法研发 2.1 下载数据集 2.2 数据集预处理 2.3 安装PaddleClas套件 2.4 算法训练 2.5 静态图导出 2.6 静态图推理 三、小结 一、任务概述 最近遇到个需求,需要将图像中的人物区分为成人和小孩,这是一个典型的二分类问题…...

20240725java的Controller、DAO、DO、Mapper、Service层、反射、AOP注解等内容的学习
在Java开发中,controller、dao、do、mapper等概念通常与MVC(Model-View-Controller)架构和分层设计相关。这些概念各自承担着不同的职责,共同协作以构建和运行一个应用程序。以下是这些概念的解释:…...
dynslam的安装
1. 安装opencv 2.4.9 下载opencv2.4.9 apt-get install build-essential apt-get install libgtk2.0-dev libavcodec-dev libavformat-dev libtiff4-dev libswscale-dev libjasper-dev apt-get install cmake apt-get install pkg-config 进入安装包文件: m…...

stats 监控 macOS 系统
Stats 监控 macOS 系统 CPU 利用率GPU 利用率内存使用情况磁盘利用率网络使用情况电池电量 brew install stats参考 stats github...
后端面试题日常练-day05 【Java基础】
题目 希望这些选择题能够帮助您进行后端面试的准备,答案在文末 在Java中,以下哪个关键字用于表示方法重写(Override)? a) override b) overrule c) overwrite d) supercede Java中的HashMap和Hashtable有什么区别&am…...

mac|安装PostgreSQL
1、官网下载:EDB: Open-Source, Enterprise Postgres Database Management 选择需要的版本: 双击得到的.dmg文件 双击,弹窗选择打开,一路next,然后输入你要设置的密码,默认账号名字为:postgres…...

内网对抗-隧道技术篇防火墙组策略FRPNPSChiselSocks代理端口映射C2上线
知识点: 1、隧道技术篇-传输层-工具项目-Frp&Nps&Chisel 2、隧道技术篇-传输层-端口转发&Socks建立&C2上线Frp Frp是专注于内网穿透的高性能的反向代理应用,支持TCP、UDP、HTTP、HTTPS等多种协议。可以将内网服务以安全、便捷的方式通过…...

arinc664总线协议
AFDX总线协议简介 (1)AFDX的传输速率高:带宽100MHZ,远远高于其他的类型的航空总线。(2)AFDX网络的鲁棒性高:AFDX的双冗余备份网络可以在某一个网络出现故障时,仍能正常通讯。 其中…...
UNIX 域协议
1. UNIX域协议 利用socket编程接口实现本地进程间通信 UNIX域协议套接字:可以使用TCP,也可以使用UDP SOCK_STREAM -----> TCP 面向字节流 SOCK_DGRAM -----> UDP 面向数据报 UNIX域协议并不是一个实际的协议族,而是在单个主机上执…...

昇思25天学习打卡营第17天|LLM-基于MindSpore的GPT2文本摘要
打卡 目录 打卡 环境准备 准备阶段 数据加载与预处理 BertTokenizer 部分输出 模型构建 gpt2模型结构输出 训练流程 部分输出 部分输出2(减少训练数据) 推理流程 环境准备 pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspo…...

Clion开发STM32——移植FreeModbus
STM32型号 :STM32H743VIT6 FreeModbus版本 :1.6 使用工具:stm32cubeMX,Clion 使用STM32作从机,模式:RTU 网上用keil的比较多,用Clion的比较少,如果你也用Clion,那么希望…...
c++栈笔记
一种常见的数据结构,遵循后进先出,先进后出的原则。地址不连续,栈顶(top) 1.常见函数 stack<int> s;定义一个参数类型为int 的栈 名为ss.push()向栈中插入元素s.emplace()压栈,无返回值s.pop()删除…...

Oracle配置TCPS加密协议测试
文章目录 一、环境信息二、配置过程1.创建证书2.监听配置2.1.配置sqlnet.ora2.2.配置listener.ora文件2.3.配置tnsnames.ora文件2.4.重载监听 3.数据库本地测试3.1. tcps登录测试3.2.日志监控 一、环境信息 操作系统:Linux 版本信息:Oracle 19c 参考文档…...

Jetpack Compose 通过 OkHttp 发送 HTTP 请求的示例
下面是一个使用 Kotlin 和 Jetpack Compose 来演示通过 OkHttp 发送 HTTP 请求的示例。这个示例包括在 Jetpack Compose 中发送一个 GET 请求和一个 POST 请求,并显示结果。 添加okhttp依赖 首先,在你的 build.gradle.kts 文件中添加必要的依赖…...

Pytorch使用教学3-特殊张量的创建与类型转化
1 特殊张量的创建 与numpy类似,PyTorch中的张量也有很多特殊创建的形式。 zeros:全0张量 # 形状为2行3列 torch.zeros([2, 3]) # tensor([[0., 0., 0.], # [0., 0., 0.]])ones:全1张量 # 形状为2行3列 torch.ones([2, 3]) # tensor([[1., 1., 1.], # …...

【日记】办个护照不至于有这种刑事罪犯一样的待遇吧……(737 字)
正文 暴晒,中午出去骑共享单车,座垫都不敢坐。 至于为什么,中午觉都不睡跑出去,是因为今天他们办承兑汇票的业务,搞了一天,中午不休息,说可能还会用到我的指纹,让我 on call。我心想…...
【矩阵微分】在不涉及张量的前提下计算矩阵对向量的导数并写出二阶泰勒展开
本篇内容摘自CMU 16-745最优控制的第10讲 “Nonlinear Trajectory Optimization”。 如何在不涉及张量运算的前提下,计算矩阵对向量的导数并写出二阶泰勒展开 在多维微积分中,计算矩阵对向量的导数和二阶泰勒展开是一项重要的任务。本文将介绍如何在不涉…...

数据结构之判断平衡二叉树详解与示例(C,C++)
文章目录 AVL树定义节点定义计算高度获取平衡因子判断是否为平衡二叉树完整示例代码结论 在计算机科学中,二叉树是一种非常重要的数据结构。它们被广泛用于多种算法中,如排序、查找等。然而,普通的二叉树在极端情况下可能退化成链表ÿ…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...