[关闭]
@lambeta 2017-03-09T07:40:11.000000Z 字数 10595 阅读 505

keystone概念及其使用指南

blog


Keystone版本发布计划

https://releases.openstack.org/

V3 API

https://developer.openstack.org/api-guide/quick-start/
https://developer.openstack.org/api-ref/identity/v3/

Policy详细解释

https://docs.openstack.org/security-guide/identity/policies.html

Keystone的组成

  1. 管理身份验证(managing authentication): 验证用户身份
  2. 授权(authorization): 基于角色role的权限管理
  3. 服务目录(catalog of services): 提服务目录(ServiceCatalog:包括service和endpoint)服务,类似于UDDI服务的概念,用户(无论是Dashboard, APIClient)都需要访问Keystone获取服务列表,以及每个服务的地址(Openstack中称为Endpoint)

操作User指南

获取token,返回在header

  1. 通过password
  1. curl -k -i -H "Content-Type: application/json" -d '
  2. { "auth": {
  3. "identity": {
  4. "methods": ["password"],
  5. "password": {
  6. "user": {
  7. "name": "admin",
  8. "domain": { "name": "Default" },
  9. "password": "secret"
  10. }
  11. }
  12. },
  13. "scope": {
  14. "project": {
  15. "name": "admin",
  16. "domain": { "name": "Default" }
  17. }
  18. }
  19. }
  20. }' https://localhost:5000/v3/auth/tokens
  21. ->
  22. HTTP/2 201
  23. server: nginx/1.11.6
  24. date: Mon, 27 Feb 2017 06:30:58 GMT
  25. content-type: application/json
  26. content-length: 1006
  27. x-subject-token: c8d4845f8e46483b80704b9605368339 # token here
  28. vary: X-Auth-Token
  29. x-openstack-request-id: req-3b7f6de4-f8ea-4322-8da8-d3448d985bcf
  30. access-control-allow-origin: *
  31. access-control-allow-credentials: true
  32. access-control-allow-methods: GET, POST, OPTIONS
  33. access-control-allow-headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Subject-Token,X-Auth-Token
  34. access-control-expose-headers: X-Subject-Token,X-Auth-Token,Content-Type
  35. {
  36. "token": {
  37. "audit_ids": [
  38. "Cwibi1HTRtWSJcG9bXFH_w"
  39. ],
  40. "catalog": [
  41. {
  42. "endpoints": [
  43. {
  44. "id": "5ae2ea0e24b34e608aa709fe6b84bb38",
  45. "interface": "public",
  46. "region": null,
  47. "region_id": null,
  48. "url": "https://172.17.0.2:5000/v3"
  49. },
  50. {
  51. "id": "6dc04da36bf147d791988d449d1bf20a",
  52. "interface": "admin",
  53. "region": null,
  54. "region_id": null,
  55. "url": "https://172.17.0.2:35357/v3"
  56. },
  57. {
  58. "id": "c70fb80469a049ef9a45a79e1d9917a7",
  59. "interface": "internal",
  60. "region": null,
  61. "region_id": null,
  62. "url": "https://172.17.0.2:5000/v3"
  63. }
  64. ],
  65. "id": "7c8cf541b6b4475baa208e1f627610e6",
  66. "name": "keystone",
  67. "type": "identity"
  68. }
  69. ],
  70. "expires_at": "2017-02-27T07:30:58.875615Z",
  71. "issued_at": "2017-02-27T06:30:58.875650Z",
  72. "methods": [
  73. "password"
  74. ],
  75. "project": {
  76. "domain": {
  77. "id": "default",
  78. "name": "Default"
  79. },
  80. "id": "d73adc212580440d981087e5d9cb5047",
  81. "name": "admin"
  82. },
  83. "roles": [
  84. {
  85. "id": "07a7ac0117dd4e18ae689e94fc300c35",
  86. "name": "admin"
  87. }
  88. ],
  89. "user": {
  90. "domain": {
  91. "id": "default",
  92. "name": "Default"
  93. },
  94. "id": "50b7b2d339eb480986e34bc9e2359781",
  95. "name": "admin"
  96. }
  97. }
  98. }
  99. # unscoped token
  100. curl -k -i -H "Content-Type: application/json" -d '
  101. { "auth": {
  102. "identity": {
  103. "methods": ["password"],
  104. "password": {
  105. "user": {
  106. "name": "admin",
  107. "domain": { "name": "Default" },
  108. "password": "secret"
  109. }
  110. }
  111. }
  112. }
  113. }' https://localhost:5000/v3/auth/tokens
  114. ->
  115. {
  116. "token": {
  117. "audit_ids": [
  118. "c8n9Wn8wThKYqsL0L-XbKQ"
  119. ],
  120. "expires_at": "2017-02-28T05:06:25.908083Z",
  121. "issued_at": "2017-02-28T04:06:25.908108Z",
  122. "methods": [
  123. "password"
  124. ],
  125. "user": {
  126. "domain": {
  127. "id": "default",
  128. "name": "Default"
  129. },
  130. "id": "50b7b2d339eb480986e34bc9e2359781",
  131. "name": "admin"
  132. }
  133. }
  134. }

什么是scoped和unscoped token?

What is the difference between a scoped and unscoped token?
An unscoped token is one where the user is authenticated but not for a specific project or domain. This type of token is useful for making queries such as determining what projects a user has access to. A scoped token is created when the user is authenticated for a specific project or domain. Scoped tokens have role information associated with them and are the types of tokens used by the other OpenStack services to determine what types of operations are permitted.

unscoped token用于查询一个用户具体访问了什么项目;而scoped token用于其他的OpenStack服务鉴别哪些类型的操作是被允许的。

2. 通过token

  1. curl -k -i -H "Content-Type: application/json" -d '
  2. { "auth": {
  3. "identity": {
  4. "methods": [
  5. "token"
  6. ],
  7. "token": {
  8. "id": "'$OS_TOKEN'"
  9. }
  10. },
  11. "scope": {
  12. "project": {
  13. "name": "admin",
  14. "domain": { "name": "Default" }
  15. }
  16. }
  17. }
  18. }' https://localhost:5000/v3/auth/tokens

列出所有user

  1. # 先从返回header中获取token,然后设置OS_TOKEN
  2. curl -k -s -H "X-Auth-Token: $OS_TOKEN" \
  3. https://localhost:5000/v3/users | python -mjson.tool
  4. ->
  5. {
  6. "links": {
  7. "next": null,
  8. "previous": null,
  9. "self": "https://localhost:5000/v3/users"
  10. },
  11. "users": [
  12. {
  13. "domain_id": "default",
  14. "enabled": true,
  15. "id": "50b7b2d339eb480986e34bc9e2359781",
  16. "links": {
  17. "self": "https://localhost:5000/v3/users/50b7b2d339eb480986e34bc9e2359781"
  18. },
  19. "name": "admin"
  20. }
  21. ]
  22. }

创建user

  1. curl -k -s \
  2. -H "X-Auth-Token: $OS_TOKEN" \
  3. -H "Content-Type: application/json" \
  4. -d '{"user": {"name": "lambeta", "password": "changeme"}}' \
  5. https://localhost:5000/v3/users | python -mjson.tool
  6. ->
  7. {
  8. "user": {
  9. "domain_id": "default",
  10. "enabled": true,
  11. "id": "624082e8dc4044268a5232ebeb5260ff",
  12. "links": {
  13. "self": "https://localhost:5000/v3/users/624082e8dc4044268a5232ebeb5260ff"
  14. },
  15. "name": "lambeta"
  16. }
  17. }

查看user详情

  1. curl -k -s \
  2. -H "X-Auth-Token: $OS_TOKEN" \
  3. https://localhost:5000/v3/users/{user_id}
  4. ->
  5. {
  6. "user": {
  7. "domain_id": "default",
  8. "enabled": true,
  9. "id": "624082e8dc4044268a5232ebeb5260ff",
  10. "links": {
  11. "self": "https://localhost:5000/v3/users/624082e8dc4044268a5232ebeb5260ff"
  12. },
  13. "name": "lambeta"
  14. }
  15. }

把user添加到group

  1. curl -k -s -X PATCH \
  2. -H "X-Auth-Token: $OS_TOKEN" \
  3. -H "Content-Type: application/json" \
  4. -d '{
  5. "user": {
  6. "default_project_id": "a4e03469459b4750bd316a3117e4e475",
  7. "enabled": true
  8. }
  9. }' \
  10. https://localhost:5000/v3/users/624082e8dc4044268a5232ebeb5260ff
  11. ->
  12. {
  13. "user": {
  14. "default_project_id": "a4e03469459b4750bd316a3117e4e475",
  15. "domain_id": "default",
  16. "enabled": true,
  17. "extra": {},
  18. "id": "624082e8dc4044268a5232ebeb5260ff",
  19. "links": {
  20. "self": "https://localhost:5000/v3/users/624082e8dc4044268a5232ebeb5260ff"
  21. },
  22. "name": "lambeta"
  23. }
  24. }

操作Project指南

列出Project

  1. curl -k -s \
  2. -H "X-Auth-Token: $OS_TOKEN" \
  3. https://localhost:5000/v3/projects | python -mjson.tool
  4. ->
  5. {
  6. "links": {
  7. "next": null,
  8. "previous": null,
  9. "self": "https://localhost:5000/v3/projects"
  10. },
  11. "projects": [
  12. {
  13. "description": "Service Project",
  14. "domain_id": "default",
  15. "enabled": true,
  16. "id": "a4e03469459b4750bd316a3117e4e475",
  17. "is_domain": false,
  18. "links": {
  19. "self": "https://localhost:5000/v3/projects/a4e03469459b4750bd316a3117e4e475"
  20. },
  21. "name": "service",
  22. "parent_id": "default"
  23. },
  24. {
  25. "description": "Bootstrap project for initializing the cloud.",
  26. "domain_id": "default",
  27. "enabled": true,
  28. "id": "d73adc212580440d981087e5d9cb5047",
  29. "is_domain": false,
  30. "links": {
  31. "self": "https://localhost:5000/v3/projects/d73adc212580440d981087e5d9cb5047"
  32. },
  33. "name": "admin",
  34. "parent_id": "default"
  35. }
  36. ]
  37. }

列出User所属的所有Project

  1. curl -k -s -H "X-Auth-Token: $TOKEN" \
  2. https://localhost:5000/v3/users/{user_id}/projects
  3. ->
  4. {
  5. "links": {
  6. "next": null,
  7. "previous": null,
  8. "self": "https://localhost:35357/v3/users/624082e8dc4044268a5232ebeb5260ff/projects"
  9. },
  10. "projects": [
  11. {
  12. "description": "Service Project",
  13. "domain_id": "default",
  14. "enabled": true,
  15. "id": "a4e03469459b4750bd316a3117e4e475",
  16. "is_domain": false,
  17. "links": {
  18. "self": "https://localhost:35357/v3/projects/a4e03469459b4750bd316a3117e4e475"
  19. },
  20. "name": "service",
  21. "parent_id": "default"
  22. }
  23. ]
  24. }

操作Group指南

列出所有group

  1. curl -k -s -H "X-Auth-Token: $OS_TOKEN" \
  2. https://localhost:5000/v3/groups | python -mjson.tool
  3. {
  4. "groups": [],
  5. "links": {
  6. "next": null,
  7. "previous": null,
  8. "self": "https://localhost:5000/v3/groups"
  9. }
  10. }

列出user所属的所有group

  1. curl -k -s -H "X-Auth-Token: $OS_TOKEN" \
  2. https://localhost:5000/v3/users/{user_id}/groups
  3. ->
  4. {
  5. "groups": [],
  6. "links": {
  7. "next": null,
  8. "previous": null,
  9. "self": "https://localhost:5000/v3/users/624082e8dc4044268a5232ebeb5260ff/groups"
  10. }
  11. }

操作Role指南

列出所有角色

  1. curl -k -s -H "X-Auth-Token: $OS_TOKEN" \
  2. https://localhost:5000/v3/roles | python -mjson.tool
  3. ->
  4. {
  5. "links": {
  6. "next": null,
  7. "previous": null,
  8. "self": "https://localhost:5000/v3/roles"
  9. },
  10. "roles": [
  11. {
  12. "domain_id": null,
  13. "id": "07a7ac0117dd4e18ae689e94fc300c35",
  14. "links": {
  15. "self": "https://localhost:5000/v3/roles/07a7ac0117dd4e18ae689e94fc300c35"
  16. },
  17. "name": "admin"
  18. },
  19. {
  20. "domain_id": null,
  21. "id": "fa82d48b40794b21a1d71a96e0c89309",
  22. "links": {
  23. "self": "https://localhost:5000/v3/roles/fa82d48b40794b21a1d71a96e0c89309"
  24. },
  25. "name": "user"
  26. }
  27. ]
  28. }

注意,这里的role和domain没有关联!

创建一个新角色

  1. curl -k -s -X POST -H "X-Auth-Token: $OS_TOKEN" \
  2. -H "Content-Type: application/json" \ #需要带json类型的头
  3. -d '{"role": {"name": "developer"}}' \
  4. https://localhost:5000/v3/roles
  5. ->
  6. {"role": {"domain_id": null,
  7. "id": "1fa6114345e94379b7fe274ee04a234e",
  8. "links": {"self":"https://localhost:5000/v3/roles/1fa6114345e94379b7fe274ee04a234e"},
  9. "name": "developer"
  10. }
  11. }

把角色赋给Project下的某个User

  1. curl -k -s -X PUT -H "X-Auth-Token: $OS_TOKEN" \
  2. -H "Content-Type: application/json" \
  3. https://locahost:5000/v3/projects/{project_id}/users/{user_id}/roles/{role_id}

操作Domain指南

创建一个Domain

  1. curl -k -s -H "X-Auth-Token: $OS_TOKEN" \
  2. -H "Content-Type: application/json" -d '{ "domain": { "name": "acme"}}'
  3. https://localhost:5000/v3/domains | python -mjson.tool

操作Policy指南

创建Policy

  1. curl -k -s -H "X-Auth-Token: $OS_TOKEN" \
  2. -H "Content-Type: application/json" \
  3. -d '{
  4. "policy": {
  5. "blob": "{'foobar_user': 'role:developer'}",
  6. "type": "application/json"
  7. }
  8. }' \
  9. https://localhost:5000/v3/policies
  10. ->
  11. {
  12. "policy": {
  13. "blob": "{foobar_user: role:developer}",
  14. "id": "6159494901ff4706ac877eff50530463",
  15. "links": {
  16. "self": "https://localhost:5000/v3/policies/6159494901ff4706ac877eff50530463"
  17. },
  18. "type": "application/json"
  19. }
  20. }

列出所有Policy

  1. curl -k -s -H "X-Auth-Token: $OS_TOKEN" https://localhost:5000/v3/policies

Policy详解

目的

控制API的访问和授权,所以Keystone创建了RBAC (Role-Based Access Control) 的策略来管控每个开放的API。

模样

  1. # /usr/share/defaults/keystone/policy.json
  2. "admin_required": "role:admin or is_admin:1"
  3. "identity:list_grants": "rule:admin_required"
  4. "identity:create_trust": "user_id:%(trust.trustor_user_id)s",
  5. ->
  6. | service:API: [rule | 'rule':alias]
  7. | target: rule

分析service:API: rule

"identity:list_grants": "rule:admin_required"为例:

Policy Target API
identity:list_grants GET /v3/projects/{project_id}/users/{user_id}/roles

修改Policy

切换用户

  1. curl -k -i -H "Content-Type: application/json" -d '
  2. { "auth": {
  3. "identity": {
  4. "methods": ["password"],
  5. "password": {
  6. "user": {
  7. "name": "lambeta",
  8. "domain": { "name": "Default" },
  9. "password": "changeme"
  10. }
  11. }
  12. },
  13. "scope": {
  14. "project": {
  15. "name": "service",
  16. "domain": { "name": "Default" }
  17. }
  18. }
  19. }
  20. }' https://localhost:5000/v3/auth/tokens
  21. # 获取token

列出project下指定user的所有roles (list_grants)

  1. curl -k -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" https://localhost:35357/v3/projects/a4e03469459b4750bd316a3117e4e475/users/624082e8dc4044268a5232ebeb5260ff/roles |json
  2. ->
  3. {
  4. "error": {
  5. "code": 403,
  6. "message": "You are not authorized to perform the requested action: identity:list_grants",
  7. "title": "Forbidden"
  8. }
  9. }

列出user下的所有project (list_user_projects)

  1. curl -k -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" https://localhost:35357/v3/users/624082e8dc4044268a5232ebeb5260ff/projects |json
  2. ->
  3. {
  4. "links": {
  5. "next": null,
  6. "previous": null,
  7. "self": "https://localhost:35357/v3/users/624082e8dc4044268a5232ebeb5260ff/projects"
  8. },
  9. "projects": [
  10. {
  11. "description": "Service Project",
  12. "domain_id": "default",
  13. "enabled": true,
  14. "id": "a4e03469459b4750bd316a3117e4e475",
  15. "is_domain": false,
  16. "links": {
  17. "self": "https://localhost:35357/v3/projects/a4e03469459b4750bd316a3117e4e475"
  18. },
  19. "name": "service",
  20. "parent_id": "default"
  21. }
  22. ]
  23. }

当前用户已经是lambeta,但是依然可以操作这个API,是因为存在这样几条policy:

  1. "owner" : "user_id:%(user_id)s",
  2. "admin_or_owner": "rule:admin_required or rule:owner",
  3. "identity:list_user_projects": "rule:admin_or_owner"
Policy Target API
identity:list_user_projects GET /v3/users/{user_id}/projects

[1] Policy Enforcement in OpenStack
[2] jq

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注