golang常用库之-ladon包 | 基于策略的访问控制

https://github.com/ory/ladon

Ladon是保护您资源的蛇龙。

Ladon是一个库,用于访问控制策略,类似于基于角色的访问控制或访问控制列表。与ACL和RBAC相比,您可以获得细粒度的访问控制,并能够在复杂环境中回答问题,例如多租户或分布式应用程序和大型组织。Ladon受到AWS IAM Policies 的启发。

A SDK for access control policies: authorization for the microservice and IoT age. Inspired by AWS IAM policies. Written for Go.

Ladon 是用 Go 语言编写的用于实现访问控制策略的库,类似于 RBAC(基于角色的访问控制系统,Role Based Access Control)和 ACL(访问控制列表,Access Control Lists)。但是与 RBAC 和 ACL 相比,Ladon 可以实现更细粒度的访问控制,并且能够在更为复杂的环境中(例如多租户、分布式应用程序和大型组织)工作。

概念

Ladon is an access control library that answers the question:

  • Who: An arbitrary unique subject name, for example “ken” or “printer-service.mydomain.com”.
  • Able: The effect which can be either “allow” or “deny”.
  • An arbitrary action name, for example “delete”, “create” or “scoped:action:something”.
  • Something: An arbitrary unique resource name, for example “something”, “resources.articles.1234” or some uniform resource name like “urn:isbn:3827370191”.
  • Context: The current context containing information about the environment such as the IP Address, request date, the resource owner name, the department ken is working in or any other information you want to pass along. (optional)

通常来说,一条完整的策略可以明确告诉我们:谁在特定环境下可以做什么。

  • subject:对应「谁」,即主体。

  • action:对应「可以做」,即操作的种类,比如增删改查。

  • resource:对应「做什么」,即具体操作的资源。

  • context:对应「特定环境」,即一些限制条件,可选。

使用

我们已经讨论了Ladon的两个基本部分:policies 和access control requests。让我们仔细看看这两个人。

策略

Ladon 解决了这个问题:在特定的条件下,谁能够 / 不能够对哪些资源做哪些操作。为了解决这个问题,Ladon 引入了授权策略。授权策略是一个有语法规范的文档,这个文档描述了谁在什么条件下能够对哪些资源做哪些操作。 Ladon 可以用请求的上下文,去匹配设置的授权策略,最终判断出当前授权请求是否通过

策略是访问控制决策的基础。将它们视为一系列规则。 在这个库中,策略被抽象为Ladon.Policy接口,Ladon附带了这个接口的标准实现,它是Ladon.defaultPolicy。创建这样的策略可以如下所述:

import "github.com/ory/ladon"

var pol = &ladon.DefaultPolicy{
	// A required unique identifier. Used primarily for database retrieval.
	ID: "68819e5a-738b-41ec-b03c-b58a1b19d043",

	// A optional human readable description.
	Description: "something humanly readable",

	// A subject can be an user or a service. It is the "who" in "who is allowed to do what on something".
	// As you can see here, you can use regular expressions inside < >.
	Subjects: []string{"max", "peter", "<zac|ken>"},

	// Which resources this policy affects.
	// Again, you can put regular expressions in inside < >.
	Resources: []string{
            "myrn:some.domain.com:resource:123", "myrn:some.domain.com:resource:345",
            "myrn:something:foo:<.+>", "myrn:some.domain.com:resource:<(?!protected).*>",
            "myrn:some.domain.com:resource:<[[:digit:]]+>"
        },

	// Which actions this policy affects. Supports RegExp
	// Again, you can put regular expressions in inside < >.
	Actions: []string{"<create|delete>", "get"},

	// Should access be allowed or denied?
	// Note: If multiple policies match an access request, ladon.DenyAccess will always override ladon.AllowAccess
	// and thus deny access.
	Effect: ladon.AllowAccess,

	// Under which conditions this policy is "active".
	Conditions: ladon.Conditions{
		// In this example, the policy is only "active" when the requested subject is the owner of the resource as well.
		"resourceOwner": &ladon.EqualsSubjectCondition{},

		// Additionally, the policy will only match if the requests remote ip address matches address range 127.0.0.1/32
		"remoteIPAddress": &ladon.CIDRCondition{
			CIDR: "127.0.0.1/32",
		},
	},
}

下面是一个 Ladon 的授权策略样例:


{
  "description": "One policy to rule them all.",
  "subjects": ["users:<peter|ken>", "users:maria", "groups:admins"],
  "actions" : ["delete", "<create|update>"],
  "effect": "allow",
  "resources": [
    "resources:articles:<.*>",
    "resources:printer"
  ],
  "conditions": {
    "remoteIP": {
        "type": "CIDRCondition",
        "options": {
            "cidr": "192.168.0.1/16"
        }
    }
  }
}

策略(Policy)由若干元素构成,用来描述授权的具体信息,你可以把它们看成一组规则。核心元素包括主题(Subject)、操作(Action)、效力(Effect)、资源(Resource)以及生效条件(Condition)。元素保留字仅支持小写,它们在描述上没有顺序要求。对于没有特定约束条件的策略,Condition 元素是可选项。一条策略包含下面 6 个元素:

  • 主题(Subject),主题名是唯一的,代表一个授权主题。例如,“ken” or “printer-service.mydomain.com”。
  • 操作(Action),描述允许或拒绝的操作。
  • 效力(Effect),描述策略产生的结果是“允许”还是“拒绝”,包括 allow(允许)和 deny(拒绝)。
  • 资源(Resource),描述授权的具体数据。
  • 生效条件(Condition),描述策略生效的约束条件。
  • 描述(Description),策略的描述。

有了授权策略,我们就可以传入请求上下文,由 Ladon 来决定请求是否能通过授权。下面是一个请求示例:

{
  "subject": "users:peter",
  "action" : "delete",
  "resource": "resources:articles:ladon-introduction",
  "context": {
    "remoteIP": "192.168.0.5"
  }
}

可以看到,在 remoteIP=“192.168.0.5” 生效条件(Condition)下,针对主题(Subject) users:peter 对资源(Resource) resources:articles:ladon-introduction 的 delete 操作(Action),授权策略的效力(Effect)是 allow 的。所以 Ladon 会返回如下结果:

{
    "allowed": true
}

Ladon 支持很多 Condition

条件 Conditions

golang常用库之-golang常用库之-ladon包 | 基于策略的访问控制-LMLPHP

golang常用库之-golang常用库之-ladon包 | 基于策略的访问控制-LMLPHP
Conditions 功能是返回 true 或 false 在给定的 context。因为conditions 实现逻辑,因此必须编程它们。策略中添加条件包括两个部分,一个a key name和Ladon.Condition接口的实现:

自定义condition

Ladon Condition使用示例
参考URL: https://github.com/marmotedu/geekbang-go/blob/master/LadonCondition%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B.md

我们还可以自定义condition,然后将自定义的condition添加到ladon.ConditionFactories中,例如:

import "github.com/ory/ladon"

func main() {
    // ...

    ladon.ConditionFactories[new(CustomCondition).GetName()] = func() Condition {
        return new(CustomCondition)
    }

    // ...
}

自定义condition很简单,读者可以参考ory/ladon项目根目录下的condition_boolean.go文件,将BooleanCondition替换为CustomCondition就得到了一个简单的自定义condition。

Ladon Condition使用示例

Ladon Condition使用示例
参考URL: https://github.com/marmotedu/geekbang-go/blob/master/LadonCondition%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B.md

持久化

访问控制(Warden)

现在我们已经确定了我们的策略,我们可以使用Warden检查请求是否有效。Ladon.Ladon,这是Ladon.Warden接口的默认实现定义ladon.Ladon.IsAllowed()如果可以授予访问请求并否则错误,则会返回nil。

import "github.com/ory/ladon"

func main() {
    // ...

    err := warden.IsAllowed(&ladon.Request{
        Subject: "peter",
        Action: "delete",
        Resource: "myrn:some.domain.com:resource:123",
        Context: ladon.Context{
            "ip": "127.0.0.1",
        },
    })
    if err != nil {
        log.Fatal("Access denied")
    }

    // ...
}

结合 Gin 开发一个简易 ACL 接口

结合 Gin 开发一个简易 ACL 接口
参考URL: https://www.bilibili.com/read/cv6934197/

通常来说,一条完整的策略可以明确告诉我们:谁在特定环境下可以做什么。

  • subject:对应「谁」,即主体。

  • action:对应「可以做」,即操作的种类,比如增删改查。

  • resource:对应「做什么」,即具体操作的资源。

  • context:对应「特定环境」,即一些限制条件,可选。

参考

技术·原创 | 零信任与基于策略的访问控制
参考URL: https://blog.csdn.net/xixiangkeji/article/details/115177593
从零开始入门 K8s | K8s 安全之访问控制
参考URL: https://www.kubernetes.org.cn/6974.html
Go 语言项目开发实战
参考URL: https://time.geekbang.org/column/article/404542
Ladon 折腾手记:结合 Gin 开发一个简易 ACL 接口
参考URL: https://www.bilibili.com/read/cv6934197/

03-17 22:38