
# 策略变量
#### 策略变量简介
在创建自定义策略时，策略中Resource元素或Condition元素的条件值可以使用策略变量作为占位符。在策略实际鉴权的时候，这些占位符将会被自动替换成请求上下文中指定条件键的值。
#### 策略变量语法与替换规则说明
策略变量结构支持使用$前缀，后跟一对大括号{ }。在大括号内，需要填入想要使用的请求上下文中的条件键的名称，例如${g:UserName}。在实际策略鉴权的时候，${g:UserName}将被自动替换为条件键g:UserName的值。
![](https://support.huaweicloud.com/usermanual-iam/public_sys-resources/note_3.0-zh-cn.png)
Condition条件值的变量可以填写在任意位置，Resource元素的变量只能填写在Resource以":"分隔的五段式中的最后一段，例如：OBS:\*:\*:bucket:${g:UserName}。
如果指定条件键在请求上下文中不存在，或者指定条件键是多值条件键，那么将会替换失败，可能会导致整个语句无效。例如当且仅当访问身份是IAM用户时，请求中才会存在g:UserName。如果以其他身份访问，那么所有包含${g:UserName}的资源和条件键都将视作不匹配。同理，对于多值条件键（指一个条件键对应多个值），即使它存在于请求上下文中，由于它是多值条件键，依然会被判定为替换失败，从而视作不匹配。
如果变量指定的条件键替换失败，您可以为它提供原定设置文本作为默认值。要向变量添加默认值，请用单引号' '括起默认值，并用英文逗号和空格分隔条件键名称和默认值，例如${key, 'default'}，表示当key不存在或者替换失败时，将${key, 'default'}替换为文本串default。条件键名称不区分大小写，但是默认值区分大小写。此外，条件键名称与默认值引号前后的空格都会被忽略。例如${ g:username , 'Default_User_Name' }表示如果访问身份是IAM用户，则替换成g:UserName的值，否则替换成文本串Default_User_Name。
对于策略变量中具有特殊含义的字符"$"（策略变量标识符），如果您不想让这个字符表示特殊含义，请将它们改写为${$}；在策略变量默认值中，如果您想表达一个单引号字符（'），请使用一对连续的单引号（''）来表示。例如${g:UserName, 'A single quote is '', two quotes are ''''.'}，当使用默认值进行替换时，它将被替换成A single quote is ', two quotes are ''.
IAM只会进行一轮替换，这意味着即使替换完毕后包含新的策略变量结构，它仍然不会被替换。例如${g:UserName, '${g:UserName}'}，当使用默认值进行替换时，它将被替换成${g:UserName}，不会继续迭代。
#### 策略变量替换失败场景说明
在以下场景下将会出现策略变量替换失败的情况：
- 变量在上下文中不存在，替换失败，例如非IAM用户登录时："${g:UserName}"。
- 变量标识符不匹配，替换失败，例如："${foo"、"${foo, 'default'"。
- 变量中默认值标识符不匹配，替换失败，例如："${key, value}"、 "${foo, 'default}"、"${foo, 'default''}"等。
- 变量为空，替换失败，例如"${}"、"${ }"、"${ }"等。
- 变量不允许存在空格，如果变量中存在空格，替换失败，例如："${g:user id}"等。
- 变量嵌套，替换失败，例如：${var1${var2}}。
 
#### 策略变量使用示例
- **在资源中使用变量** **：**
  - 该示例表示，如果以IAM用户身份登录，且IAM用户名是test_user_name的情况下（g:UserName获取到的值是test_user_name）对资源OBS:\*:\*:bucket:test_user_name（"\*"代表通配表示任意多个字符）执行obs:bucket:CreateBucket的行为结果是Allow。
    ```
    {
    "Version": "1.1",
    "Statement": [{
    "Effect": "Allow",
    "Action": [
    "obs:bucket:CreateBucket"
    ],
    "Resource": [
    "OBS:*:*:bucket:${g:UserName}"
    ]
    }]
    }
    ```
    
  
  - 该示例表示，以IAM用户身份登录，且IAM用户名是test_user_name的情况下（g:UserName获取到的值是test_user_name）对资源OBS:\*:\*:bucket:prefix_test_user_name_suffix（"\*"代表通配表示任意多个字符）执行obs:bucket:CreateBucket的行为结果是Allow。
    ```
    {
    "Version": "1.1",
    "Statement": [{
    "Effect": "Allow",
    "Action": [
    "obs:bucket:CreateBucket"
    ],
    "Resource": [
    "OBS:*:*:bucket:prefix_${g:UserName}_suffix"
    ]
    }]
    }
    ```
    
   
- **在条件值中使用变量：**
  该示例表示，以IAM用户身份登录，且IAM用户名是test_user_name的情况下（g:UserName获取到的值是test_user_name）执行iam:agencies:getAgency的行为结果是Allow。
  ```
  {
  "Version": "1.1",
  "Statement": [{
  "Effect": "Allow",
  "Action": [
  "iam:agencies:getAgency"
  ],
  "Condition": {
  "StringEquals": {
  "g:UserName": [
  "${g:UserName}"
  ]
  }
  }
  }]
  }
  ```
  
 
