新版Spring Security6.2架构 (三) - Authorization

前言

书接上文,在经过了authentication后就是authorization了,本文还是对官网文档authorization的一个架构翻译和个人理解,后续的博客在写具体使用例子,从数据中认证,融合authentication和authorization的概念。

Authorization 架构

Authorization就是在确定用户进行身份验证的方式后,还需要配置应用进程的授权规则。

Spring Security 中之所以这么受到那么多人信任和欢迎,高级授权功能是其原因之一。无论您选择如何进行身份验证(无论是使用 Spring Security 提供的机制和提供进程,还是与容器或其他非 Spring Security 身份验证机构集成),都可以在应用进程中以一致且简单的方式使用授权服务。 

应考虑把授权规则附加在请求 URIs路径和方法上。下面还有大量关于Spring Security授权如何工作的细节,以及在创建了基本模型后,如何对其进行微调。

Authorization 架构

Authorities

Authentication讨论的是所有Authentication的实现,以及如何存储 GrantedAuthority 对象的列表。这些代表已授予委托人的权限。GrantedAuthority 对象由 AuthenticationManager 插入到 Authentication 对象中,在后续中由 AccessDecisionManager 实例读取来实现授权决策。
GrantedAuthority接口只有一个方法

String getAuthority();

AuthorizationManager 实例使用此方法来获取 GrantedAuthority 准确的字符串表示形式。通过以字符串形式返回表示形式,大多数 AuthorizationManager 实现可以轻松“读取”GrantedAuthority。如果 GrantedAuthority 无法准确表示为字符串,则 GrantedAuthority 被视为“复杂”,并且 getAuthority() 必须返回 null。

GrantedAuthority复杂的实现在于存储适用于不同客户帐号的操作和权限阈值列表。将这个复杂的 GrantedAuthority 表示为字符串将非常困难。因此,getAuthority() 方法应返回 null。这向任何 AuthorizationManager 表明它需要支持特定的 GrantedAuthority 实现才能理解其内容。

Spring Security 包含一种具体的 GrantedAuthority 实现:SimpleGrantedAuthority。此实现允许将任何用户指定的字符串转换为 GrantedAuthority。安全架构中包含的所有 AuthenticationProvider 实例都使用 SimpleGrantedAuthority 来填充 Authentication 对象。

默认情况下,基于角色的授权规则包含 ROLE_ 作为前缀。这意味着,如果有一个授权规则要求安全上下文具有“USER”角色,Spring Security 将默认查找返回“ROLE_USER”的 GrantedAuthority#getAuthority。

您可以使用 GrantedAuthorityDefaults 对此进行自定义。 GrantedAuthorityDefaults 的存在是为了允许自定义用于基于角色的授权规则的前缀。

您可以通过公开 GrantedAuthorityDefaults bean 将授权规则配置为使用不同的前缀,如下所示:

@Bean
static GrantedAuthorityDefaults grantedAuthorityDefaults() {
	return new GrantedAuthorityDefaults("MYPREFIX_");
}

这边官网还有个提示:

可以使用静态方法公开 GrantedAuthorityDefaults,以确保 Spring 在初始化 Spring Security 的方法安全性@Configuration类之前发布它

Invocation Handling

Spring Security 提供了拦截器来控制对安全对象(例如方法调用或 Web 请求)的访问。调用前决定是否允许调用继续由 AuthorizationManager 实例做出。此外,调用后是否可返回给定值的决策由 AuthorizationManager 实例做出。

The AuthorizationManager

AuthorizationManager 取代了 AccessDecisionManager 和 AccessDecisionVoter。 

使用自定义 AccessDecisionManager 或 AccessDecisionVoter 的应用程序建议更改为使用 AuthorizationManager。AuthorizationManager 接口包含两种方法:

AuthorizationManager 是通过 Spring Security 基于请求、基于方法和基于消息的授权组件来调用,并负责做出最终的访问控制决策。AuthorizationManager 接口包含两种方法:

AuthorizationDecision check(Supplier<Authentication> authentication, Object secureObject);

default AuthorizationDecision verify(Supplier<Authentication> authentication, Object secureObject)
        throws AccessDeniedException {
    // ...
}

AuthorizationManager 的检查方法将传递它需要的所有相关信息,以便做出授权决策。具体而言,传递安全对象可以检查实际安全对象调用中包含的那些参数。例如,假设安全对象是 MethodInvocation。很容易在 MethodInvocation 中查询任何 Customer 参数,然后在 AuthorizationManager 中实现某种安全逻辑,以确保允许主体对该客户进行操作。如果授予访问权限,则实现应返回正 AuthorizationDecision,如果访问被拒绝,则返回负 AuthorizationDecision,在弃权时返回空 AuthorizationDecision。

verify 调用检查,随后在负 AuthorizationDecision 的情况下引发 AccessDeniedException。

基于委托的 AuthorizationManager 实现

虽然用户可以实现自己的 AuthorizationManager 来控制授权的所有方面,但 Spring Security 附带了一个委托 AuthorizationManager,它可以与各个 AuthorizationManager 协作。

RequestMatcherDelegatingAuthorizationManager 会将请求与最合适的委托AuthorizationManager 进行匹配。为了方法安全性,可以使用 AuthorizationManagerBeforeMethodInterceptor 和 AuthorizationManagerAfterMethodInterceptor。

Authorization Manager Implementations阐释它的相关类。

使用此方法,可以在授权决策上轮询 AuthorizationManager 实现一系列组合。

AuthorityAuthorizationManager

Spring Security 提供的最常见的 AuthorizationManager 是 AuthorityAuthorizationManager。它配置了一组给定的权限,以在当前Authentication身份验证上查找。如果 Authentication 包含任何已配置的authorities,它将返回正 AuthorizationDecision。否则,它将返回负的 AuthorizationDecision。

AuthenticatedAuthorizationManager

另一个管理器是 AuthenticatedAuthorizationManager。它可用于区分匿名用户、完全身份验证用户和“记住我”身份验证的用户。许多站点允许在“记住我”身份验证下进行某些有限的访问,但要求用户通过登录来确认其身份才能获得完全访问权限。

AuthorizationManagers

AuthenticationManagers 中还有有用的静态工厂,用于将单个 AuthenticationManager 组合成更复杂的表达式。

Custom Authorization Managers

显然,您还可以实现自定义 AuthorizationManager,并且可以将所需的任何访问控制逻辑放入其中。它可能特定于您的应用程序(与业务逻辑相关),也可能实现某些安全管理逻辑。例如,您可以创建一个可以查询 Open Policy Agent 或您自己的授权数据库的实现。

小提示:您可以在 Spring 网站上找到一篇博客文章,其中介绍了如何使用旧AccessDecisionVoter 实时拒绝帐户已被暂停的用户的访问。可以通过改为实现 AuthorizationManager 来实现相同的结果。

AccessDecisionManager 和 AccessDecisionVoters 调整

在 AuthorizationManager 之前,Spring Security 发布了 AccessDecisionManager 和 AccessDecisionVoter。

在某些情况下,例如迁移较旧的应用程序,可能需要引入调用 AccessDecisionManager 或 AccessDecisionVoter 的 AuthorizationManager。

要调用现有的 AccessDecisionManager, 可以如下:

@Component
public class AccessDecisionManagerAuthorizationManagerAdapter implements AuthorizationManager {
    private final AccessDecisionManager accessDecisionManager;
    private final SecurityMetadataSource securityMetadataSource;

    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, Object object) {
        try {
            Collection<ConfigAttribute> attributes = this.securityMetadataSource.getAttributes(object);
            this.accessDecisionManager.decide(authentication.get(), object, attributes);
            return new AuthorizationDecision(true);
        } catch (AccessDeniedException ex) {
            return new AuthorizationDecision(false);
        }
    }

    @Override
    public void verify(Supplier<Authentication> authentication, Object object) {
        Collection<ConfigAttribute> attributes = this.securityMetadataSource.getAttributes(object);
        this.accessDecisionManager.decide(authentication.get(), object, attributes);
    }
}

然后将其连接到您的 SecurityFilterChain。

或者,若要仅调用 AccessDecisionVoter,可以执行以下操作:

@Component
public class AccessDecisionVoterAuthorizationManagerAdapter implements AuthorizationManager {
    private final AccessDecisionVoter accessDecisionVoter;
    private final SecurityMetadataSource securityMetadataSource;

    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, Object object) {
        Collection<ConfigAttribute> attributes = this.securityMetadataSource.getAttributes(object);
        int decision = this.accessDecisionVoter.vote(authentication.get(), object, attributes);
        switch (decision) {
        case ACCESS_GRANTED:
            return new AuthorizationDecision(true);
        case ACCESS_DENIED:
            return new AuthorizationDecision(false);
        }
        return null;
    }
}

然后将其连接到您的安全过滤链中。

角色层次-Hierarchical Roles

应用程序的通常需求,一个特定角色应自动“包含”其他角色。例如,在具有“管理员”和“用户”角色概念的应用程序中,您可能希望管理员能够执行普通用户所能做的所有事情。为此,您可以确保所有管理员用户也被分配了“用户”角色。或者,您可以修改每个访问约束,要求“用户”角色也包括“管理员”角色。如果您的应用程序中有很多不同的角色,这可能会变得非常复杂。

使用角色层次结构可以配置哪些角色(或权限)应包括其他角色。Spring Security 的 RoleVoter 的扩展版本 RoleHierarchyVoter 配置了 RoleHierarchy,它从中获取分配给用户的所有“可访问权限”。典型配置可能如下所示:

@Bean
static RoleHierarchy roleHierarchy() {
    RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
    hierarchy.setHierarchy("ROLE_ADMIN > ROLE_STAFF\n" +
            "ROLE_STAFF > ROLE_USER\n" +
            "ROLE_USER > ROLE_GUEST");
    return hierarchy;
}

// and, if using method security also add
@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler(RoleHierarchy roleHierarchy) {
	DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
	expressionHandler.setRoleHierarchy(roleHierarchy);
	return expressionHandler;
}

温馨提示:RoleHierarchy Bean 配置尚未移植到 @EnableMethodSecurity。因此,此示例使用的是 AccessDecisionVoter。如果需要 RoleHierarchy 支持方法安全性,请继续使用 @EnableGlobalMethodSecurity,直到 github.com/spring-projects/spring-security/issues/12783 完成。

在这里,我们在层次结构ROLE_ADMIN ⇒ ROLE_STAFF ⇒ ROLE_USER ⇒ ROLE_GUEST中有四个角色。使用 ROLE_ADMIN 进行身份验证的用户在针对适用于调用上述 RoleHierarchyVoter 的 AuthorizationManager 评估安全约束时,其行为将被视为具有所有四个角色。>符号可以被认为是“包括”的意思。

角色层次结构提供了一种方便的方法,可以简化应用程序的访问控制配置数据和/或减少需要分配给用户的权限数量。对于更复杂的要求,您可能希望在应用程序所需的特定访问权限和分配给用户的角色之间定义逻辑映射,以便在加载用户信息时在两者之间进行转换。

旧版授权组件

Spring Security 包含一些遗留组件。由于它们尚未删除,因此出于历史目的包含文档。他们推荐的替代品如上所述。

The AccessDecisionManager

AccessDecisionManager 由 AbstractSecurityInterceptor 调用,负责做出最终的访问控制决策。AccessDecisionManager 接口包含三种方法:

void decide(Authentication authentication, Object secureObject,
	Collection<ConfigAttribute> attrs) throws AccessDeniedException;

boolean supports(ConfigAttribute attribute);

boolean supports(Class clazz);

AccessDecisionManager 的 decide 方法传递了做出授权决策所需的所有相关信息。具体而言,传递安全对象可以检查实际安全对象调用中包含的那些参数。例如,假设安全对象是 MethodInvocation。您可以在 MethodInvocation 中查询任何 Customer 参数,然后在 AccessDecisionManager 中实现某种安全逻辑,以确保允许主体对该客户进行操作。如果访问被拒绝,则实现应引发 AccessDeniedException。

supports(ConfigAttribute) 方法由 AbstractSecurityInterceptor 在启动时调用,以确定 AccessDecisionManager 是否可以处理传递的 ConfigAttribute。supports(Class) 方法由安全侦听器实现调用,以确保配置的 AccessDecisionManager 支持安全侦听器提供的安全对象类型。

基于投票的 AccessDecisionManager 实现

虽然用户可以实现自己的 AccessDecisionManager 来控制授权的所有方面,但 Spring Security 包含多个基于投票的 AccessDecisionManager 实现。投票决策管理器描述了相关类。

下图显示了 AccessDecisionManager 接口:

通过使用此方法,将针对授权决策轮询一系列 AccessDecisionVoter 实现。然后,AccessDecisionManager 根据其对投票的评估决定是否引发 AccessDeniedException。

AccessDecisionVoter 接口有三种方法:

int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attrs);

boolean supports(ConfigAttribute attribute);

boolean supports(Class clazz);

具体实现返回一个 int,可能的值反映在名为 ACCESS_ABSTAIN、ACCESS_DENIED 和 ACCESS_GRANTED 的 AccessDecisionVoter 静态字段中。如果投票实现对授权决策没有反对,则返回 ACCESS_ABSTAIN。如果它确实有反对意见,它必须返回ACCESS_DENIED或ACCESS_GRANTED。

Spring Security 提供了三个具体的 AccessDecisionManager 实现来统计投票。ConsensusBased 实现根据非弃权票的共识授予或拒绝访问。提供属性以控制在票数相等或所有票数均弃权的情况下的行为。如果收到一个或多个ACCESS_GRANTED投票,则 AffirmativeBased 实现将授予访问权限(换句话说,如果至少有一个授予投票,则将忽略拒绝投票)。与 ConsensusBased 实现一样,如果所有投票者都弃权,则有一个参数来控制行为。UnanimousBased 提供程序期望获得一致的 ACCESS_GRANTED 票才能授予访问权限,而忽略了弃权票。如果有任何ACCESS_DENIED投票,它将拒绝访问。与其他实现一样,有一个参数用于控制所有投票者弃权时的行为。

您可以实现一个自定义 AccessDecisionManager,它以不同的方式计算投票。例如,来自特定 AccessDecisionVoter 的投票可能会获得额外的权重,而来自特定投票者的拒绝投票可能会产生否决权效应。

投票角色RoleVoter

Spring Security 提供的最常用的 AccessDecisionVoter 是 RoleVoter,它将配置属性视为角色名称,并在用户被分配了该角色时投票授予访问权限。

如果任何 ConfigAttribute 以 ROLE_ 前缀开头,它将投票。如果存在一个 GrantedAuthority,它返回的 String 表示形式(来自 getAuthority() 方法)与一个或多个以 ROLE_ 前缀开头的 ConfigAttributes 完全相等,则它会投票授予访问权限。如果任何以 ROLE_ 开头的 ConfigAttribute 没有完全匹配,则 RoleVoter 将投票拒绝访问。如果没有 ConfigAttribute 以 ROLE_ 开头,则投票者弃权。

AuthenticatedVoter

我们隐式看到的另一个投票者是 AuthenticatedVoter,它可用于区分匿名、完全身份验证和记住我身份验证的用户。许多站点允许在“记住我”身份验证下进行某些有限的访问,但要求用户通过登录来确认其身份才能获得完全访问权限。

当我们使用 IS_AUTHENTICATED_ANONYMOUSLY 属性授予匿名访问权限时,此属性正在由 AuthenticatedVoter 处理。有关详细信息,请参阅 AuthenticatedVoter。

自定义投票器Custom Voters

您还可以实现自定义 AccessDecisionVoter,并在其中放置所需的任何访问控制逻辑。它可能特定于您的应用程序(与业务逻辑相关),也可能实现某些安全管理逻辑。例如,在 Spring 网站上,您可以找到一篇博客文章,该文章介绍了如何使用投票者实时拒绝帐户已被暂停的用户的访问。

与 Spring Security 的许多其他部分一样,AfterInvocationManager 有一个具体的实现,即 AfterInvocationProviderManager,它轮询 AfterInvocationProviders 列表。允许每个 AfterInvocationProvider 修改返回对象或引发 AccessDeniedException。事实上,多个提供程序可以修改对象,因为前一个提供程序的结果将传递给列表中的下一个提供程序。

请注意,如果您使用的是 AfterInvocationManager,您仍然需要允许 MethodSecurityInterceptor 的 AccessDecisionManager 允许操作的配置属性。如果您使用的是典型的 Spring Security 包含的 AccessDecisionManager 实现,则没有为特定的安全方法调用定义配置属性将导致每个 AccessDecisionVoter 弃权。反过来,如果 AccessDecisionManager 属性“allowIfAllAbstainDecisions”为 false,则将引发 AccessDeniedException。您可以通过以下任一方式避免此潜在问题:(i) 将“allowIfAllAbstainDecisions”设置为 true(尽管通常不建议这样做)或 (ii) 仅确保 AccessDecisionVoter 将投票授予访问权限的至少一个配置属性。后一种(推荐)方法通常通过ROLE_USER或ROLE_AUTHENTICATED配置属性来实现。

参考文献:

《Spring bott官网》

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

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

相关文章

【论文解读】Accelerating motion estimation by genetic algorithm approach in x265

时间&#xff1a;2018 级别&#xff1a;SCI 机构&#xff1a;College of Engineering Pune 摘要&#xff1a; 在过去 20 年&#xff0c;在视频编码和压缩领域&#xff0c;研究人员提出了几种减少运动估计的计算量和时间的技术&#xff0c;本文提出了一种基于遗传算法初始种群确…

电脑ffmpeg.dll丢失如何修复?3个详细修复的教程分享

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“ffmpeg.dll丢失”。ffmpeg.dll是FFmpeg多媒体框架中的一个重要组件&#xff0c;它负责处理音频和视频的编解码。当这个文件丢失或损坏时&#xff0c;可能会导致一些应用程序无法正常运行。…

2023年【G2电站锅炉司炉】报名考试及G2电站锅炉司炉考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 G2电站锅炉司炉报名考试根据新G2电站锅炉司炉考试大纲要求&#xff0c;安全生产模拟考试一点通将G2电站锅炉司炉模拟考试试题进行汇编&#xff0c;组成一套G2电站锅炉司炉全真模拟考试试题&#xff0c;学员可通过G2电…

如何有效利用餐厅预约小程序推广餐厅品牌

随着餐饮行业竞争的加剧&#xff0c;餐厅订座预约成为了吸引顾客的一种重要方式。而微信小程序作为移动互联网的重要入口之一&#xff0c;为餐厅提供了一个方便快捷的预约平台。本文将介绍如何使用乔拓云平台等第三方小程序制作平台来开发餐厅订座预约微信小程序。 首先&#x…

进程、容器与虚拟机的区别

进程、容器与虚拟机 参考&#xff1a;关于进程、容器与虚拟机的区别&#xff0c;你想知道的都在这&#xff01; 进程、容器与虚拟机的结构图 进程 介绍 进程是一个正在运行的程序&#xff0c;它是一个个可执行文件的实例。当一个可执行文件从硬盘加载到内存中的时候&#xf…

【FreeRTOS】FreeRTOS移植stm32详细步骤介绍

我在查找FreeRTOS移植的相关教程特别少&#xff0c;所以想非常详细的介绍FreeRTOS移植stm32详细步骤&#xff0c;包括源码的下载&#xff0c;源码介绍&#xff0c;系统移植&#xff0c;代码验证等&#xff0c;每一步都有对应的介绍和解释&#xff0c;希望可以帮助到你们。 文章…

1. mycat入门

1、mycat介绍 Mycat 是一个开源的分布式数据库系统&#xff0c;但是由于真正的数据库需要存储引擎&#xff0c;而 Mycat 并没有存 储引擎&#xff0c;所以并不是完全意义的分布式数据库系统。MyCat是目前最流行的基于Java语言编写的数据库中间件&#xff0c;也可以理解为是数据…

Firmware Analysis Plus (Fap)固件模拟安装教程(最新)

最近在搞IoT的研究&#xff0c;但是难在设备比较难弄&#xff0c;只有固件&#xff0c;而没有设备&#xff0c;买吧&#xff0c;又太费钱&#xff0c;不划算。好在有很多项目可以在模拟环境中运行固件。但是几乎没有一个平台能够模拟所有硬件设备。IoT产品的架构也不尽相同。 …

C++初学教程四

一、程序设计 程序设计的三种基本结构:顺序、选择、循环 选择结构(也叫分支结构) :判断所指定的条件是否满足&#xff0c;决定从给定的两组或多组操作选择其中的一种。 计算机的判断是通过对表达式的计算来实现&#xff0c;也就是关系运算、逻辑运算。 用语句来体现就是if语…

53 代码审计-TP5框架及无框架变量覆盖反序列化

目录 演示案例:Metinfo-无框架-变量覆盖-自动审计或搜索phpmyadmin-无框架-反序列化-自动审计或搜索Thinkphp5-有框架-搭建使用入口访问调试SQL等 演示案例: Metinfo-无框架-变量覆盖-自动审计或搜索 变量覆盖会直接覆盖原始变量&#xff0c;来形成新的变量值 搜索关键字或者…

IDEA版SSM入门到实战(Maven+MyBatis+Spring+SpringMVC) -Spring IOC底层实现

第一章 SpringIOC底层实现 IOC&#xff1a;将对象的控制器反转给Spring 1.1 BeanFactory与ApplicationContexet BeanFactory&#xff1a;IOC容器的基本实现&#xff0c;是Spring内部的使用接口&#xff0c;是面向Spring本身的&#xff0c;不是提供给开发人员使用的。****Appli…

APP自动化测试工具大全

一、UI自动化测试工具 1. uiautomator2 openatx开源的ui自动化工具&#xff0c;支持Android和iOS。主要面向的编程语言是Python&#xff0c;API设计简洁易用&#xff0c;在开源社区也是很受欢迎。 安装&#xff1a; pip install --upgrade --pre uiautomator2# Or you can …

IO / day07 作业

1. 使用消息队列完成两个进程之间相互通信 代码 #include <myhead.h>//define a msg struct type struct msgbuf {long mtype; //消息类型char mtext[1024]; //消息正文大小};//macro msg size #define SIZE (sizeof(struct msgbuf)-sizeof(long))int recv(int mtype_r…

Vue学习计划-Vue2--VueCLi(三)ref属性、mixins混入、插件、scoped样式

1. ref属性 被用来给元素或子组件注册引用信息&#xff08;id的替代者&#xff09;应用在html标签上获取的是真实DOM元素&#xff0c;应用在组件标签上是组件实例对象&#xff08;VC&#xff08;VueComponent&#xff09;&#xff09;使用方式&#xff1a; 打标识<h1 ref&q…

火山引擎边缘计算用硬核助力赛事直播

经过一个多月激烈争夺&#xff0c;2023英雄联盟全球总决赛终于在11月19日落下帷幕。精彩的对决和高热话题使得直播平台观赛人数暴增&#xff0c;给直播平台稳定性和资源储备提出了巨大的考验。

macosx dbeaver执行脚本报错提示:还没有设置连接地址

1.原因 因为你本地没有安装MySql Client所以按照网上其他操作办法你找不到MySql的客户端&#xff0c;因此配置客户端的时候自然就找不到对应的文件. 2.解决办法 参考DBeaver提供的解决办法&#xff1a; https://dbeaver.com/docs/dbeaver/Local-Client-Configuration/#local…

【复杂网络建模】——基于Graph Convolutional Networks (GCN)进行链接预测

目录 一、复杂网络建模 二、图嵌入方法&#xff08;Graph Convolutional Networks (GCN) &#xff09; 1. 图表示&#xff1a; 2. 邻接矩阵&#xff08;Adjacency Matrix&#xff09;&#xff1a; 3. 图卷积层&#xff08;Graph Convolutional Layer&#xff09;&#xff…

docker的资源控制:

docker的资源控制&#xff1a; 对容器的使用宿主机的资源进行限制 cpu 内存 磁盘i/0 docker使用linux自带的功能cgroup control grouos是linux内核系统提供的一种可以限制&#xff0c;记录&#xff0c;隔离进程所使用的物理资源 control grouos是linux内核系统提供的一种可…

【动态规划】03斐波那契数列模型_最小花费爬楼梯_C++(easy1)

题目链接&#xff1a;leetcode使用最小花费爬楼梯 目录 题目解析&#xff1a; 算法原理 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 编写代码 题目解析&#xff1a; 题目让我们求达到楼梯顶部的最低花费. 由题可得&#xff1a; cost[i] 是从楼梯第 i 个…

【LeetCode刷题-树】--113.路径总和II

113.路径总和II 方法一&#xff1a;深度优先搜素 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeN…
最新文章