当前位置: 首页 > news >正文

新版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&#xff1f; 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 中实现线程锁

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有需要我的支持&#xff0c;请私信或评论留言&#xff01; 前言&#xff1a; …...

基于PaddleClas的人物年龄分类项目

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

20240725java的Controller、DAO、DO、Mapper、Service层、反射、AOP注解等内容的学习

在Java开发中&#xff0c;‌controller、‌dao、‌do、‌mapper等概念通常与MVC&#xff08;‌Model-View-Controller&#xff09;‌架构和分层设计相关。‌这些概念各自承担着不同的职责&#xff0c;‌共同协作以构建和运行一个应用程序。‌以下是这些概念的解释&#xff1a;‌…...

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 进入安装包文件&#xff1a; m…...

stats 监控 macOS 系统

Stats 监控 macOS 系统 CPU 利用率GPU 利用率内存使用情况磁盘利用率网络使用情况电池电量 brew install stats参考 stats github...

后端面试题日常练-day05 【Java基础】

题目 希望这些选择题能够帮助您进行后端面试的准备&#xff0c;答案在文末 在Java中&#xff0c;以下哪个关键字用于表示方法重写&#xff08;Override&#xff09;&#xff1f; a) override b) overrule c) overwrite d) supercede Java中的HashMap和Hashtable有什么区别&am…...

mac|安装PostgreSQL

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

内网对抗-隧道技术篇防火墙组策略FRPNPSChiselSocks代理端口映射C2上线

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

arinc664总线协议

AFDX总线协议简介 &#xff08;1&#xff09;AFDX的传输速率高&#xff1a;带宽100MHZ&#xff0c;远远高于其他的类型的航空总线。&#xff08;2&#xff09;AFDX网络的鲁棒性高&#xff1a;AFDX的双冗余备份网络可以在某一个网络出现故障时&#xff0c;仍能正常通讯。 其中…...

UNIX 域协议

1. UNIX域协议 利用socket编程接口实现本地进程间通信 UNIX域协议套接字&#xff1a;可以使用TCP&#xff0c;也可以使用UDP SOCK_STREAM -----> TCP 面向字节流 SOCK_DGRAM -----> UDP 面向数据报 UNIX域协议并不是一个实际的协议族&#xff0c;而是在单个主机上执…...

昇思25天学习打卡营第17天|LLM-基于MindSpore的GPT2文本摘要

打卡 目录 打卡 环境准备 准备阶段 数据加载与预处理 BertTokenizer 部分输出 模型构建 gpt2模型结构输出 训练流程 部分输出 部分输出2&#xff08;减少训练数据&#xff09; 推理流程 环境准备 pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspo…...

Clion开发STM32——移植FreeModbus

STM32型号 &#xff1a;STM32H743VIT6 FreeModbus版本 &#xff1a;1.6 使用工具&#xff1a;stm32cubeMX&#xff0c;Clion 使用STM32作从机&#xff0c;模式&#xff1a;RTU 网上用keil的比较多&#xff0c;用Clion的比较少&#xff0c;如果你也用Clion&#xff0c;那么希望…...

c++栈笔记

一种常见的数据结构&#xff0c;遵循后进先出&#xff0c;先进后出的原则。地址不连续&#xff0c;栈顶&#xff08;top&#xff09; 1.常见函数 stack<int> s;定义一个参数类型为int 的栈 名为ss.push()向栈中插入元素s.emplace()压栈&#xff0c;无返回值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.日志监控 一、环境信息 操作系统&#xff1a;Linux 版本信息&#xff1a;Oracle 19c 参考文档…...

Jetpack Compose 通过 OkHttp 发送 HTTP 请求的示例

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

Pytorch使用教学3-特殊张量的创建与类型转化

1 特殊张量的创建 与numpy类似&#xff0c;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 字)

正文 暴晒&#xff0c;中午出去骑共享单车&#xff0c;座垫都不敢坐。 至于为什么&#xff0c;中午觉都不睡跑出去&#xff0c;是因为今天他们办承兑汇票的业务&#xff0c;搞了一天&#xff0c;中午不休息&#xff0c;说可能还会用到我的指纹&#xff0c;让我 on call。我心想…...

【矩阵微分】在不涉及张量的前提下计算矩阵对向量的导数并写出二阶泰勒展开

本篇内容摘自CMU 16-745最优控制的第10讲 “Nonlinear Trajectory Optimization”。 如何在不涉及张量运算的前提下&#xff0c;计算矩阵对向量的导数并写出二阶泰勒展开 在多维微积分中&#xff0c;计算矩阵对向量的导数和二阶泰勒展开是一项重要的任务。本文将介绍如何在不涉…...

数据结构之判断平衡二叉树详解与示例(C,C++)

文章目录 AVL树定义节点定义计算高度获取平衡因子判断是否为平衡二叉树完整示例代码结论 在计算机科学中&#xff0c;二叉树是一种非常重要的数据结构。它们被广泛用于多种算法中&#xff0c;如排序、查找等。然而&#xff0c;普通的二叉树在极端情况下可能退化成链表&#xff…...

深入解析仓颉编程语言:函数式编程的核心特性

摘要 仓颉编程语言以其独特的语法和功能&#xff0c;为开发者提供了强大的编程工具。本文将深入探讨仓颉语言中的嵌套函数、Lambda 表达式和闭包等函数式编程的核心特性&#xff0c;帮助开发者更好地理解和利用这些工具。 引言 在现代编程语言中&#xff0c;函数式编程范式越…...

springboot惠农服务平台-计算机毕业设计源码50601

目录 1 绪论 1.1 研究背景 1.2研究意义 1.3论文结构与章节安排 2 惠农服务平台app 系统分析 2.1 可行性分析 2.2 系统功能分析 2.3 系统用例分析 2.4 系统流程分析 2.5本章小结 3 惠农服务平台app 总体设计 3.1 系统功能模块设计 3.2 数据库设计 表access_token (…...

Lua脚本简单理解

目录 1.安装 2.语法 2.1Lua数据类型 2.2变量 2.3lua循环 2.4流程控制 2.5函数 2.6运算符 2.7关系运算符 3.lua脚本在redis中的使用 3.1lua脚本再redis简单编写 3.2普通锁Lua脚本 3.3可重入锁lua脚本 1.安装 centos安装 安装指令&#xff1a; yum -y update yum i…...

AutoSAR自适应平台架构总览--AP的初认识

AutoSAR自适应平台架构总览:AP 基础设施层&#xff08;Foundation Layer&#xff09;核心操作系统&#xff08;Core OS&#xff09;通信管理&#xff08;Communication Management&#xff09; 服务层&#xff08;Services Layer&#xff09;诊断服务&#xff08;Diagnostics S…...

GPT-4o Mini:探索最具成本效益的小模型在软件开发中的应用

随着人工智能技术的迅猛发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域也取得了显著的进步。OpenAI 最新发布的 GPT-4o Mini 模型&#xff0c;以其卓越的性能和极具竞争力的价格&#xff0c;成为了广大开发者关注的焦点。作为一名长期关注人工智能及其在软件开发…...

{Spring Boot 原理篇} Spring Boot自动装配原理

SpringBootApplication 1&#xff0c;Spring Boot 应用启动&#xff0c;SpringBootApplication标注的类就是启动类&#xff0c;它去实现配置类中的Bean的自动装配 SpringBootApplication public class SpringbootRedis01Application {public static void main(String[] args)…...

QEMU源码全解析 —— CPU虚拟化(10)

接前一篇文章: 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社 《深度探索Linux系统虚拟化原理与实现》—— 王柏生 谢广军, 机械工业出版社 特此致谢! 二、x86架构CPU虚拟化 3. VMX 上一回讲解了支…...

46、PHP实现矩阵中的路径

题目&#xff1a; PHP实现矩阵中的路径 描述&#xff1a; 请设计一个函数&#xff0c;用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。 路径可以从矩阵中的任意一个格子开始&#xff0c;每一步可以在矩阵中向左&#xff0c;向右&#xff0c;向上&#xff0c;向…...

c++笔记2

目录 2.2 栈底&#xff08;bottom&#xff09; } 大数乘大数 节点&#xff1a;包含一个数据元素及若干指向子树分支的信息 。 节点的度&#xff1a;一个节点拥有子树的数目称为节点的度 。 叶子节点&#xff1a;也称为终端节点&#xff0c;没有子树的节点或者度为零的节点…...

通过Lua脚本手写redis分布式锁

1、手写 Redis 分布式锁&#xff0c;包括上锁、解锁、自动续期。 此功能实现采用 Lua脚本实现&#xff0c;Lua脚本可以保证原子性。 setnx可以实现分布式锁&#xff0c;但是无法实现可重入锁&#xff0c;所以用hset来代替setnx实现可重入的分布式锁。 -- lock if redis.call…...

解析银行个人征信系统

银行个人征信系统&#xff0c;也被称为个人信用信息基础数据库或金融信用信息基础数据库&#xff0c;是我国社会信用体系的重要基础设施。该系统由中国人民银行组织国内相关金融机构建立&#xff0c;旨在依法采集、整理、保存、加工自然人&#xff08;法人&#xff09;及其他组…...

AttributeError: ‘list‘ object has no attribute ‘text‘

AttributeError: ‘list‘ object has no attribute ‘text‘ 目录 AttributeError: ‘list‘ object has no attribute ‘text‘ 【常见模块错误】 【解决方案】 示例代码 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英…...

Codeforces Round 874 (Div. 3)(A~D题)

A. Musical Puzzle 思路: 用最少的长度为2的字符串按一定规则拼出s。规则是&#xff1a;前一个字符串的尾与后一个字符串的首相同。统计s中长度为2的不同字符串数量。 代码: #include<bits/stdc.h> #include <unordered_map> using namespace std; #define N 20…...

[Python][基础语法]详细讲解

目录 1.顺序语句2.条件语句3.缩进和代码块4.空语句 pass5.循环语句1.while2.for3.continue4.break ∞.积累 1.顺序语句 默认情况下&#xff0c;Python的代码执行顺序是按照从上到下的顺序&#xff0c;依次执行# 输出结果&#xff1a;"123" print("1") pri…...

Layui---输入事件

输入实时监听 //监听表单单选框复选框选择 form.on(radio, function (data) {console.log(data.value); //得到被选中的值 });//监听表单下拉菜单选择form.on(select, function (data) //监听表单下拉菜单选择form.on(select, function (data) ​ //监听表单复选框选择form.…...

甄选范文“论软件测试中缺陷管理及其应用”软考高级论文,系统架构设计师论文

论文真题 软件缺陷指的是计算机软件或程序中存在的某种破坏正常运行能力的问题、错误,或者隐藏的功能缺陷。缺陷的存在会导致软件产品在某种程度上不能满足用户的需要。在目前的软件开发过程中,缺陷是不可避免的。软件测试是发现缺陷的主要手段,其核心目标就是尽可能多地找…...

spring框架实现滑动验证码功能

spring框架实现滑动验证码功能 1. 整体描述2. 具体实现2.1 滑动验证码实体类2.2 滑动验证码登录VO2.3 滑动验证码接口返回类2.4 滑动验证码工具类2.5 滑动验证码Service2.6 滑动验证码Controller 3 工程源码4 总结 1. 整体描述 之前项目需要在验证码模块&#xff0c;增加滑动验…...

Pytorch使用教学8-张量的科学运算

在介绍完PyTorch中的广播运算后&#xff0c;继续为大家介绍PyTorch的内置数学运算&#xff1a; 首先对内置函数有一个功能印象&#xff0c;知道它的存在&#xff0c;使用时再查具体怎么用其次&#xff0c;我还会介绍PyTorch科学运算的注意事项与一些实用小技巧 1 基本数学运算…...

[Spring Boot]登录密码三种加密方式

简述 介绍其三种密码加密方法 1.SM2加密与验签 2.随机密码盐加密 3.MD5加密 推荐使用方法1&#xff0c;其次使用方法2&#xff0c;最不推荐的是方法3。方法3极其容易被密码字典破解&#xff0c;如果项目进行安全测试&#xff0c;通常是不允许的加密方式。 SM2加密与验签 引入…...

前端面试项目细节重难点分享(十三)

面试题提问&#xff1a;分享你最近做的这个项目&#xff0c;并讲讲该项目的重难点&#xff1f; 答&#xff1a;最近这个项目是一个二次迭代开发项目&#xff0c;迭代周期一年&#xff0c;在做这些任务需求时&#xff0c;确实有很多值得分享的印象深刻的点&#xff0c;我讲讲下面…...

每天五分钟深度学习:向量化方式完成逻辑回归m个样本的前向传播

本文重点 我们已经知道了向量化可以明显的加速程序的运行速度,本节课程将使用向量化来完成逻辑回归的前向传播,不使用一个for循环。 逻辑回归的前向传播 我们先来回忆一下逻辑回归的前向传播,如果我们有m个训练样本,首先对第一个样本进行预测,我们需要计算z,然后计算预…...

以线程完成并发的UDP服务端

网络(九)并发的UDP服务端 以线程完成功能 客户端 // todo UDP发送端 #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <stdlib.h> #include <string.h…...

linux c 特殊字符分割

/* * brief: 根据split_symbol分割字符串 * param: str为要分割的字符串&#xff0c;split_symbol是分隔符 * return&#xff1a;返回garray的指针数组&#xff0c;如果返回非空需要自己处理释放 */ GPtrArray_autoptr char_sz_spilt(pchar* str, pchar split_symbol) {if (NUL…...

搭建本地私有知识问答系统:MaxKB + Ollama + Llama3 (wsl网络代理配置、MaxKB-API访问配置)

目录 搭建本地私有知识问答系统:MaxKB、Ollama 和 Llama3 实现指南引言MaxKB+Ollama+Llama 3 Start buildingMaxKB 简介:1.1、docker部署 MaxKB(方法一)1.1.1、启用wls或是开启Hyper使用 WSL 2 的优势1.1.2、安装docker1.1.3、docker部署 MaxKB (Max Knowledge Base)MaxKB …...

谷粒商城实战笔记-65-商品服务-API-品牌管理-表单校验自定义校验器

文章目录 1&#xff0c;el-form品牌logo图片自定义显示2&#xff0c;重新导入和注册element-ui组件3&#xff0c;修改brand-add-or-update.vue控件的表单校验规则firstLetter 校验规则sort 校验规则 1&#xff0c;el-form品牌logo图片自定义显示 为了在品牌列表中自定义显示品…...

学好C++之——命名空间

c开始学习之时&#xff0c;你不可避免会遇到一个新朋友&#xff0c;那就是——namespace&#xff08;命名空间&#xff09;。 那么这篇文章就来为你解决这个小麻烦喽~ 目录 1.namespace存在的意义 2.namespace的定义 3.namespace的使用 1.namespace存在的意义 在C中&#…...

pytorch lightning报错all tensors to be on the same device

RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu! 修改指定为gpu trainer pl.Trainer(max_epochstrain_params.iterations, loggertb_logger,acceleratorgpu, devices1)...

Redis中的哨兵(Sentinel)

上篇文章我们讲述了Redis中的主从复制&#xff08;Redis分布式系统中的主从复制-CSDN博客&#xff09;&#xff0c;本篇文章针对主从复制中的问题引出Redis中的哨兵&#xff0c;希望本篇文章会对你有所帮助。 文章目录 一、引入哨兵机制 二、基本概念 三、主从复制的问题 四、哨…...

产业创新研究杂志产业创新研究杂志社产业创新研究编辑部2024年第12期目录

高质量发展 如何在新一轮产业链变革中平稳应对挑战 王宏利; 1-3《产业创新研究》投稿&#xff1a;cnqikantg126.com 基于ERGM的城市间绿色低碳技术专利转让网络结构及演化研究 吕彦朋;姜军;张宁; 4-6 数字基础设施建设对城市FDI的影响——基于“宽带中国”试点政策…...

网闸(Network Gatekeeper或Security Gateway)

本心、输入输出、结果 文章目录 网闸(Network Gatekeeper或Security Gateway)前言网闸主要功能网闸工作原理网闸使用场景网闸网闸(Network Gatekeeper或Security Gateway) 编辑 | 简简单单 Online zuozuo 地址 | https://blog.csdn.net/qq_15071263 如果觉得本文对你有帮助…...