SpringSecurity中文文档(Servlet Password Storage)

存储机制(Storage Mechanisms)

每种支持的读取用户名和密码的机制都可以使用任何支持的存储机制:

  • Simple Storage with In-Memory Authentication
  • Relational Databases with JDBC Authentication
  • Custom data stores with UserDetailsService
  • LDAP storage with LDAP Authentication

In-Memory Authentication

Spring Security 的 InMemoryUserDetailsManager实现了 UserDetailsService,以支持存储在内存中的基于用户名/密码的身份验证。InmemyUserDetailsManager 通过实现 UserDetailsManager 接口提供对 UserDetails 的管理。当 SpringSecurity 配置为接受用户名和密码进行身份验证时,将使用基于 UserDetails 的身份验证。

在下面的示例中,我们使用 Spring Boot CLI 对密码的密码值进行编码,并得到{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW

InMemoryUserDetailsManager Java Configuration

@Bean
public UserDetailsService users() {
	UserDetails user = User.builder()
		.username("user")
		.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
		.roles("USER")
		.build();
	UserDetails admin = User.builder()
		.username("admin")
		.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
		.roles("USER", "ADMIN")
		.build();
	return new InMemoryUserDetailsManager(user, admin);
}

前面的示例以安全的格式存储密码,但在初始体验方面还有很多不足之处。

在下面的示例中,我们使用 User.withDefaultPasswordEncoder 来确保存储在内存中的密码受到保护。但是,它不能通过反编译源代码来防止获取密码。因此,User.withDefaultPasswordEncoder 只能用于“入门”,而不能用于生产。

InMemoryUserDetailsManager with User.withDefaultPasswordEncoder

@Bean
public UserDetailsService users() {
	// The builder will ensure the passwords are encoded before saving in memory
	UserBuilder users = User.withDefaultPasswordEncoder();
	UserDetails user = users
		.username("user")
		.password("password")
		.roles("USER")
		.build();
	UserDetails admin = users
		.username("admin")
		.password("password")
		.roles("USER", "ADMIN")
		.build();
	return new InMemoryUserDetailsManager(user, admin);
}

在基于 XML 的配置中使用 User.withDefaultPasswordEncoder 没有简单的方法。对于演示或刚开始,您可以选择以{ noop }作为密码的前缀来表示不应该使用编码:

<user-service>
	<user name="user"
		password="{noop}password"
		authorities="ROLE_USER" />
	<user name="admin"
		password="{noop}password"
		authorities="ROLE_USER,ROLE_ADMIN" />
</user-service>

JDBC Authentication

Spring Security 的 JdbcDaImpl 实现了 UserDetailsService,以支持使用 JDBC 检索的基于用户名和密码的身份验证。JdbcUserDetailsManager 扩展了 JdbcDaImpl,通过 UserDetailsManager 接口提供对 UserDetails 的管理。Spring Security 将基于 UserDetails 的身份验证配置为接受用户名/密码进行身份验证时,将使用该身份验证。

在下面的章节中,我们将讨论:

  • Spring Security JDBC Authentication使用的默认架构
  • 设置数据源
  • JdbcUserDetailsManager Bean

默认架构(Default Schema)

SpringSecurity 为基于 JDBC 的身份验证提供默认查询。本节提供与默认查询一起使用的相应默认架构。您需要调整模式,使其与所使用的查询和本地数据库的任何定制相匹配。

用户架构(User Schema)

JdbcDaImpl 需要表来加载用户的密码、帐户状态(启用或禁用)和权限(角色)列表。默认模式也公开为一个名为 org/springFramework/security/core/userDetails/jdbc/users.ddl 的类路径资源。

Default User Schema

create table users(
	username varchar_ignorecase(50) not null primary key,
	password varchar_ignorecase(500) not null,
	enabled boolean not null
);

create table authorities (
	username varchar_ignorecase(50) not null,
	authority varchar_ignorecase(50) not null,
	constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);

Oracle 是一种流行的数据库选择,但需要一种略有不同的模式:

Default User Schema for Oracle Databases

CREATE TABLE USERS (
    USERNAME NVARCHAR2(128) PRIMARY KEY,
    PASSWORD NVARCHAR2(128) NOT NULL,
    ENABLED CHAR(1) CHECK (ENABLED IN ('Y','N') ) NOT NULL
);


CREATE TABLE AUTHORITIES (
    USERNAME NVARCHAR2(128) NOT NULL,
    AUTHORITY NVARCHAR2(128) NOT NULL
);
ALTER TABLE AUTHORITIES ADD CONSTRAINT AUTHORITIES_UNIQUE UNIQUE (USERNAME, AUTHORITY);
ALTER TABLE AUTHORITIES ADD CONSTRAINT AUTHORITIES_FK1 FOREIGN KEY (USERNAME) REFERENCES USERS (USERNAME) ENABLE;

组结构(Group Schema)

如果应用程序使用组,则需要提供组架构:

Default Group Schema

create table groups (
	id bigint generated by default as identity(start with 0) primary key,
	group_name varchar_ignorecase(50) not null
);

create table group_authorities (
	group_id bigint not null,
	authority varchar(50) not null,
	constraint fk_group_authorities_group foreign key(group_id) references groups(id)
);

create table group_members (
	id bigint generated by default as identity(start with 0) primary key,
	username varchar(50) not null,
	group_id bigint not null,
	constraint fk_group_members_group foreign key(group_id) references groups(id)
);

设置数据源(Setting up a DataSource)

在配置 JdbcUserDetailsManager 之前,必须创建一个 DataSource。在我们的示例中,我们设置了一个用默认用户架构初始化的嵌入式 DataSource。

@Bean
DataSource dataSource() {
	return new EmbeddedDatabaseBuilder()
		.setType(H2)
		.addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
		.build();
}

JdbcUserDetailsManager Bean

在这个示例中,我们使用 Spring Boot CLI 对密码的密码值进行编码,并获得{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW 的编码密码。有关如何存储密码的详细信息,请参阅 PasswordEncoder 部分。

JdbcUserDetailsManager

@Bean
UserDetailsManager users(DataSource dataSource) {
	UserDetails user = User.builder()
		.username("user")
		.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
		.roles("USER")
		.build();
	UserDetails admin = User.builder()
		.username("admin")
		.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
		.roles("USER", "ADMIN")
		.build();
	JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
	users.createUser(user);
	users.createUser(admin);
	return users;
}

UserDetails

UserDetails 由 UserDetailsService 返回。DauAuthenticationProvider 验证 UserDetails,然后返回一个 Authentication,其主体是由配置的 UserDetailsService 返回的 UserDetails。

UserDetailsService

DataAuthenticationProvider 使用 UserDetailsService 检索用户名、密码和其他属性,以便使用用户名和密码进行身份验证。Spring Security 提供了 UserDetailsService 的内存、 JDBC 和缓存实现。

可以通过将自定义 UserDetailsService 公开为 bean 来定义自定义身份验证。例如,下面的清单假设 CustomUserDetailsService 实现 UserDetailsService,从而自定义身份验证:

只有在没有填充 AuthenticationManagerBuilder 且没有定义 AuthenticationProviderBean 的情况下才会使用。

Custom UserDetailsService Bean

@Bean
CustomUserDetailsService customUserDetailsService() {
	return new CustomUserDetailsService();
}

PasswordEncoder

SpringSecurity 的 servlet 支持包括通过集成 PasswordEncoder 来安全地存储密码。您可以通过公开 PasswordEncoderBean 来自定义 Spring Security 使用的 PasswordEncoder 实现。

DaoAuthenticationProvider

DauAuthenticationProvider 是一个 AuthenticationProvider 实现,它使用 UserDetailsService 和 PasswordEncoder 对用户名和密码进行身份验证。

本节研究 DauAuthenticationProvider 如何在 SpringSecurity 中工作。下图以“阅读用户名和密码”部分中的数字解释了 AuthenticationManager 的工作原理。

daoauthenticationprovider

  1. Reading the Username & Password 部分中的身份验证筛选器将 UsernamePasswordAuthenticationToken 传递给 AuthenticationManager,后者由 ProviderManager 实现。
  2. ProviderManager 配置为使用类型为 DauAuthenticationProvider 的 AuthenticationProvider。
  3. DauAuthenticationProvider 从 UserDetailsService 查找 UserDetails。
  4. DauAuthenticationProvider 使用 PasswordEncoder 验证在上一步中返回的 UserDetails 上的密码。
  5. 身份验证成功后,返回的身份验证类型为 UsernamePasswordAuthenticationToken,其主体是由配置的 UserDetailsService 返回的 UserDetails。最终,身份验证筛选器将在 SecurityContextHolder 上设置返回的 UsernamePasswordAuthenticationToken。

LDAP Authentication

LDAP (轻型目录访问协议)经常被组织用作用户信息的中央存储库和身份验证服务。它还可用于存储应用程序用户的角色信息。

Spring Security 的基于 LDAP 的身份验证在配置为接受用户名/密码进行身份验证时使用。然而,尽管使用用户名和密码进行身份验证,它并不使用 UserDetailsService,因为在绑定身份验证中,LDAP 服务器不会返回密码,因此应用程序无法进行密码验证。

对于如何配置 LDAP 服务器,有许多不同的场景,因此 Spring Security 的 LDAP 提供程序是完全可配置的。它使用单独的策略接口进行身份验证和角色检索,并提供默认实现,可以将其配置为处理各种情况。

Required Dependencies

Spring Security LDAP Dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-ldap</artifactId>
</dependency>

Prerequisites

在尝试将 LDAP 与 SpringSecurity 一起使用之前,您应该熟悉 LDAP。以下连结提供有关概念的简介,以及使用免费 LDAP 伺服器(OpenLDAP)建立目录的指引: www.zytrax.com/books/LDAP/。熟悉用于从 Java 访问 LDAP 的 JNDI API 也很有用。我们在 LDAP 提供商中不使用任何第三方 LDAP 库(Mozilla、 JLDAP 或其他) ,而是大量使用的是 Spring LDAP,所以如果您计划添加自己的定制,对该项目有一些了解可能会有用。

在使用 LDAP 身份验证时,应确保正确配置 LDAP 连接池。如果您不熟悉如何这样做,请参阅 JavaLDAP 文档。

设置嵌入式 LDAP 服务器(Setting up an Embedded LDAP Server)

您需要做的第一件事情是确保您有一个 LDAP 服务器来指向您的配置。

您需要做的第一件事情是确保您有一个 LDAP 服务器来指向您的配置。为了简单起见,最好从嵌入式 LDAP 服务器开始。Spring Security 支持使用以下两种方式:

  • Embedded UnboundID Server
  • Embedded ApacheDS Server

在下面的示例中,我们将 users.ldif 作为类路径资源公开,以使用两个用户(user 和 admin)初始化嵌入式 LDAP 服务器,这两个用户都有密码:

users.ldif

dn: ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: groups

dn: ou=people,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: people

dn: uid=admin,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Rod Johnson
sn: Johnson
uid: admin
userPassword: password

dn: uid=user,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Dianne Emu
sn: Emu
uid: user
userPassword: password

dn: cn=user,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfNames
cn: user
member: uid=admin,ou=people,dc=springframework,dc=org
member: uid=user,ou=people,dc=springframework,dc=org

dn: cn=admin,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfNames
cn: admin
member: uid=admin,ou=people,dc=springframework,dc=org

Embedded UnboundID Server

如果希望使用 Unbound ID,请指定以下依赖项:

UnboundID Dependencies

<dependency>
	<groupId>com.unboundid</groupId>
	<artifactId>unboundid-ldapsdk</artifactId>
	<version>6.0.11</version>
	<scope>runtime</scope>
</dependency>

然后可以使用 EmbeddedLdapServerContextSourceFactoryBean 配置嵌入式 LDAP 服务器。这将指示 Spring Security 启动内存中的 LDAP 服务器:

Embedded LDAP Server Configuration

@Bean
public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
	return EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
}

或者,可以手动配置嵌入式 LDAP 服务器。如果选择这种方法,您将负责管理嵌入式 LDAP 服务器的生命周期。

Explicit Embedded LDAP Server Configuration

@Bean
UnboundIdContainer ldapContainer() {
	return new UnboundIdContainer("dc=springframework,dc=org",
				"classpath:users.ldif");
}

Embedded ApacheDS Server

Spring Security 使用 ApacheDS 1.x,不再进行维护。不幸的是,ApacheDS 2.x 只发布了里程碑版本,没有稳定的版本。一旦 ApacheDS 2.x 的稳定版本可用,我们将考虑更新。

如果您希望使用 Apache DS,请指定以下依赖项:

ApacheDS Dependencies

<dependency>
	<groupId>org.apache.directory.server</groupId>
	<artifactId>apacheds-core</artifactId>
	<version>1.5.5</version>
	<scope>runtime</scope>
</dependency>
<dependency>
	<groupId>org.apache.directory.server</groupId>
	<artifactId>apacheds-server-jndi</artifactId>
	<version>1.5.5</version>
	<scope>runtime</scope>
</dependency>

然后可以配置嵌入式 LDAP 服务器:

@Bean
ApacheDSContainer ldapContainer() {
	return new ApacheDSContainer("dc=springframework,dc=org",
				"classpath:users.ldif");
}

LDAP ContextSource

一旦有了指向配置的 LDAP 服务器,就需要将 Spring Security 配置为指向应该用于身份验证用户的 LDAP 服务器。为此,创建一个 LDAP ContextSource (相当于 JDBC DataSource)。如果已经配置了 EmbeddedLdapServerContextSourceFactoryBean,Spring Security 将创建指向嵌入式 LDAP 服务器的 LDAP ContextSource。

LDAP Context Source with Embedded LDAP Server

@Bean
public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
	EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =
			EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
	contextSourceFactoryBean.setPort(0);
	return contextSourceFactoryBean;
}

或者,可以显式配置 LDAP ContextSource 以连接到提供的 LDAP 服务器:

LDAP Context Source

ContextSource contextSource(UnboundIdContainer container) {
	return new DefaultSpringSecurityContextSource("ldap://localhost:53389/dc=springframework,dc=org");
}

Authentication

Spring Security 的 LDAP 支持不使用 UserDetailsService,因为 LDAP 绑定身份验证不允许客户端读取密码,甚至不允许密码的散列版本。这意味着没有办法读取密码,然后由 SpringSecurity 进行身份验证。

因此,LDAP 支持是通过 LdapAuthenticator 接口实现的。LdapAuthenticator 接口还负责检索任何必需的用户属性。这是因为对属性的权限可能取决于所使用的身份验证类型。例如,如果绑定为用户,则可能需要使用用户自己的权限读取属性。

Spring Security 提供了两个 LdapAuthenticator 实现:

  • Using Bind Authentication
  • Using Password Authentication

Using Bind Authentication

绑定身份验证是使用 LDAP 对用户进行身份验证的最常用机制。在绑定身份验证中,用户的凭据(用户名和密码)被提交给 LDAP 服务器,LDAP 服务器对它们进行身份验证。使用绑定身份验证的优点是不需要向客户机公开用户的秘密(密码) ,这有助于保护它们不被泄露。

下面的示例演示绑定身份验证配置:

Bind Authentication

@Bean
AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
	LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
	factory.setUserDnPatterns("uid={0},ou=people");
	return factory.createAuthenticationManager();
}

前面的简单示例将通过在提供的模式中替换用户登录名并尝试将该用户与登录密码绑定来获取该用户的 DN。如果所有用户都存储在目录中的单个节点下,则可以这样做。如果希望配置 LDAP 搜索筛选器来定位用户,可以使用以下方法:

Bind Authentication with Search Filter

@Bean
AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
	LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
	factory.setUserSearchFilter("(uid={0})");
	factory.setUserSearchBase("ou=people");
	return factory.createAuthenticationManager();
}

如果与前面显示的 ContextSource 定义一起使用,这将使用(uid = {0})作为过滤器在 DN ou = people,dc = springFramework,dc = org 下执行搜索。同样,用户登录名替代了筛选器名称中的参数,因此它搜索的条目的 uid 属性与用户名相等。如果未提供用户搜索基,则从根目录执行搜索。

Using Password Authentication

密码比较是将用户提供的密码与存储库中存储的密码进行比较。这可以通过检索 password 属性的值并在本地进行检查来完成,也可以通过执行 LDAP 的“比较”操作来完成,其中提供的密码被传递给服务器进行比较,并且永远不会检索到真正的密码值。如果密码使用随机的 salt 进行了正确的散列,则无法进行 LDAP 比较。

Minimal Password Compare Configuration

@Bean
AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
	LdapPasswordComparisonAuthenticationManagerFactory factory = new LdapPasswordComparisonAuthenticationManagerFactory(
			contextSource, NoOpPasswordEncoder.getInstance());
	factory.setUserDnPatterns("uid={0},ou=people");
	return factory.createAuthenticationManager();
}

下面的示例显示了一个更高级的配置,其中包含一些自定义项:

Password Compare Configuration

@Bean
AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
	LdapPasswordComparisonAuthenticationManagerFactory factory = new LdapPasswordComparisonAuthenticationManagerFactory(
			contextSource, new BCryptPasswordEncoder());
	factory.setUserDnPatterns("uid={0},ou=people");
	factory.setPasswordAttribute("pwd");
	return factory.createAuthenticationManager();
}
  • 将 password 属性指定为 pwd。

LdapAuthoritiesPopulator

SpringSecurity 的 LdapAuthoritiesPopator 用于确定为用户返回哪些权限。下面的示例显示如何配置 LdapAuthoritiesPopator:

LdapAuthoritiesPopulator Configuration

@Bean
LdapAuthoritiesPopulator authorities(BaseLdapPathContextSource contextSource) {
	String groupSearchBase = "";
	DefaultLdapAuthoritiesPopulator authorities =
		new DefaultLdapAuthoritiesPopulator(contextSource, groupSearchBase);
	authorities.setGroupSearchFilter("member={0}");
	return authorities;
}

@Bean
AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource, LdapAuthoritiesPopulator authorities) {
	LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
	factory.setUserDnPatterns("uid={0},ou=people");
	factory.setLdapAuthoritiesPopulator(authorities);
	return factory.createAuthenticationManager();
}

Active Directory

ActiveDirectory 支持自己的非标准身份验证选项,正常的使用模式与标准的 LdapAuthenticationProvider 不太匹配。通常,身份验证是通过使用域用户名(以 user@domain 的形式)执行的,而不是使用 LDAP 专有名称。为了简化这一点,SpringSecurity 有一个身份验证提供程序,该程序是为典型的 ActiveDirectory 设置定制的。

配置 ActiveDirectoryLdapAuthenticationProvider 非常简单。您只需提供域名和提供服务器地址的 LDAP URL。

也可以通过 DNS 查找获得服务器的 IP 地址。目前还不支持,但希望在将来的版本中会支持。

下面的示例配置 ActiveDirectory:

Example Active Directory Configuration

@Bean
ActiveDirectoryLdapAuthenticationProvider authenticationProvider() {
	return new ActiveDirectoryLdapAuthenticationProvider("example.com", "ldap://company.example.com/");
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

4个免费文章生成器,为你免费一键生成原创文章

在当今的创作领域&#xff0c;创作者们常常陷入各种困境。灵感的缺失、内容创新的压力&#xff0c;每一项都如同沉重的枷锁&#xff0c;束缚着他们的创作步伐。但随着免费文章生成器的出现&#xff0c;宛如一场及时雨&#xff0c;为创作者们带来了新的希望和转机。免费文章生成…

【ABB】原点设定

【ABB】原点设定 操作流程演示 操作流程 操作轴回原点编辑电机校准偏移更新转速计数器 1.首先得了解机器手的轴&#xff0c;这里以6轴作参考。 注意先回456轴&#xff0c;后回123轴。 2.然后需要了解机器人关节运动模式&#xff0c;即选择如下两个模式。 3.注意机器人各轴移动…

19C 单机文件系统安装文档

准备工作 1)查看系统版本、内核参数 more /etc/redhat-release more /etc/redflag-releaseuname -a2)查看当前系统是否配置了HugePages。在下面的查询中&#xff0c;HugePages的几个相关值都为0&#xff0c;表明当前未配值HugePages&#xff0c;其次可以看到该版本的大页大小为…

Linux服务器性能参数指标

【摘要】一个基于 Linux 操作系统的服务器运行的同时&#xff0c;会表征出各种各样参数信息&#xff0c;这些蛛丝马迹往往会帮助快速定位跟踪问题。 这里只是一些简单的工具查看系统的相关参数&#xff0c;当然很多工具也是通过分析加工 /proc、/sys 下的数据来工作的&#xff…

课设:选课管理系统(Java+MySQL)

在本博客中&#xff0c;我将介绍用Java、MySQL、JDBC和Swing GUI开发一个简单的选课管理系统。 技术栈 Java&#xff1a;用于编写应用程序逻辑MySQL&#xff1a;用于存储和管理数据JDBC&#xff1a;用于连接Java应用程序和MySQL数据库Swing GUI&#xff1a;用于构建桌面应用程…

RH850系列芯片深度剖析 1.8-内存管理之MPU

RH850系列芯片深度剖析 1.8-内存管理之MPU 文章目录 RH850系列芯片深度剖析 1.8-内存管理之MPU一、MPU简介1.1 功能特性1.2 系统保护标识符(SPID)二、保护区域设置2.1 保护区域属性设置2.2 保护区域设置注意事项2.2.1 跨越保护区域边界2.2.2 无效的保护区域设置2.2.3 保护违规…

【anaconda】—“conda info“命令后conda配置和环境信息的理解

文章目录 conda配置和环境信息的理解 conda配置和环境信息的理解 安装anaconda成功后&#xff0c;打开cmd&#xff0c;输入"conda info"命令&#xff0c;结果显示如下&#xff1a; conda的配置和环境信息的输出。以下是对每个字段的解释&#xff1a; active environm…

记录一下被一行代码耽误的一下午

记录一下被一行代码耽误的一下午 代码如下&#xff1a; defineOptions({name: OrderRewards})起因使用了yudao的项目框架&#xff0c;前端页面切换之后莫名其妙重新刷新页面&#xff0c;而另外的页面则会保存检索条件 页面配置页面 设定路由的名字&#xff0c;一定要填写不然…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(二十二)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 32 节&#xff09; P32《31.通知-基础通知》 基础文本类型通知&#xff1a;briefText 没有用&#xff0c;写了也白写。 长文本类型…

[SAP ABAP] 版本管理

版本管理是指软件开发过程中各种程序代码、配置文件以及说明文档等文件变更的管理 生成版本 版本管理 对比版本 点击上述版本管理即可进行版本对比操作 补充扩展 我们可以使用事务码SE10对传输请求进行创建、修改、删除、合并以及更改所有者等操作 使用事务码SCC1进行不同cl…

CV01_相机成像原理与坐标系之间的转换

目录 0.引言&#xff1a;小孔成像->映射表达式 1. 相机自身的运动如何表征&#xff1f;->外参矩阵E 1.1 旋转 1.2 平移 2. 如何投影到“像平面”&#xff1f;->内参矩阵K 2.1 图像平面坐标转换为像素坐标系 3. 三维到二维的维度是如何丢失的&#xff1f;…

【CentOS7.6】docker部署EMQX教程,本地镜像直接导入(附下载链接),没法在云服务器上魔法拉取镜像的快来

总览 先把下载链接放在这里吧&#xff0c;这是 EMQX 的 tar 包&#xff0c;能够直接导入 CentOS 的 docker&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rSGSLoVvj83ai6d5oolg8Q?pwd0108 提取码&#xff1a;0108 一、安装配置教程 1.将 EMQX-latest.tar 包导入…

记录第一次写脚本

使用csh语言&#xff0c;Linux系统操作的 写和执行csh&#xff08;C Shell&#xff09;脚本不需要额外的软件&#xff0c;只需要一个支持csh的终端环境。 1.检查是否安装了C Shell 在终端terminal运行以下命令 which csh 如果返回路径&#xff0c;比如/bin/csh&#xff0c…

【mybatis】mybatisX插件概述

一、主要功能 智能补全与提示 MyBatisX 可以智能地提示和补全 SQL 语句中的关键字、表名、列名等信息&#xff0c;从而显著提高开发效率。代码生成器 虽然 MyBatisX 本身可能不直接提供一个完整的、独立的代码生成器&#xff0c;但它可能集成了或支持与其他代码生成工具&#…

【Linux进阶】磁盘分区2——MBR和GPT

1.磁盘的分区 因为如果你的磁盘被划分成两个分区&#xff0c;那么每个分区的设备文件名是什么&#xff1f; 在了解这个问题之前&#xff0c;我们先来复习一下磁盘的组成&#xff0c;因为现今磁盘的划分与它物理的组成很有关系。 我们谈过磁盘主要由碟片、机械手臂、磁头与主轴马…

Tomcat(+Servlet)笔记+代码

Tomcat安装和配置 安装在不含中文的路径&#xff0c;路径不能太长 Apache 官网&#x1f447; Apache Tomcat - Welcome! 配置部分 点击下图红框处&#xff0c;找到Tomcat安装位置 添加项目的文件 配好的话&#xff0c;红框这里有个猫 代码部分 新建jsp文件&#xff0c;里…

小程序渗透测试的两种方法——burpsuite、yakit

首先呢主要是配置proxifier&#xff0c;找到小程序的流量&#xff0c;然后使用burpsuite或者yakit去抓包。 一、使用burpsuiteproxifier的抓包测试 1、先配置proxifier&#xff0c;开启http流量转发 勾选确定 2、配置burp对应代理端口&#xff0c;选择profile&#xff0c;点…

基于React和TypeScript的开源白板项目(Github项目分享)

在学习前端开发的过程中&#xff0c;有时候我们需要一些有趣的项目来提升我们的技能。今天我要给大家介绍的是一个非常酷的项目——NinjaSketch&#xff0c;这是一个用React和TypeScript构建的简易白板工具。这个项目使用了Rough.js来实现手绘风格的效果。尽管这个应用不是响应…

vue中如何使用echarts和echarts-gl实现三维折线图和三维柱状图

一、vue中使用三维折线图 效果图&#xff1a; 二、使用步骤 1.引入库 安装echarts 在package.json文件中添加 "dependencies": {"echarts": "^5.1.2""echarts-gl": "^1.1.1",// "echarts-gl": "^2.0.8…

【C++】 解决 C++ 语言报错:Memory Leak

文章目录 引言 内存泄漏&#xff08;Memory Leak&#xff09;是 C 编程中常见且严重的内存管理问题之一。当程序分配了内存而没有正确释放&#xff0c;导致内存无法被重新利用时&#xff0c;就会发生内存泄漏。这种错误会导致程序占用越来越多的内存&#xff0c;最终可能导致系…