XACML策略实现资源独占使用
1. XACML基本数据流程
在资源访问控制中,XACML(可扩展访问控制标记语言)有着一系列关键的数据流程:
1.
Flow 4
:将访问请求转换为策略决策点(PDP)能够理解的格式。
2.
Flow 10
:针对Flow 5,从策略信息点(PIP)收集资源、请求者属性以及当前系统状态,以此生成评估上下文,然后传递给PDP。这里的信息收集涉及Flows 6、7、8和9。
3.
Flow 12
:从PDP接收策略决策,并将其转换回策略执行点(PEP)。PDP会评估适用于访问请求和伴随上下文的XACML策略。若评估失败,访问将被拒绝;反之,则允许访问。该决策会提供给Flow 11的上下文处理程序,并转发给PEP进行执行。
为了增强XACML的访问控制决策,引入了锁管理器(LM),这带来了额外的数据流程:
1.
Flow 5b - 更新系统请求(USR)
:可能由PDP发起,用于更新系统资源以建立访问。例如,启用某个角色可能需要更新用户会话(一种系统资源)。
2.
Flow 5c - 创建锁请求(CRL)
:由PDP代表请求进程发起,用于对可用资源进行独占访问。最终会细化为acquireLock操作(9c),此时锁由请求进程持有。
3.
Flow 10 - 对PDP查询的响应(重载)
:除了资源查询响应外,还复用上下文处理程序发送给PDP查询的响应来发送USR和CRL响应。
4.
Flow 9b - 资源更新
:在执行访问控制决策后,PEP会更新内部访问日志。此数据流程有助于实现基于历史的资源使用控制。
5.
Flow 9c - 获得锁
:指示LM代表请求者调用锁。根据资源的可用性,此操作可能成功或失败。
在进行策略评估之前,假定所有属性都已通过属性证书认证进行了身份验证。
2. 锁管理器(LM)设计
锁管理器是一个特权进程,在任何给定时间,只有一个实例运行。它负责维护和创建其所管理资源的锁,具体功能如下:
1.
锁获取
:锁获取是一个原子操作acquireLock,类似于Unix的test&set操作。该操作关联两个字符串:requesterId和resourceId,它们可以是网络实体的限定名称或URI。实际调用由锁管理器在临界区中完成。
2.
锁释放
:锁释放是一个原子过程,通过releaseLock方法实现。
3.
锁验证
:verifyLock操作用于验证锁的有效性。执行模型规定,每次资源更新前都必须调用verifyLock,由资源管理器调用以验证锁的有效性。请求者获取锁后,在使用资源时需向资源管理器出示锁定权限,资源管理器再与锁管理器或PDP验证其有效性。
4.
单一LM注册
:资源必须使用X.509属性证书绑定到单个锁管理器进行注册,这是基本设计要求,由本地证书颁发机构执行。
3. 增强上下文处理程序
为了实现更多功能,对上下文处理程序进行了增强,包括资源池的启动、终止和维护,以及扩展业务逻辑。
1.
资源池维护
:扩展上下文处理程序以支持锁管理器的启动和资源池的维护。相关算法以伪代码形式呈现,“–>”符号表示调用上下文处理程序内的子模块。
2.
安全注册资源
:为防止资源发起多个并发注册请求,引入了安全注册流程。资源发起注册请求时,需附带包含资源和锁管理器的可验证属性证书。以下是安全注册算法:
1 register(R,C,LM)
2 Inputs: R(resource), C(certificate), LM(lock manager)
3 Output: Lock information, Exception
4
5 Translate request to XML document
6 Pass translated XML to PDP Handler
7 -->Invoke PDP to verify R,C and LM
8
if (decision == accept)
9
Lock Request for lock to global.lock
10
-->Acquire lock to global.lock
11
Update System Request for variable
12
-->Create variable lock.R
13
if (lock.R NOT IN global.lock)//
14
Assign lock.R.subjectID = ""
15
Insert lock.R in global.lock
16
Assign message = lock.R
17
Hand request to PostProcessor
18
-->Lock Request for release lock
19
-->Release lock
20
Return request+message to Request Handler
21
else
22
Assign exception = Already Registered
23
Hand Request to PostProcessor
24
-->Lock Request for release lock
25
-->Release lock
26
Return request+exception to Request Handler
27
else
28
Assign exception = Invalid Request
29
Hand the request to PostProcessor
30
-->Return request+exception to Request Handler
该算法的步骤如下:
- 接收资源R、属性证书C和锁管理器LM作为输入。
- 将请求转换为XML文档并传递给PDP处理程序。
- 调用PDP验证输入信息。
- 如果验证通过,获取全局锁,创建变量锁lock.R。若lock.R不在全局锁中,初始化其subjectID并插入全局锁,然后释放锁并返回锁信息。
- 如果验证失败,根据情况返回相应的异常信息。
- 安全注销资源 :与注册类似,注销资源也需要锁支持,以防止在使用时被注销。以下是安全注销算法:
1 deregister(R,C,LM)
2 Inputs: R(resource), C(certificate), LM(lock manager)
3 Output: boolean, Exception
4
5 Translate request to XML document
6 Pass translated XML to PDP Handler
7 -->Invoke PDP to verify R,C and LM
8
if (decision == accept)
9
Lock Request for lock to global.lock
10
-->Acquire lock to global.lock
11
if (acquirelock()== false)
12
Assign exception = In use // no waiting!!
13
Hand request to PostProcessor
14
-->Send request+exception to Request Handler
15
else
16
if(lock.R IN global.lock && lock.R.subjectId="")
17
Update System Request
18
-->Assign global.lock = global.lock -lock.R
19
Assign message = true
20
Hand request to PostProcessor
21
-->Lock Request for release lock
22
-->Release Lock // will succeed
23
Return request+message to Request Handler
24
else
25
Assign exception = Does not exist/In use
26
Hand Request to PostProcessor
27
-->Lock Request for release lock
28
-->Release lock
29
Return request+exception to Request Handler
30
else
31
Assign exception = Invalid Request
32
Hand the request to PostProcessor
33
-->Return request+exception to Request Handler
该算法的步骤如下:
- 接收资源R、属性证书C和锁管理器LM作为输入。
- 将请求转换为XML文档并传递给PDP处理程序。
- 调用PDP验证输入信息。
- 如果验证通过,获取全局锁。若无法获取锁,表示资源正在使用,返回相应异常。
- 若锁存在且未被占用,从全局锁中移除该锁,释放锁并返回成功信息。
- 如果验证失败,返回无效请求异常。
4. 扩展业务逻辑
- 获得资源的独占访问权 :资源注册后,可通过以下过程保证对其的独占访问:
1 exclusiveAccess(R,S)
2 Input: R (resource), S (Subject)
3 Output: boolean, Exception
4
5 Translate request to XML document
6 Pass translated XML to Pre processor
7 -->Lock Request for lock to global.lock
8
-->Acquire lock to global.lock
9
if (acquireLock() == false)
10
Assign exception = In use // no wait
11
Hand Request to PostProcessor
12
-->Send Request+exception to Request Handler
13
else
14
Hand request to PDP Handler
15
-->Invoke PDP for authorizing S to R
16
-->Attribute Query for lock.R
17
-->Read lock.R
18
if(lock.R IN global.lock)
19
send lock.R to PDP
20
else
21
exception = resource unknown
22
Hand request to PostProcessor
23
-->Return Request+exception // to RH
24
if (decision == accept)
25
Update System Request
26
-->Assign lock.R.subjectId = S
27
Assign message = true //
28
Hand request to PostProcessor
29
-->Lock Request for release lock
30
-->Release Lock
31
Return request+message to Request Handler
32
else
33
Assign exception = Invalid Request
34
Hand the request to PostProcessor
35
-->Return request+exception to Request Handler
该算法的步骤如下:
- 接收资源R和主体S作为输入。
- 将请求转换为XML文档并传递给预处理器。
- 获取全局锁,若无法获取锁,表示资源正在使用,返回相应异常。
- 将请求传递给PDP处理程序,调用PDP进行授权验证。
- 查询锁信息,若锁存在,将其发送给PDP。
- 如果授权通过,更新系统请求,将锁的所有者设置为主体S,释放锁并返回成功信息。
- 如果授权失败,返回无效请求异常。
- 使用资源 :当请求者获得资源的独占访问权后,通过PEP调用资源。资源管理器有责任确保请求者拥有有效的锁,这通过向锁管理器调用verifyLock来实现。
- 保证动态/基于历史的访问约束 :执行动态约束的步骤如下:
1 accessResource(R,S)
2 Inputs: R (resource), S (Subject)
3 Output: boolean, Exception
4
5 Translate request to XML document
6 Pass translated XML to Pre processor
7 -->Locate internal resources for the request
8
Lock Request for locks to all internal resources
9
-->while(more resources)
10
{ Acquire lock } // locking phase
11
if (all locks acquired == false)
12
Assign exception = Cannot process // no wait
13
Hand Request to PostProcessor
14
-->Send Request+exception to Request Handler
15
else
16
Invoke PDP for authorizing S to R
17
Attribute Queries (optionally)
18
-->Read attribute
19
if(attribute present)
20
send attribute to PDP
21
else
22
exception = resource unknown
23
Hand request to PostProcessor
24
-->Send Request+exception to Request Handler
25
if (decision == accept)
26
Update System Request
27
-->while(more resources need updation)
28
{ update ith resource }
29
Assign message = true //
30
Hand request to PostProcessor
31
-->Lock Request for releasing all locks
32
-->Release Lock
33
Return request+message to Request Handler
34
else
35
Assign exception = Invalid Request
36
Hand the request to PostProcessor
37
-->Return request+exception to Request Handler
该算法的步骤如下:
- 接收资源R和主体S作为输入。
- 将请求转换为XML文档并传递给预处理器。
- 定位请求所需的内部资源,并获取所有内部资源的锁。
- 若无法获取所有锁,返回无法处理的异常。
- 调用PDP进行授权验证,可选择性地查询属性信息。
- 如果属性存在,将其发送给PDP。
- 如果授权通过,更新系统请求,更新所有需要更新的资源,释放所有锁并返回成功信息。
- 如果授权失败,返回无效请求异常。
- 释放资源 :持有锁的资源请求者可以释放资源,具体实现是对上述算法的简单修改。
5. 增强设计的实现
-
数据结构
:
- 锁数据结构 :
<xs:element name="Lock"
type="xacml-context:LockType"/>
<xs:complexType name="LockType">
<xs:sequence>
<xs:element name="resourceId" type="xs:string"
minOccurs="1" maxOccurs="1"/>
<xs:element name="ownerId" type="xs:string"
minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
该数据结构通过resourceID和ownerId标识锁。可用锁的ownerId为空字符串,已锁定资源的ownerId为非空字符串。多个这样的锁存储在全局LM数据结构GlobalLock中。
-
全局锁数据结构
:
<xs:element name="GlobalLock"
type="xacml-context:GlobalLockType"/>
<xs:complexType name="GlobalLockType">
<xs:sequence>
<xs:element ref="xacml-context:GlobalLockEntryType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
- **全局锁条目类型**:
<xs:complexType name="GlobalLockEntryType">
<xs:sequence>
<xs:element name="resource" type="xacml-context:Resource"
minOccurs="1" maxOccurs="1"/>
<xs:element name="lock" type="xacml-context:Lock"
minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
该数据结构存储资源及其锁的键值对。
2.
WSDL消息定义
:
<wsdl:message name="aquireLockRequest">
<wsdl:part name="correlationSet" element=
"xacml-context:CorrelationSet" />
<wsdl:part name="lock" element=
"xacml-context:Lock" />
</wsdl:message>
<wsdl:message name="lockResult">
<wsdl:part name="correlationSet" element=
"xacml-context:CorrelationSet" />
<wsdl:part name="result" element=
"xacml-context:LockResult" />
</wsdl:message>
这些定义用于锁获取请求和结果响应。
3.
Java实现
:
public class LockManager {
// list of all the resources and locks
public static Map GlobalLock = new HashMap();
/**
* Aquire a lock
*/
public static LockResult aquireLock (AquireLockRequest request) {
Lock lock = null;
boolean aquireSuccess = false;
// aquire global lock
synchronized (GlobalLock) {
// if lock already acquired or not registered then fail
if (GlobalLock.containsKey(request.getResourceId())) {
lock = GlobalLock.get(request.getResourceId());
if (lock==null) {
// if no locks exist on the resource
// then create a new resource
lock = new Lock();
lock.setOwnerId(request.getActorId());
lock.setResourceId(request.getResourceId());
GlobalLock.put(request.getResourceId(), lock);
aquireSuccess = true;
}
}
} // release the global lock
LockResult result = new LockResult();
if (!aquireSuccess) {
// couldnt aquire lock
result.setStatus("fail");
} else {
// lock aquired
result.setStatus("pass");
result.setLock(lock);
}
return result;
}
}
该Java实现用于获取现有资源的锁。通过对GlobalLock数据结构进行同步访问,检查资源是否已注册和锁是否已授予,若未授予则创建新锁并更新GlobalLock。最后根据结果设置返回状态。
6. 安全性和活性属性
由于允许并发请求并使用锁来序列化对安全监视器关键部分的访问,因此确保了活性和安全性属性:
1.
引理1
:给定资源池R和一组锁管理器L,资源Ri ∈R只能注册到单个锁管理器Lj ∈L。
2.
引理2
:给定资源Ri和它可以注册的锁管理器LK,register方法确保Ri只能在LK上注册一次。
3.
引理3
:给定资源Ri和它已注册的锁管理器LK,deregister方法确保只有Ri可以从LK注销。
4.
定理1(独占访问的安全性)
:给定用于对可用资源R进行独占访问的XACML策略P,以及来自主体Si(i ∈[1, n])的多个并发访问请求(即exclusiveAccess(R, Si)),策略P只授权上述集合中的一个请求。
5.
定理2(动态约束的安全性)
:给定用于资源访问动态约束的XACML策略P和多个冲突的访问请求(accessResource(R, Si)),策略P只授权一个请求。
6.
定理3(活性1)
:给定资源R和主体S的独占使用访问请求(exclusiveAccess(R,S)),无论访问控制决策如何,策略评估都会释放所有内部资源的锁。
7.
定理4(活性2)
:给定资源x、y和主体S的独占使用访问请求(exclusiveAccess(x,S) 后接exclusiveAccess(y,S))以及主体T的并发独占使用访问请求(exclusiveAccess(y,T) 后接exclusiveAccess(x,T)),策略评估至少会拒绝一个独占访问请求,并释放为该策略评估获取的所有锁。
7. 结论
XACML是万维网默认的访问控制规范语言,但目前不支持三种类型的访问控制用例:确保对全局可用资源的独占访问、防止在另一个资源被并发冲突使用时访问某个资源(DSoD约束)以及防止在有冲突访问历史时访问某个资源(如中国墙约束)。通过用锁管理器增强XACML策略执行框架,扩展了XACML语法以支持上述用例,并通过非正式论证表明实现保证了安全性和活性属性。
XACML策略实现资源独占使用
8. 关键数据流程总结
为了更清晰地理解整个资源访问控制过程,下面对关键的数据流程进行总结,以表格形式呈现:
| 流程编号 | 流程名称 | 描述 |
| — | — | — |
| Flow 4 | 访问请求转换 | 将访问请求转换为PDP能理解的格式 |
| Flow 10 | 评估上下文生成 | 从PIP收集资源、请求者属性和系统状态,生成评估上下文并传递给PDP |
| Flow 12 | 策略决策传递 | 从PDP接收策略决策并转换回PEP |
| Flow 5b | 更新系统请求(USR) | 由PDP发起,更新系统资源以建立访问 |
| Flow 5c | 创建锁请求(CRL) | 由PDP代表请求进程发起,用于独占访问可用资源 |
| Flow 9b | 资源更新 | PEP在执行访问控制决策后更新内部访问日志 |
| Flow 9c | 获得锁 | 指示LM代表请求者调用锁 |
下面是整个过程的mermaid格式流程图:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始]):::startend --> B(Flow 4: 转换访问请求):::process
B --> C(Flow 5: 相关操作触发):::process
C --> D(Flow 10: 生成评估上下文):::process
D --> E(PDP评估策略):::process
E --> F{评估结果}:::decision
F -->|通过| G(Flow 12: 传递决策到PEP):::process
F -->|失败| H(拒绝访问):::process
G --> I(Flow 5b: 更新系统请求):::process
G --> J(Flow 5c: 创建锁请求):::process
I --> K(Flow 9b: 资源更新):::process
J --> L(Flow 9c: 获得锁):::process
K --> M([结束]):::startend
L --> M
H --> M
9. 算法对比分析
为了更好地理解各个算法的特点和适用场景,下面对安全注册、安全注销、独占访问和动态约束算法进行对比分析:
| 算法名称 | 输入 | 输出 | 主要步骤 | 适用场景 |
| — | — | — | — | — |
| 安全注册 | 资源R、属性证书C、锁管理器LM | 锁信息、异常 | 转换请求为XML,验证信息,获取全局锁,创建锁,更新全局锁 | 资源首次注册到锁管理器 |
| 安全注销 | 资源R、属性证书C、锁管理器LM | 布尔值、异常 | 转换请求为XML,验证信息,获取全局锁,移除锁,更新全局锁 | 资源从锁管理器注销 |
| 独占访问 | 资源R、主体S | 布尔值、异常 | 转换请求为XML,获取全局锁,验证授权,更新锁信息 | 请求对资源的独占访问 |
| 动态约束 | 资源R、主体S | 布尔值、异常 | 转换请求为XML,获取内部资源锁,验证授权,更新资源 | 执行动态访问约束 |
10. 代码示例的详细解释
下面对Java实现的
aquireLock
方法进行详细解释:
public class LockManager {
// list of all the resources and locks
public static Map GlobalLock = new HashMap();
/**
* Aquire a lock
*/
public static LockResult aquireLock (AquireLockRequest request) {
Lock lock = null;
boolean aquireSuccess = false;
// aquire global lock
synchronized (GlobalLock) {
// if lock already acquired or not registered then fail
if (GlobalLock.containsKey(request.getResourceId())) {
lock = GlobalLock.get(request.getResourceId());
if (lock==null) {
// if no locks exist on the resource
// then create a new resource
lock = new Lock();
lock.setOwnerId(request.getActorId());
lock.setResourceId(request.getResourceId());
GlobalLock.put(request.getResourceId(), lock);
aquireSuccess = true;
}
}
} // release the global lock
LockResult result = new LockResult();
if (!aquireSuccess) {
// couldnt aquire lock
result.setStatus("fail");
} else {
// lock aquired
result.setStatus("pass");
result.setLock(lock);
}
return result;
}
}
-
全局锁数据结构
:
GlobalLock是一个HashMap,用于存储所有资源及其对应的锁。 -
锁获取方法
:
aquireLock方法接收一个AquireLockRequest对象作为参数。 -
同步访问
:使用
synchronized (GlobalLock)确保在同一时间只有一个线程可以访问GlobalLock,避免并发问题。 -
检查资源是否注册
:通过
GlobalLock.containsKey(request.getResourceId())检查资源是否已注册。 -
创建新锁
:如果资源已注册但锁为空,则创建一个新锁,设置其所有者和资源ID,并将其添加到
GlobalLock中。 -
返回结果
:根据锁获取结果设置
LockResult对象的状态,并返回该对象。
11. 实际应用中的考虑因素
在实际应用中,使用XACML策略实现资源独占使用需要考虑以下因素:
1.
性能
:由于使用了锁机制,可能会影响系统的性能。需要合理设计锁的粒度,避免锁竞争过于激烈。
2.
并发控制
:确保在高并发场景下,系统能够正确处理多个请求,避免死锁和资源竞争问题。
3.
证书管理
:属性证书的管理至关重要,需要确保证书的有效性和安全性。
4.
错误处理
:在各个算法中,都有异常处理机制,但在实际应用中,需要根据具体情况进行更详细的错误处理和日志记录。
12. 总结与展望
通过引入锁管理器和扩展上下文处理程序,XACML策略能够有效地实现资源的独占使用,同时保证了安全性和活性属性。在实际应用中,需要根据具体需求和场景,合理调整算法和配置,以提高系统的性能和可靠性。
未来,可以进一步研究如何优化锁机制,减少锁竞争对系统性能的影响。同时,可以探索与其他安全机制的结合,提供更全面的访问控制解决方案。此外,随着技术的不断发展,可能会出现新的访问控制需求,需要不断扩展和完善XACML策略。
超级会员免费看
2920

被折叠的 条评论
为什么被折叠?



