【Spring Security第一篇】初始Spring Security、表单认证、认证与授权

news2024/11/16 16:32:36

文章目录

  • 一、初识Spring Security
    • 1. Spring Security简介
    • 2. 第一个Spring Security项目(XML文件配置)
    • 3. 第一个Spring Security项目(自动配置)
    • 4. 配置Security账户
  • 二、表单认证
    • 1. Web 应用中基于密码的身份认证机制
    • 2. 默认表单认证
    • 3. 自定义表单登录页
  • 三、认证与授权
    • 1. 默认数据库模型的认证与授权
    • 2. 基于内存的多用户多角色支持
    • 3. 基于默认数据库数据库的认证与授权
    • 4. 自定义数据库模型的认证与授权

一、初识Spring Security

1. Spring Security简介

应用程序的安全性通常体现在两个方面:认证和授权

认证:确认登录系统的用户在某系统中是否合法、可用的过程。
授权:当主体通过认证之后,是否允许其执行某项操作的过程。

2. 第一个Spring Security项目(XML文件配置)

首先我们为Spring Security专门建立一个Spring的配置文件spring-security.xml,该文件就专门用来作为Spring Security的配置。
spring-security.xml 文件框架

<!--命名空间-->
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:security="http://www.springframework.org/schema/security"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.1.xsd">
	
	<!--Web/Http安全:当访问受保护的URL时会将用户引入登录界面或者是错误提示界面-->
	<!--业务对象或者方法的安全:控制方法访问权限-->
	<!--AuthenticationManager:处理来自于框架的认证请求-->
	<!--AccessDecisionManager:为Web或方法的安全提供访问决策-->
	<!--AuthenticationProvider:用来认证用户-->
	<!--UserDetailsService:跟AuthenticationProvider关系密切,用来获取用户信息-->
</beans>

Spring Security 初体验
spring-security.xml

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:security="http://www.springframework.org/schema/security"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.1.xsd">

	<!--http元素是用来定义Web相关权限控制的-->
   <security:http auto-config="true">
      <security:intercept-url pattern="/**" access="ROLE_USER"/>
   </security:http>    

	<!--有了权限的控制的而规则之后,接下来我们需要定义一个AuthenticationManager用于认证-->
   <security:authentication-manager>
      <security:authentication-provider>
         <security:user-service>
            <security:user name="user" password="user" authorities="ROLE_USER"/>
            <security:user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN"/>
         </security:user-service>
      </security:authentication-provider>
   </security:authentication-manager>

</beans>

Spring核心配置文件Application.xml
之后我们告诉的Spring加载这个配置文件,我们可以在 web.xml 文件中通过 context-param 把它指定为 Spring 的初始配置文件,也可以在对应 Spring 的初始配置文件中引入它。这里我们采用前者。

<!--将Spring配置文件设置为spring-security.xml文件-->
<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>/WEB-INF/config/applicationContext.xml,/WEB-INF/config/spring-security.xml</param-value>
</context-param>

<!--通过ContextLoaderListener来加载和初始化Spring配置文件,这里初始化spring-security.xml-->
<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!--定义一个filter用来拦截需要交给Spring Security处理的请求-->
<filter>
   <filter-name>springSecurityFilterChain</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
   <filter-name>springSecurityFilterChain</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

接下来可以启动我们的应用,然后在浏览器中访问我们的主页。你会看到如下页面。
在这里插入图片描述
因为我们的 spring-security.xml 文件中配置好了所有的请求都需要 “ROLE_USER” 权限,所以当我们在请求主页的时候,Spring Security 发现我们还没有登录,Spring 会引导我们到登录界面。使用正确的用户名和密码(如上面配置的 user/user 或 admin/admin)登录后,如果符合对应的权限我们就可以访问主页了,否则将出现 403(禁止访问)界面。

3. 第一个Spring Security项目(自动配置)

添加模块中得pom依赖

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

创建Web接口

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {

        return "Hello, 来跟 一一哥 学习 Spring Security吧!";
    }
}

创建项目入口类

package com.yyg.security;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Demo01Application {

    public static void main(String[] args) {

        SpringApplication.run(Demo01Application.class, args);
    }

}

启动项目
在访问/hello接口之前会自动跳转到/login地址,进入到一个登录界面。这是因为Spring Boot中"约定大约配置"的规则,只要我们添加了Spring Security的依赖包,就会自动开启安全限制,在访问Web接口之前会进行安全拦截。只有输入了用户名和密码,才能访问项目中的Web接口/hello
在这里插入图片描述
这个默认的用户名是“user”,密码是一个用UUID生成的随机字符串。在每次启动项目时,都可以在控制台中看到生成的随机密码,如下图所示:
在这里插入图片描述
我们只要把这个随机密码,复制粘贴到登录页面的密码框中,就可以访问"/hello"接口了。
在这里插入图片描述

4. 配置Security账户

我们在application.yml中配置Spring Security的自定义账户。

spring:
  security:
    user:
      name: yyg
      password: 123

在这里配置了自定义的用户名和密码后,在Spring Security的源码中,会通过调用SecurityProperties的 set()方法 注入到对应的属性中。我们来看下 SecurityProperties.User#setPassword() 方法的源码:

public void setPassword(String password){
	if(!StringUtils.hasLength(password)){
		return;
	}
	this.passwordGenerated = false;
	this.password = password;
}

由此我们可以看到,passwordGenerated属性变成了false,结合上文的源码分析,我们就知道在控制台不会再输出打印密码信息了。

重启项目
接着我们重启项目,这时候利用我们自己配置的用户名和密码,就可以访问"/hello"接口了。
在这里插入图片描述

二、表单认证

1. Web 应用中基于密码的身份认证机制

认证(Authentication)

一、基于密码的认账过程
1. 服务器从客户端获取用户账密
2. 服务器将拿到的账密和数据库中保存的账密进行比较,确认正确后生成用户身份信息
3. 客户端从服务器获取用户身份信息

二、存在的两种问题
1. 当提供方与使用方能够共享数据库,不必跨网络和安全边界进行交互时,需要考虑一个问题:按照什么流程、什么格式能够安全可靠地把用户账密从客户端传递给服务器。
2. 当提供方与使用方独立部署,必须跨网络和安全边界进行交互时,不仅仅需要考虑上面问题,还需要考虑:按照什么流程、什么格式能够安全可靠地把用户身份信息从服务器传给客户端。

三、上述两种问题的解决办法
【Question1】的解决办法:表单认证、HTTP Basic认证、HTTP Digest认证、HTTP Mutual认证
【Question2】的解决方法:OIDC、SAML 、WS-Federation、Windows AD

表单认证

1. 客户端请求访问受保护的资源(目标URI:GET localhost/resource)。
2. 目标URI收到请求后,将检查用户是否登录(是否携带了指定cookie,校验cookie值)。如果用户未登录,则返回303,通过浏览器将客户端重定向到登录页面(GET localhost/login.html)。
3. 用户在登录页面的表单中输入账密,提交表单时调用验证账密接口(POST localhost/user_pass/verify),请求体传参为用户名、加密密码、目标URI。
4. 验证账密接口(POST localhost/user_pass/verify)校验收到的传参:
	(1)如果账密正确,则颁发登录凭证(设置指定cookie),返回303,通过浏览器将客户端重定向到目标URI。
	(2)如果账密错误,则返回303,通过浏览器将客户端重定向到错误页面。
5. 目标URI收到请求后,发现用户已登录,则检查用户权限:
	(1)如果有权限,则返回保护资源作为响应。
	(2)如果权限不足,则重定向到无权访问页面。

HTTP基本认证
1、客户端请求访问受保护的资源(目标URI:GET localhost/resource)。

2、目标URI收到请求后,检查请求头是否包含Authorization字段。如果不包含,则服务器将发起质询,即返回401 Unauthorized响应,响应头带有WWW-Authenticate字段,

  • Basic:表明认证方式为HTTP基本认证。
  • realm:保护空间标识名称,告知客户端自动应用账密的范围
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="example_space_name"

3、客户端收到401的质询响应,要求用户提供账密。客户端按照Basic的规定格式(username:password)对账密进行base64编码,放在请求头Authorization字段中,重新请求目标URI,将账密提交给服务器。

GET /resource HTTP/1.1
Host: localhost
Authorization: Basic cUZFeFZtQlE4blBZOjVjNWVkYjA2OTA2MTZjZGJkNGNmOWMwYjBlMjg3MWVkNjM2MzE2ZTliNjI1NWQzMDA2MDg3NGJm

4、目标URI再次收到请求后,根据realm="example_space_name"这一保护空间采用的认证机制来校验收到的账密。

1. 如果账密正确,则检查用户权限。如果用户有权限,则返回保护资源作为响应。如果没有权限,则返回403 Forbidden作为响应。
2. 如果账密错误,则重复步骤2,即返回401 Unauthorized响应,带有响应头WWW-Authenticate: Basic realm="example_space_name"。

2. 默认表单认证

【Question 1】Security怎么知道我们需要对所有的接口进行验证?Security又是怎么知道我们需要支持基于表单的验证?

【Answer 1】原因是WebSecurityConfigurerAdapter在configure(HttpSecurity http)方法中提供了一个默认的配置,代码如下:

protected void configure(HttpSecurity http) throws Exception {
    ((HttpSecurity)
    	((HttpSecurity)
    		((AuthorizedUrl)http
    			.authorizeRequests()
    			.anyRequest())
    		.authenticated()	// 请求都需要被认证
    		.and())
    	.formLogin()	// 基于表单认证
		.and())
	.httpBasic();	// 配置basic登录
}

3. 自定义表单登录页

但是大多数应用程序都有自己的登录页面,登录接口,接口请求参数名称。
比如不想使用 Security 提供的登录页面,不想调用 login 接口,想改名为 /auth/login,表单参数不想使用 username、password,而是想使用 account、pwd,要做到这一点,只需要配置如下代码:

@Configuration
// @EnableWebSecurity  如果你的项目是 SpringBoot 项目,该注解就没必要写
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(HttpSecurity http) throws Exception {
	    http.authorizeRequests()  //开启配置
	    	.antMatchers("/hello2", "/hello4").permitAll()	//hello2、hello4接口可以直接访问
    	    .anyRequest().authenticated()// 其他请求都要验证:需要登录才能访问
            	.and()	// 还要添加以下要求
            	.formLogin()	// 使用表单认证方式
            	.loginPage("/login.html") //登录页面
            	.loginProcessingUrl("/auth/login") //登录接口,此地址可以不真实存在
            	.usernameParameter("account") //用户名字段
            	.passwordParameter("pwd") //密码字段
            	.defaultSuccessUrl("/hello")  //登录成功的回调
            	.successForwardUrl("/hello3")	//登录成功的回调 
            	.permitAll() // 上述 login.html 页面、/auth/login接口放行
            	.and()
            	.csrf().disable();  // 禁用 csrf 保护
	}
}

我们来设置一下/login.html页面,内容如下,并将其配置在 resources/static 目录下。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
<div id="login">
    <h1>Login</h1>
    <form method="post" action="/auth/login">
        <input type="text" required="required" placeholder="用户名" name="account"></input>
        <input type="password" required="required" placeholder="密码" name="pwd"></input>
        <button class="but" type="submit">登录</button>
    </form>
</div>
</body>
</html>  

配置完成之后,重启项目。请求 /hello 接口,跳转到指定的页面,如下:
在这里插入图片描述

三、认证与授权

在初始Spring Security中默认的安全机制:仅有一个用户,仅有一种角色。在实际开发中,这自然是无法满足需求的,我们可以通过以下不同的方式来增加用户角色。

1. 默认数据库模型的认证与授权

默认controller包下新建三个控制器AdminController、AppController、UserController

@RestController
@RequestMapping("/admin/api")
public class AdminController{
	@GetMapping("/hello")
	public String hello(){
		return "hello, admin";
	}	
}

@RestController
@RequestMapping("/app/api")
public class AppController{
	@GetMapping("/hello")
	public String hello(){
		return "hello, app";
	}	
}

@RestController
@RequestMapping("/user/api")
public class AdminController{
	@GetMapping("/hello")
	public String hello(){
		return "hello, user";
	}	
}

为了能正常访问前面的路由,我们需要进一步地配置Spring Security。

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
	@Override
	protected void configure(HttpSecurity http) throws Exception{
		http.authorizeRequests()
			.antMatchers("/admin/api/**").hasRole("ADMIN")	// admin才能访问这个接口
			.antMatchers("/user/api/**").hasRole("USER")	// 开发者才能访问这个接口
			.antMatchers("/app/api/**").permitAll()			// 所有人能够访问这个接口
			.and()
			.formLogin();
	}
}

重启服务,尝试访问localhost:8080/app/api/hello,页面打印hello,app,验证了/app/api下的服务确实是权限公开的。接着访问localhost:8080/user/api/hello,这次需要登陆了,我们尝试输入前面在application.properties中定义的用户名和密码,登录之后,页面打印hello,user。然而,我们并没user用户的,为什么可以成功访问路由呢?为了验证不是授权环节出了问题,我们尝试访问localhost:8080/admin/api/hello,出现如下图所示。
在这里插入图片描述
页面显示403错误,表示该用户授权失败(401代表该用户认证失败)。也就是说,本次访问已经通过了认证环节,只是在授权的时候被驳回了。认证环节没有问题,是因为Spring Security将所有账户的角色默认为user。

2. 基于内存的多用户多角色支持

到目前为止,我们仍然只有一个可登录的用户,怎样引入多用户的呢?非常简单,我们只需要实现一个自定义的UserDetailsService即可,并且为其添加一个@Bean注解,便可被Spring Security发现并使用。

这是因为Spring Security支持各种来源的用户数据,包括内存、数据库等,它们被抽象为一个UserDetailsService接口。任何实现了UserDetailsService接口的对象都可以作为认证数据源。

@Bean
public UserDetailsService userDetailsService(){
	// InMemoryUserDetailsManager是UserDetailsService接口的实现类
	InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
	manager.createUser(User.withUsername("user").password("123").roles("USER").build());
	manager.createUser(User.withUsername("admin").password("123").roles("ADMIN").build());
	return manager;
}

3. 基于默认数据库数据库的认证与授权

除了上述使用到的I你Memory User DetailsManager,Spring Security还提供了另一个UserDetailsService实现类JdbcUserDetailsManager,这个类可以帮助我们以JDBC方式对接数据库和Spring Security,它设定了一个默认的数据库模型。

首先在工程中引入JDBC和MySQL两个必要依赖
在这里插入图片描述
接着在application.properties中配置数据库连接参数。
在这里插入图片描述
JdbcUserDetailsManager设定了一个默认的数据库模型,Spring Security将该模型定义在了/org/springframework/security/core/userdetails/jdbc/users.ddl

JdbcUserDetailsManager需要两个表,其中users表用来存放用户名、密码和是否可用三个信息。
authorities表用来的存放用户名、权限两个信息。
在这里插入图片描述
但是不能直接将上述语句执行,会报错,因为上述语句是hsqldb创建的,而MySQL不支持varchar_ignorecase这种类型,需要将它变成varchar即可。

下面构建一个JdbcUserDetailsManager实例,让Spring Security使用数据库来管理用户。
在这里插入图片描述
Spring Security通过DataSource执行设定好的命令,例如createUser函数实际上就是执行insert的SQL语句。

现在重启服务,看看在数据库中Spring Security生成了哪些数据。
在这里插入图片描述
在这里插入图片描述

4. 自定义数据库模型的认证与授权

当使用Spring Security默认数据库模型应对各种用户系统时,难免灵活性欠佳,因为已经规定好了数据表及其表的字段。如果对现有的系统做Spring Security嵌入时,原本的用户数据就要做出大的修改来适配Spring Security,这样显然得不偿失,那么强大而灵活的Spring Security对这方面进行了改进。

UserDetailsService仅定义了一个loadUserByUsername方法,用于获取一个UserDetails对象。UserDetails对象包含了的一系列在验证时会用到的信息,Spring Security会根据这些信息判定验证是否成功。

public interface UserDetails extends Serializable{
	
	Collection<? extends GrantedAuthority> getAuthorities();

	String getPassword();

	String getUsername();
	
	boolean isAccountNonExpired();

	boolean isAccount NonLocked();
	
	boolean is CredentialsNonExpired();

	boolean isEnable();
}

也就是说,不管数据库结构如何变化,只要能构造一个UserDetails即可,下面就来实现这个过程。

1. 数据库准备
设计一个自定义的数据库结构。
在这里插入图片描述
2. 编写对应的User实体类,并且实现UserDetails
isAccountNonExpired、isAccountNonLocked、isCredentialsNonExpired暂且用不到,所以统一返回true,否则Spring Security会认为账号异常。

@Data
public class User implements UserDetails{

	private Long id;
	private String username;
	private String password;
	private String roles;
	private boolean enable;

	// 每种角色对应一个GrantedAuthority
	private List<GrantedAuthority>	authorities;

	@Override
	public boolean isAccountNonExpired(){
		return true;
	}

	@Override
	public boolean isAccountNonLocked(){
		return true;
	}
	
	@Override 
	public boolean isCredentialsNonExpired(){
		return true;
	}
	
	@Override
	public boolean isEnabled(){
		return this.enable;
	}

	public void setAuthorities(List<GrantedAuthority> authorities){
		this.authorities = authorities;
	}

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities(){
		return this.authorities;
	}
}

3. 实现User DetailsService
当准备好UserDetails之后,使用数据库持久层框架读取数据并填充对象。

首先编写持久层Mapper。

@Component
public interface UserMapper{
	@Select("SELECT * FROM users WHERE username = #{username}")
	User findByUserName(@Param("username") String username);
}

其次编写UserDetailsService。

@Service	// 一定要加上@Service注解,以便被Spring Security自动发现
public class MyUserDetailsService implementsUserDetailsService{
	
	@Autowired
	private UserMapper userMapper;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
		// 从数据库尝试读取该用户
		User user = userMapper.findByUserName(username);
		// 用户不存在,抛出异常
		if(user == null)
			throw new UsernameNotFoundException("用户不存在")
		// 将数据库形式的roles解析为UserDetails的权限集
		user.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRoles()));
		return user;
	}

	// 自行实现权限的转换
	private List<GrantedAuthority> generatedAuthorities(String roles){
		List<GrantedAuthority> authorities = new ArrayList<>();
		String roleArray = roles.split(";");
		if(roles != null && !"".equals(roles))
			for(String role:roleArray)
				authorities.add(new SimpleGrantedAuthority(role));
		return authorities;
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/487169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于 Rainbond 的混合云管理解决方案

内容概要&#xff1a;文章探讨了混合云场景中的难点、要点&#xff0c;以及Rainbond平台在跨云平台的混合云管理方面的解决方案。包括通过通过统一控制台对多集群中的容器进行编排和管理&#xff0c;实现了对混合云中应用的一致性管理。文章还介绍了Rainbond平台在混合云环境下…

程序员的新电脑应该安装那些环境呢?

换新电脑了&#xff0c;那么作为一名程序员需要安装那些软件呢&#xff1f; 电脑系统版本&#xff1a;Windows11 注意&#xff1a;用户名一定要设置成英文的&#xff0c;否则后面会出现一定的问题&#xff01;&#xff01; 1、配置环境 &#xff08;1&#xff09;JDK环境 h…

HIEE300024R4 UAA326A04电流、电压、功率测量机电指示仪表的选用

​ HIEE300024R4 UAA326A04电流、电压、功率测量机电指示仪表的选用 电流、电压、功率测量机电指示仪表的选用 用于测量电流和电压的仪器类型如下 不 乐器 适用于 1个 PMMC&#xff08;永磁动圈&#xff09; 直流电流 2个 动铁式 交直流 3个 电测力计式 …

vcruntime140_1.dll丢失的解决方法

vcruntime140_1.dll是Microsoft Visual C Redistributable中的一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;是电脑Windows系统中重要的文件&#xff0c;丢失会造成很多软件报错无法运行。有不少小伙伴在打开ps&#xff0c;pr或者游戏的过程中都遇到过这个问题&a…

辅助驾驶功能开发-功能规范篇(16)-2-领航辅助系统NAP-巡航跟车基础功能

接上篇博文 2.3.2.巡航跟车基础功能 巡航跟车基础功能介绍辅助驾驶系统的车速设定,车间时距设定,纵向定速巡航、跟车加减速、起停,横向居中控制,弯道控制等逻辑。 前置条件: (1)NOA功能激活; 2.3.2.1.车速调节 1)激活时初始显示 中控屏设置界面有“融合限速设置”的开…

成功上岸国科大研究生!

Datawhale干货 作者&#xff1a;罗龙&#xff0c;江西财经大学&#xff0c;Datawhale优秀助教 中国科学院大学简介 中国科学院大学&#xff08;University of Chinese Academy of Sciences&#xff09;&#xff0c;简称“国科大”&#xff0c;是一所以研究生教育为主的科教融合…

我群 300+人已熟练使用的 ChatGPT Prompt 技巧

这是吴恩达联合 OpenAI 官方录制的 ChatGPT Prompt 免费视频课&#xff0c;最后一个总结&#xff0c;视频&#xff1a; https://learn.deeplearning.ai/chatgpt-prompt-eng/lesson/2/guidelines 在这一节中&#xff0c;我会分享两个技巧&#xff1a;Transforming 和 Expanding …

搭建electron-vue下

搭建electron-vue下 npm install 后续问题Version 9 of Highlight.js has reached EOL. npm run dev 后续ReferenceError: Unknown plugin "component" specified in ...Error: Cannot find module electron-logCant resolve axios inCant resolve vue-electronCant …

day1_内存区域

文章目录 1 程序计数器2 虚拟机栈(JVM 栈)2.1 基本概念以及演示2.2 栈内存溢出的情况2. 3 线程排查 3 本地方法栈4 堆4.1 堆内存溢出以及诊断 5 方法区 JVM的内存区域&#xff0c;主要分为了5个部分: 方法区&#xff0c; 堆&#xff0c; 程序计数器&#xff0c; 虚拟机栈&#…

解读Toolformer

【引子】读论文Toolformer: Language Models Can Teach Themselves to Use Tools&#xff0c;https://arxiv.org/pdf/2302.04761.pdf&#xff0c;再阅读了几篇关于Toolformer的网络热文&#xff0c;于是“无知者无畏”&#xff0c;开始自不量力地试图解读Toolformer。 大语言模…

《数据安全法》

中华人民共和国数据安全法 &#xff08;2021年6月10日第十三届全国人民代表大会常务委员会第二十九次会议通过&#xff09; 目录 第一章 总则 第二章 数据安全与发展 第三章 数据安全制度 第四章 数据安全保护义务 第五章 政务数据安全与开放 第六章 法律责任 第…

Gradio学习笔记--Gradio基本用法和简单案例

​​​​​​​ 目录 1--配置Gradio 2--Hello World案例 2-1--基本使用 2-2--进阶使用 3--图像案例 3--常用类 Interface 和 Blocks 1--配置Gradio 使用 pip 安装 Gradio&#xff1a; pip install gradio 2--Hello World案例 2-1--基本使用 import gradio as grdef …

代码随想录算法训练营第二十八天 | 三个逗点四个子串的类型题、子集题要取所有节点、子集与树层去重

93.复原IP地址 文档讲解&#xff1a;代码随想录 (programmercarl.com) 视频讲解&#xff1a;回溯算法如何分割字符串并判断是合法IP&#xff1f;| LeetCode&#xff1a;93.复原IP地址_哔哩哔哩_bilibili 状态&#xff1a;不会做。这是三个逗点四个子串的类型题。 思路 这是切割…

重新定义分析 - EventBridge 实时事件分析平台发布

对于日志分析大家可能并不陌生&#xff0c;在分布式计算、大数据处理和 Spark 等开源分析框架的支持下&#xff0c;每天可以对潜在的数百万日志进行分析。 事件分析则和日志分析是两个完全不同的领域&#xff0c;事件分析对实时性的要求更高&#xff0c;需要磨平事件领域中从半…

【STM32】基础知识 第十一课 时钟

【STM32】基础知识 第十一课 时钟 概述时钟系统的基本概念什么是时钟时钟树锁相环APB 时钟树F1 系列时钟树F4 系列时钟树F7 系列时钟树H7 系列时钟树 系统时钟配置系统时钟配置步骤外设时钟的使能和使能HAL_RCC_OscConfig() 函数HAL_RCC_ClockConfig() 函数 概述 STM32 微控制…

超级香,分享8个相见恨晚的Python库

看到新奇又实用的第三方库&#xff0c;当然要分享出来咯~ Plottable Plottable是一个Python库&#xff0c;用于在matplotlib基础上绘制精美表格。例如下图所示表格。 代码如下&#xff1a; import matplotlib.pyplot as plt import numpy as np import pandas as pd from ma…

Leangoo领歌轻量级协作-OKR目标管理

​本场景是OKR目标管理模板&#xff0c;用Leangoo管理和跟踪OKR可以提升OKR的透明度和传递的即时性&#xff0c;驱动团队的积极性、促进共享和协作、提升沟通和协作的效率&#xff0c;帮助企业快速落地OKR。 OKR&#xff08;Objectives and Key Results目标与关键结果&#xf…

Packet Tracer - 谁会听到广播?

Packet Tracer - 谁会听到广播&#xff1f; 目标 第 1 部分&#xff1a;观察 VLAN 实施中的广播流量 第 2 部分&#xff1a;完成思考题 拓扑图 场景 在本练习中&#xff0c;将完全填充一个配有 24 个端口的 Catalyst 2960 交换机。 所有端口都已使用。 您将观察 VLAN 实施…

PS磨皮插件portraiture最新版磨皮工具

Portraiture是一款智能磨皮插件&#xff0c;为Photoshop和Lightroom添加一键磨皮美化功能&#xff0c;快速对照片中皮肤、头发、眉毛等部位进行美化&#xff0c;无需手动调整&#xff0c;大大提高P图效率。全新4版本&#xff0c;升级AI算法&#xff0c;并独家支持多人及全身模式…

剪纸中秋海报

打开【Ps】&#xff0c;新建【A4画布】&#xff0c;双击背景图层【解锁】&#xff0c;再添加【图案叠加】图层样式&#xff0c;选择最后一个图案&#xff0c;增加【缩放】。 【椭圆选框工具】按住【Shift】键画一个正圆&#xff0c;填充颜色#0e8993&#xff0c;添加【渐变叠加】…