Nacos 安全零信任实践

作者:柳遵飞

Nacos 作为配置中心经常存储一些敏感信息,但是由于误用导致安全风险,最常见的主要是以下两个问题:

1)Nacos 暴露公网可以吗?不可以,因为 Nacos 定位是注册配置中心,是内部系统,不应该暴露到公网使用。

2)不得已要开公网不开鉴权可以吗?不可以,开公网不开鉴权等同于裸奔,为黑客攻击创造充分条件。

看到赶紧自查一下是否有这两类问题,如果有立即解决一下!!! 解决完这些基础问题,可以看一下下面安全的进阶玩法。

安全问题的现实背景

Nacos 作为国内被广泛使用的注册配置中心,是云原生时代不可或缺的基础中间件组件,在开源社区拥有庞大的开发者群体,Nacos 也被广泛运行在生产环境之中。随着当前云计算,物联网,大数据 AI 等技术的兴起,相比于传统的基于“安全内网”的网络架构,现代的系统网络部署架构复杂性上升,传统的网络边界逐渐模糊化,对传统的网络安全架构产生了极大的冲击,业内数据泄露,网络攻击等事件频发,安全问题给企业的发展带来的影响越来越大。在此背景下,安全零信任的理念逐渐兴起,成为了现代化网络安全架构的指导思想,本文将介绍如何基于安全零信任的理念来保证 Nacos 的数据安全。

图片

今天分享的内容分为三个部分展开,第一个部分会简单介绍下 Nacos 这款产品以及其常见的一些使用场景,第二个部分会根据 Nacos 运行时的原理来分析其可能面临的安全风险,没有对 Nacos 做必要安全保护也是当前造成 Nacos 数据泄露的真实现状,最后一个部分会分享 Nacos 在安全零信任理念下的最佳实践,如何让 Nacos 更加安全的运行在生产环境。

Nacos 发展及使用场景

图片

Nacos 是什么?它的名字是由服务和配置管理的英文首字母,它的核心功能包括动态服务发现管理,动态配置管理,动态 DNS 服务。动态服务管理可以和上层的微服务 RPC 调用框架结合,比如 Spring Cloud, Dubbo 等实现节点上下线自动流量拆除或者上线,动态配置管理提供了在运行期不重启业务节点的情况下改变业务应用的运行时行为,也可以结合 CoreDNS 将 Nacos 上注册的服务导出为 DNS 域名来实现动态 DNS 服务。

图片

Nacos 将阿里巴巴集团内部 Diamond,ConfigServer,VipServer 三款中间件融合进一款产品,承袭了阿里内部十几年双十一大促的性能,稳定性,高可用方面的技术经验,2018 年从阿里内部开源以来,无论从 github 上的 star 数,fork 数,社区活跃度还是知名技术网站论坛评选的奖项可以看出它的受欢迎程度。从注册配置中心单一领域产品角度看,Nacos 现在是国内首选,被非常多的头部企业使用,占据国内 60%+ 的市场份额。

Nacos 能收到这么多开源社区的关注度和参与度,和它的使用场景是息息相关的。

图片

上图列举了 Nacos 的一些非常常见的使用场景,覆盖了微服务领域,高可用领域,前端生态,数据库领域等等,产品功能角度看,服务发现和注册涉及的场景会相对聚焦一些,它所承载的数据是服务名或者域名到 ip 地址的映射关系,而配置管理涉及的场景就会丰富很多,可以说是涉及到任何的领域。从上面图中可以看出,其中有一些非常关键的场景都是靠配置中心来完成的,比如流量调度,路由规则,应急预案,一些业务的关键开关,数据库的一些数据源配置。

这些数据是非常敏感的,如果数据被误写,密码数据被泄露,可能会产生非常大的数据安全问题。

在业界内也发生过不少的敏感数据泄漏事件,用户把开源的 Nacos 部署到了生产环境,但没有对 Nacos 做一些必要的安全防护的措施,当前行业对安全方面的意识也在逐渐提高,国家颁布的网络安全三级等保也对非银行业的平台做了若干个角度的安全要求。

Nacos 面临的安全问题

图片

上面是 Nacos 运行时的简要示意图,左侧是业务应用和 nacos-client,通常是部署在一个进程中,右侧是 Nacos 的服务端,包括 Nacos-Server 和中心化的持久化存储。从数据流转方向上看,数据由业务应用侧产生调用 nacos-client 的配置发布接口,通过网络传输至 Nacos-Server 端,Nacos-Server 端将配置内容持久化存储,并且从持久化存储加载到 Server 本地的磁盘缓存和内存缓存中,客户端查询配置时将配置内容从服务端拉取到本地,出于高可用容灾的考虑,客户端会将配置内容缓存在客户端本地磁盘中。从数据的角度看,配置内容会存在于业务应用本地的磁盘缓存,服务端本地的磁盘缓存,持久化的数据库中,并且数据会在传输过程中经过每一个中间网络设备。

现在我们做个假设,让我们先忽略安全内网,假设这些组件都是暴露在公网之中。基于这个假设,可能会存在以下几个方面的问题。

  • 业务应用机器被入侵

    因为 Nacos 的配置数据会在客户端进行缓存,所以如果业务应用的机器被入侵,本地缓存中的配置内容也会泄漏

  • 数据传输过程中被中间网络设备获取

    数据经过中间网络设备,可能被流量抓包,如果数据是明文传输,数据就会泄漏

  • Nacos 服务端被入侵

    如果 Nacos 服务端所部署的机器被外部攻破,那么存在于本地磁盘缓存内的也会被明文获取

  • 持久化层数据库被拖库

    配置存储的中心化数据库被拖库也会导致配置泄露

  • Nacos 服务端可公开访问

Nacos 服务端没有开启权限访问,任何知道 server 节点 IP 地址的人都可以通过 Nacos 接口 API 拉取到配置内容,或者对 Nacos 服务端的节点设置了比较宽泛的 ACL 规则,这两种情况在用户使用 Nacos 的场景中都比较常见,比如在商业化 MSE Nacos 的真实案例中,有很多用户给实例开了公网访问并且设置了比较宽泛的 ACL 规则的情况下没有开启鉴权,这些都是风险比较高的场景。

图片

我们对以上的几个问题进行一些简单的归纳,可以分为三个方面,存储安全,传输安全,访问控制。

上面我们做了几个假设,比如忽略安全内网隔离的问题,假设每一个环境都可能会被攻破的。其实这也就是安全零信任理念中一个非常重要的原则,“永不信任,永远验证”,下一节我们将介绍下 Nacos 的安全零信任实践,如何通过安全零信任理念来保障 Nacos 数据安全。

Nacos 安全零信任实践

图片

我们先简单了解下安全零信任的相关内容。

零信任的定义

顾名思义,即对任何未经验证的访问实体默认不信任。零信任是一种现代化的网络安全访问理念,核心思想是“永不信任,持续验证”。

零信任解决的问题

它诞生的背景是基于当前 IT 网络架构下的一系列现实因素。

  • 网络边界模糊化,现代系统网络架构更加负责,云计算,物联网等兴起打破了传统的”安全内网“边界
  • 安全漏洞无法避免:网络攻击和数据泄露事件增加,传统安全模型无法应对
  • 数据泄露风险:数据泄露对企业造成的直接经济损失以及舆情影响
  • 合规性要求:整体大环境下,行业和法规要求企业对网络安全实时更加严格的验证

零信任基本功能

零信任的几个基本功能包括:

  • 身份管理:提供对身份全生命周期管理
  • 身份认证:对所以访问的来源进行身份认证
  • 访问控制:确保对网络实体发起访问的资源进行授权
  • 传输安全:确保所有在网络中传输的数据不被窃取和篡改
  • 行为监控:对行为进行持续监测,实时响应异常

零信任基本原则

  • 永不信任,永远验证
  • 访问控制,最小权限访问
  • 微分段,防止横移,减少攻击面

Nacos 传输安全

接下来我会按照 Nacos 传输安全,存储安全,访问控制三个方面来介绍 Nacos 的安全零信任实践。

图片

第一个方面是 Nacos 传输安全 TLS,我们知道 TLS 解决的是数据传输过程中的三个问题,一个是数据保密性,基于 TLS 传输的数据都会被加密,无法被第三方获取明文,第二个是完整性,它保证的是数据不被第三方篡改,第三个是身份认证,它解决的是通信双方的身份认证问题,防止中间人攻击。

TLS 的握手过程分为几个主要阶段,这里做了部分简化,第一个阶段是客户端和服务端之间进行 TLS 协议版本,加密算法,压缩方法等基本信息的确认,第二阶段是双方的证书交换及验证,这里保证的是身份认证的问题,第三个阶段是双方通过非对称加密来协商后续实际传输报文过程中所使用对称秘钥,第四个阶段,双方发送加密切换消息,双方开始基于对称加密秘钥进行通信,第五个阶段是进行实际的应用报文传输,这里会使用对称加密进行数据传输,同时对报文进行 MAC 校验保证完整性。

图片

Nacos 在 2.x 的版本中使用 grpc 来作为底层通信协议,grpc 内部使用 netty 作为网络通信框架,Nacos 的 TLS 能力也是基于 grpc/netty 来实现的,该图中描述了客户端服务端的基本组件,其中淡蓝色部分是用户通过参数来控制是否开启 TLS 的方式,包括属性文件,jvm 参数,环境变量。深蓝色部分是 Nacos 层提供的组件来接受参数,并将参数转换为底层 grpc、netty 的组件来实现 TLS 功能。 另外在 server 端我们支持了服务端证书的动态轮转功能,可以自定义 SPI 扩展来实现当服务端证书文件变更时的处理逻辑。

图片

这里我们介绍 Nacos 如何开启 TLS 传输加密功能,整个过程分为三步:

  • 证书准备

    可以通过购买商业证书来获得相关的文件信息,如果是开发测试,可以通过 keytool openssl 自签的方式来生成 SSL 证书,该步骤可以参考网上的自签 SSL 证书流程,此处不在赘述。这一步中需要得到如下几个信息:

    • CA 证书文件:用于对端的证书合法性,对端使用的证书必须是通过是由该 CA 签发,防止身份冒充中间人攻击
    • 证书文件&证书私钥文件:用于服务端开启 TLS 功能
    • 私钥文件密码:处于安全性考虑,通常需要为私钥文件设置密码。
  • Nacos 服务端启动

    • nacos.remote.server.rpc.tls.enable=true开启 TLS 开关,设置为 true 表示服务端开启 TLS 功能
    • nacos.remote.server.rpc.tls.certChainFile={certFilePath}指定证书文件路径
    • nacos.remote.server.rpc.tls.certPrivateKey={keyPath}指定证书私钥文件
    • *nacos.remote.server.rpc.tls.mutualAuth=true/false是否开启双向认证,默认为 false,设置为 true 表示需要验证客户端的身份,客户端也需要同步设置证书和私钥文件
    • *nacos.remote.server.rpc.tls.trustCollectionChainPath={trustFilePath}受信任客户端 CA 证书,当开启双向认证时,用于校验客户端的证书合法性
    • *nacos.remote.server.rpc.tls.compatibility=true/false是否支持非加密客户端,默认是 true
    • *nacos.remote.server.rpc.tls.sslContextRefresher={spiName}指定证书轮转感应器 SPI 名称
  • Nacos 客户端启动

    • nacos.remote.client.rpc.tls.enable=true客户端开启 TLS 开关,如果设置为 true 的情况下,服务端不支持 TLS 或者没有开启 TLS,则会连接失败
    • nacos.remote.client.rpc.tls.trustAll=true/false是否信任所有支持 TLS 的服务端,设置为 true 表示不对服务端证书进行 CA 校验
    • *nacos.remote.client.rpc.tls.trustCollectionChainPath={trustFilePath}trustAll 为 true 时,需要设置受信任服务端 CA 证书文件
    • *nacos.remote.client.rpc.tls.mutualAuth=true/false是否开启双向认证,设置为 true 时,则需要同步设置客户端的证书文件和私钥
    • *nacos.remote.client.rpc.tls.certChainFile={certFilePath}指定客户端的证书文件路径
    • *nacos.remote.client.rpc.tls.certPrivateKey={keyPath}指定客户端的证书私钥文件

Nacos 存储安全

配置存储安全解决的问题是当各个可能存在配置内容的介质被攻破,配置被明文访问的问题。在这种情况下,我们需要对配置内的内容进行加密存储,加密存储需要第三方加密系统来辅助完成,复杂性会上升,通常我们建议对部分敏感配置进行加密存储。下面我们将介绍如何通过配置的加解密插件来实现敏感配置存储。

图片

上图介绍了加密配置的发布过程,明文内容在业务应用中产生,经由 nacos-client 发往服务端,在客户端内部,加密配置经过 IConfigFilter 过滤器,会经过加解密插件的加密 encrypt 步骤,将明文转化为密文和 dataKey,通常的做法是本地先生成一个随机 key,通过这个随机 key 对明文内容进行本地加密为密文,将 key 经由加解密插件加密的 dataKey,然后把将密文配置内容和加密后的 dataKey 发向服务端,服务端将密文 +dataKey 进行持久化存储,并且通知集群所有节点将密文 +dataKey 从数据库加载到服务端本地的磁盘缓存和内存缓存中。这种情况下,即使服务端被攻破,持久化数据库被拖库,无法通过密文 +dataKey 解密对应的明文,降低数据泄露带来的安全风险。

图片

接下来是加密后的配置的查询过程,客户端从服务端查询配置,服务端将密文 +dataKey 返回给客户端,客户端经由 IConfigFilter 过滤器,会经过加解密插件的解密 decrypt,将密文 +dataKey 解密为明文,然后在内存中将明文回调给业务的监听器,其中客户端本地缓存中存储的是密文和 dataKey,并不是明文,以此来保证整个链路中的配置存储安全。

在整个链路中引入了第三方加解密插件,增加数据安全的同时,也会带来额外的链路复杂度,我们建议是对一些敏感信息进行加解密,比如用户名密码,数据库配置,AK/SK, Token 等。同时因为加解密插件实现了密文->明文的加密过程,在与其的交互过程中也要保证数据传输安全,并且如果它是有状态的,也要保证它的存储安全。在商业化 MSE Nacos 中,我们使用 KMS 作为第三方加解密插件的实现方,来保证整体的数据安全。

Nacos 访问控制

第三个部分,我们将介绍如何通过 Nacos 鉴权插件实现对 Nacos 的访问控制。

图片

鉴权插件对 Nacos 访问控制进行了基础的模型抽象,分为客户端和服务端,两者通过约定的规则实现整体的访问控制功能。

  • 客户端

    • 提取识别客户端身份信息 IdentityContext
    • 使用身份信息对访问资源进行签名
    • 在报文中上传身份信息+签名
  • 服务端

    • 提取客户端上传的身份信息 identityNames
    • 验证身份合法性及验证签名 validateIdentity
    • 验证身份与访问资源的权限 validateAuthority

身份信息 IdentityContext 可以是用户名密码,AK/SK,或者 STS/RAM ROLE 自动轮转的 AK/TOKEN,如果想自定义实现自己的身份信息,只需要按需实现 SPI 即可,也可在自定义实现中实现动态身份轮转的逻辑。无论使用哪种身份识别信息,客户端和服务端要保持一致的规则,包括身份信息的提取以及签名验证的逻辑。

服务端处理身份验证和签名验证之外,还需要对身份和访问资源进行权限的校验,用户权限管理比较通用的是 RBAC 模型,RBAC 全称是基于角色的访问控制,当前 Nacos 默认的鉴权插件也就是使用这个模型。

图片

RBAC 模型由权限-角色-用户三个部分组成。

  • 权限:权限定义了对指定资源的访问规则,包括资源定义+ 操作(读/写)+许可(允许/拒绝),比如允许对命名空间 A 下的配置进行读操作。
  • 角色:拥有一系列权限集合的虚拟身份,它包含了多个权限的集合,比如定义命名空间 A 管理员角色,给其赋于对命名空间 A 下的配置进行读写操作。
  • 用户:可实际访问系统的实体用户,用于一个代表自身身份的标识,可以将多个角色赋于实体的用户,间接拥有多种权限。分为管理员和普通用户,管理员拥有最高权限,一般对其会进行 MFA 多因素认证。普通用户由管理员创建,可以给用户赋于多种角色。

上面提到,Nacos 默认的鉴权插件也是基于 RBAC 模型构建,可以完成基本的权限控制,开启默认的鉴权功能需要创建 users,roles, permissions 三张表用于存储对应的数据。

图片

开启 Nacos 访问控制需要三步:

1)服务端开启鉴权

  • 打开鉴权开关:nacos.core.auth.enabled=true
  • 设置鉴权插件:nacos.core.auth.system.type=nacos,指定为 Nacos 模型内置鉴权插件名

2)创建用户/角色/权限

  • 修改 admin 角色默认密码:开启服务端鉴权开关后,登录 Nacos 控制台需要设置用户名密码,首次登录后务必替换默认密码。开启鉴权后,登录控制台,左侧会出现权限控制的菜单
  • 创建普通用户,设置用户名密码
  • 创建角色,绑定用户-角色
  • 创建权限,绑定资源访问规则和角色的关系

3)创建用户/角色/权限

服务端打开鉴权之后,控制台登录需要验证用户名密码,通过 nacos-client 进行接口调用时也需要传入用户名,密码,在构建 ConfigService 和 NamingService 时需要在 properties 属性中传入用户名密码,否则接口访问会返回 403 无权限错误码。

🔔 注意: 开源默认的鉴权插件当前支持基于命名空间粒度的权限控制,MSE 商业化 Nacos 基于阿里云产品 RAM 实现访问控制,可以支持细粒度服务 serviceName/ 配置 dataId 级别权限控制。

结语

图片

以往我们更多地从用户的易用性角度出发,为了降低 Nacos 使用门槛,安全层面往往被忽视,在过去一年内,Nacos 在安全方面做了很大的投入,其中也因为安全问题做了一下 breakchange 的版本更新,删除了一些默认的安全方面的参数,提升用户在使用 Nacos 过程中的安全意识。

除了实现业务功能,安全问题也是当下每一个架构师需要关注的必不可少的方面。上面我们介绍了如何在使用开源 Nacos 过程中实现传输安全,存储安全,访问控制三方面来构建安全零信任架构,在此我们倡议在生产环境使用 Nacos 中默认开启访问控制,关闭匿名访问,对身份权限进行精细化权限管控,使用 TLS 保证数据传输安全,并在此基础之上,使用加解密插件对高敏感信息进行加密存储。未来在开源 Nacos 侧我们会持续完善安全防护策略,在快速入门中引导安全相关设置,开源控制台中增加更多的提示,加强用户数据安全意识建设。

Nacos 是一款开源产品,我们在 2.0 的版本中进行了多个插件化改造,用户可以进行插件化定制或者增强自建 Nacos 的安全等级,这些需要一些额外的定制开发工作。

这里推荐大家试用商业化 MSE Nacos ,可获得一站式安全防护能力。在商业化 MSE Nacos 中我们提供了完善了安全防护能力,包括 TLS 证书统一管理分发及自动轮转,联合 KMS3.0 支持加解密解决方案,结合 RAM 实现了完善细粒度的鉴权规则,支持日常安全巡检,风险管理等进阶安全防护能力。

如果你有更多的安全需求,也欢迎通过钉钉搜索群号联系我们。(钉钉群号:23371469

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

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

相关文章

谷歌验证码识别/谷歌识别/Google/本地库识别/图像识别

谷歌识别 做这个有两种方式,一种是图像分类的方式,标注量大,识别率有局限性。 另外一种是通过上面的图和下面的小图做一个相似度匹配,做孪生网络。 谷歌验证方式比较丰富,有时候上面的小图没有,我们可以做…

力扣37题:回溯算法之解数独

编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) 数独部分空…

java-动态代理

为什么需要代理? 如何创建代理 注意:实现类和代理需要实现同一个接口 接口 public interface Star {String sing(String song);void dance(); }实现类 public class BigStar implements Star {private String name;public BigStar(String name) {this.…

开源博客项目Blog .NET Core源码学习(20:App.Hosting项目结构分析-8)

本文学习并分析App.Hosting项目中后台管理页面的个人资料页面、修改密码页面。 个人资料页面 个人资料页面用于显示和编辑个人信息,支持从本地上传个人头像。整个页面使用了layui中的表单、日期与时间选择、上传等样式或模块,通过layui.css文件设置样式…

精彩回顾|从 AI 到银幕:顶尖对话揭秘 AI 如何塑造影视新格局

4月17日,由万合天宜、三次元影业、NOVATECH、微软中国极客天团、微软 Reactor 共同推出的「从 AI 到银幕」顶尖对话在上海微软紫竹园区举办。中国内地著名导演、编剧、监制黄建新,微软(中国)有限公司首席技术官韦青,与…

基于SpringBoot+Vue高校实习管理系统的设计与实现

项目介绍: 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统高校实习管理系统信息管理难度大&#xf…

atlas 500容器(ubuntu20.04)搭建

1.docker 及环境搭建略 2.宿主机驱动安装略 3.宿主机中能正确使用npu-smi 4.docker 拉取略 5.docker 容器启动 docker run -itd --device/dev/davinci0 --device/dev/davinci_manager --device/dev/devmm_svm --device/dev/hisi_hdc -v /run/board_cfg.ini:/run/b…

吴恩达2022机器学习专项课程(一)7.2 逻辑回归的简化成本函数

问题预览/关键词 本节课内容逻辑回归的损失函数简化之后的形式是?为什么可以简化?成本函数的通用形式是?逻辑回归成本函数的最终形式是?逻辑回归为什么用对数损失函数计算成本函数?为什么不直接给出逻辑回归损失函数的…

银河麒麟V10 ARM64 离线安装 新版Docker

查询当前发行版本 nkvers下载最新版本 卸载旧依赖 卸载已经安装的老版本 yum remove docker \containerd.io \docker-runc \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine \docker-compo…

【数据结构7-1-查找-线性-二分法-二叉树-哈希表】

目录 1 查找基本概念2 线性表的查找2.1 顺序查找2.2 二分法查找2.3 分块查找 3 树表的查询3.1 二叉排序树3.1.1 定义3.1.2 二叉树的建立、遍历、查找、增加、删除:3.1.3 代码实现: 3.2 平衡二叉树3.2.1 平横因子3.2.2 不平横树的调整-左旋3.2.3 不平横树…

c++高级篇(三) ——Linux下IO多路复用之poll模型

poll模型 前言 poll模型与select的实现原理相近,所以绝大数的原理其实可以参考select,我们这里对二者的相同点不做过多探究,如果有需要可以去看一下博主的上一篇文章: c高级篇(二) ——Linux下IO多路复用之select模型 这里我们只…

【Jenkins】持续集成与交付 (三):有关报错解决(Jenkins (2.387.3) or higher required)

🟣【Jenkins】持续集成与交付 (三):有关报错解决Jenkins (2.387.3) or higher required 一、Jenkins主页报错二、安装Jenkins插件报错三、解决过程(解压替换jenkins.war)四、重新访问登录💖The Begin💖点点关注,收藏不迷路💖 一、Jenkins主页报错 New version …

51单片机两个中断及中断嵌套

文章目录 前言一、中断嵌套是什么?二、两个同级别中断2.1 中断运行关系2.2 测试程序 三、两个不同级别中断实现中断嵌套3.1 中断运行关系3.2 测试程序 总结 前言 提示:这里可以添加本文要记录的大概内容: 课程需要: 提示&#x…

【电路笔记】-RC振荡器电路

RC振荡器电路 文章目录 RC振荡器电路1、概述2、RC 相移网络3、基本RC振荡器电路4、运算放大器RC振荡器5、运算放大器相位滞后RC振荡器电路6、RC振荡器示例11、概述 RC 振荡器使用放大器和 RC 反馈网络的组合,由于级之间的相移而产生输出振荡。 当单级晶体管放大器作为共发射…

疯狂的爬虫案例(2)文末附源码

软件版本号: python --version Python 3.8.0 pip show selenium Version: 4.20.0 chromedriver.exe -version 109.0.5414.74 主题:爬取10条动态网页内容(电影票房) 1.根据xpath获取网页节点(CtrlF) 2.…

spring高级篇(五)

1、参数解析器 前篇提到过,参数解析器是HandlerAdapters中的组件,用于解析controller层方法中加了注解的参数信息。 有一个controller,方法的参数加上了各种注解: public class Controller {public void test(RequestParam("…

Python-100-Days: Day06 Functions and Modules

函数的作用 编程大师Martin Fowler先生曾经说过:“代码有很多种坏味道,重复是最坏的一种!”,要写出高质量的代码首先要解决的就是重复代码的问题。可以将特定的功能封装到一个称之为“函数”的功能模块中,在需要的时候…

MyBatis(环境配置+基本CRUD)

文章目录 1.基本介绍1.为什么需要MyBatis?2.MyBatis介绍3.MyBatis工作示意图4.MyBatis的优势 2.快速入门文件目录1.需求分析2.数据库表设计3.父子模块环境配置1.创建maven父项目2.删除父项目的src目录3.pom.xml文件文件解释 4.创建子模块1.新建一个Module2.创建一个…

面向对象编程三大特征:封装、继承、多态

封装、继承、多态 1. 封装 1.1 介绍 封装(encapsulation)就是把抽象出的数据 [属性] 和对数据的操作 [方法] 封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作 [方法] ,才能对数据进行操作。 1.2 封装的理解和好处 1) 隐藏实现细节:方法(连接数据库)<…

UE Snap03 启动参数设置

UE Snap03 启动参数设置 UE打包后传入自定义参数及解析。 void UGameInstance::StartGameInstance() {Super::StartGameInstance();UE_LOG(LogTemp, Warning, TEXT("--StartGameInstance--"));FString param;FParse::Value(FCommandLine::Get(), TEXT("-UserN…