@lambeta
2017-03-09T07:40:11.000000Z
字数 10595
阅读 505
blog
https://releases.openstack.org/
https://developer.openstack.org/api-guide/quick-start/
https://developer.openstack.org/api-ref/identity/v3/
https://docs.openstack.org/security-guide/identity/policies.html
curl -k -i -H "Content-Type: application/json" -d '{ "auth": {"identity": {"methods": ["password"],"password": {"user": {"name": "admin","domain": { "name": "Default" },"password": "secret"}}},"scope": {"project": {"name": "admin","domain": { "name": "Default" }}}}}' https://localhost:5000/v3/auth/tokens->HTTP/2 201server: nginx/1.11.6date: Mon, 27 Feb 2017 06:30:58 GMTcontent-type: application/jsoncontent-length: 1006x-subject-token: c8d4845f8e46483b80704b9605368339 # token herevary: X-Auth-Tokenx-openstack-request-id: req-3b7f6de4-f8ea-4322-8da8-d3448d985bcfaccess-control-allow-origin: *access-control-allow-credentials: trueaccess-control-allow-methods: GET, POST, OPTIONSaccess-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-Tokenaccess-control-expose-headers: X-Subject-Token,X-Auth-Token,Content-Type{"token": {"audit_ids": ["Cwibi1HTRtWSJcG9bXFH_w"],"catalog": [{"endpoints": [{"id": "5ae2ea0e24b34e608aa709fe6b84bb38","interface": "public","region": null,"region_id": null,"url": "https://172.17.0.2:5000/v3"},{"id": "6dc04da36bf147d791988d449d1bf20a","interface": "admin","region": null,"region_id": null,"url": "https://172.17.0.2:35357/v3"},{"id": "c70fb80469a049ef9a45a79e1d9917a7","interface": "internal","region": null,"region_id": null,"url": "https://172.17.0.2:5000/v3"}],"id": "7c8cf541b6b4475baa208e1f627610e6","name": "keystone","type": "identity"}],"expires_at": "2017-02-27T07:30:58.875615Z","issued_at": "2017-02-27T06:30:58.875650Z","methods": ["password"],"project": {"domain": {"id": "default","name": "Default"},"id": "d73adc212580440d981087e5d9cb5047","name": "admin"},"roles": [{"id": "07a7ac0117dd4e18ae689e94fc300c35","name": "admin"}],"user": {"domain": {"id": "default","name": "Default"},"id": "50b7b2d339eb480986e34bc9e2359781","name": "admin"}}}# unscoped tokencurl -k -i -H "Content-Type: application/json" -d '{ "auth": {"identity": {"methods": ["password"],"password": {"user": {"name": "admin","domain": { "name": "Default" },"password": "secret"}}}}}' https://localhost:5000/v3/auth/tokens->{"token": {"audit_ids": ["c8n9Wn8wThKYqsL0L-XbKQ"],"expires_at": "2017-02-28T05:06:25.908083Z","issued_at": "2017-02-28T04:06:25.908108Z","methods": ["password"],"user": {"domain": {"id": "default","name": "Default"},"id": "50b7b2d339eb480986e34bc9e2359781","name": "admin"}}}
什么是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
curl -k -i -H "Content-Type: application/json" -d '{ "auth": {"identity": {"methods": ["token"],"token": {"id": "'$OS_TOKEN'"}},"scope": {"project": {"name": "admin","domain": { "name": "Default" }}}}}' https://localhost:5000/v3/auth/tokens
# 先从返回header中获取token,然后设置OS_TOKENcurl -k -s -H "X-Auth-Token: $OS_TOKEN" \https://localhost:5000/v3/users | python -mjson.tool->{"links": {"next": null,"previous": null,"self": "https://localhost:5000/v3/users"},"users": [{"domain_id": "default","enabled": true,"id": "50b7b2d339eb480986e34bc9e2359781","links": {"self": "https://localhost:5000/v3/users/50b7b2d339eb480986e34bc9e2359781"},"name": "admin"}]}
curl -k -s \-H "X-Auth-Token: $OS_TOKEN" \-H "Content-Type: application/json" \-d '{"user": {"name": "lambeta", "password": "changeme"}}' \https://localhost:5000/v3/users | python -mjson.tool->{"user": {"domain_id": "default","enabled": true,"id": "624082e8dc4044268a5232ebeb5260ff","links": {"self": "https://localhost:5000/v3/users/624082e8dc4044268a5232ebeb5260ff"},"name": "lambeta"}}
curl -k -s \-H "X-Auth-Token: $OS_TOKEN" \https://localhost:5000/v3/users/{user_id}->{"user": {"domain_id": "default","enabled": true,"id": "624082e8dc4044268a5232ebeb5260ff","links": {"self": "https://localhost:5000/v3/users/624082e8dc4044268a5232ebeb5260ff"},"name": "lambeta"}}
curl -k -s -X PATCH \-H "X-Auth-Token: $OS_TOKEN" \-H "Content-Type: application/json" \-d '{"user": {"default_project_id": "a4e03469459b4750bd316a3117e4e475","enabled": true}}' \https://localhost:5000/v3/users/624082e8dc4044268a5232ebeb5260ff->{"user": {"default_project_id": "a4e03469459b4750bd316a3117e4e475","domain_id": "default","enabled": true,"extra": {},"id": "624082e8dc4044268a5232ebeb5260ff","links": {"self": "https://localhost:5000/v3/users/624082e8dc4044268a5232ebeb5260ff"},"name": "lambeta"}}
curl -k -s \-H "X-Auth-Token: $OS_TOKEN" \https://localhost:5000/v3/projects | python -mjson.tool->{"links": {"next": null,"previous": null,"self": "https://localhost:5000/v3/projects"},"projects": [{"description": "Service Project","domain_id": "default","enabled": true,"id": "a4e03469459b4750bd316a3117e4e475","is_domain": false,"links": {"self": "https://localhost:5000/v3/projects/a4e03469459b4750bd316a3117e4e475"},"name": "service","parent_id": "default"},{"description": "Bootstrap project for initializing the cloud.","domain_id": "default","enabled": true,"id": "d73adc212580440d981087e5d9cb5047","is_domain": false,"links": {"self": "https://localhost:5000/v3/projects/d73adc212580440d981087e5d9cb5047"},"name": "admin","parent_id": "default"}]}
curl -k -s -H "X-Auth-Token: $TOKEN" \https://localhost:5000/v3/users/{user_id}/projects->{"links": {"next": null,"previous": null,"self": "https://localhost:35357/v3/users/624082e8dc4044268a5232ebeb5260ff/projects"},"projects": [{"description": "Service Project","domain_id": "default","enabled": true,"id": "a4e03469459b4750bd316a3117e4e475","is_domain": false,"links": {"self": "https://localhost:35357/v3/projects/a4e03469459b4750bd316a3117e4e475"},"name": "service","parent_id": "default"}]}
curl -k -s -H "X-Auth-Token: $OS_TOKEN" \https://localhost:5000/v3/groups | python -mjson.tool{"groups": [],"links": {"next": null,"previous": null,"self": "https://localhost:5000/v3/groups"}}
curl -k -s -H "X-Auth-Token: $OS_TOKEN" \https://localhost:5000/v3/users/{user_id}/groups->{"groups": [],"links": {"next": null,"previous": null,"self": "https://localhost:5000/v3/users/624082e8dc4044268a5232ebeb5260ff/groups"}}
curl -k -s -H "X-Auth-Token: $OS_TOKEN" \https://localhost:5000/v3/roles | python -mjson.tool->{"links": {"next": null,"previous": null,"self": "https://localhost:5000/v3/roles"},"roles": [{"domain_id": null,"id": "07a7ac0117dd4e18ae689e94fc300c35","links": {"self": "https://localhost:5000/v3/roles/07a7ac0117dd4e18ae689e94fc300c35"},"name": "admin"},{"domain_id": null,"id": "fa82d48b40794b21a1d71a96e0c89309","links": {"self": "https://localhost:5000/v3/roles/fa82d48b40794b21a1d71a96e0c89309"},"name": "user"}]}
注意,这里的role和domain没有关联!
curl -k -s -X POST -H "X-Auth-Token: $OS_TOKEN" \-H "Content-Type: application/json" \ #需要带json类型的头-d '{"role": {"name": "developer"}}' \https://localhost:5000/v3/roles->{"role": {"domain_id": null,"id": "1fa6114345e94379b7fe274ee04a234e","links": {"self":"https://localhost:5000/v3/roles/1fa6114345e94379b7fe274ee04a234e"},"name": "developer"}}
curl -k -s -X PUT -H "X-Auth-Token: $OS_TOKEN" \-H "Content-Type: application/json" \https://locahost:5000/v3/projects/{project_id}/users/{user_id}/roles/{role_id}
curl -k -s -H "X-Auth-Token: $OS_TOKEN" \-H "Content-Type: application/json" -d '{ "domain": { "name": "acme"}}'https://localhost:5000/v3/domains | python -mjson.tool
curl -k -s -H "X-Auth-Token: $OS_TOKEN" \-H "Content-Type: application/json" \-d '{"policy": {"blob": "{'foobar_user': 'role:developer'}","type": "application/json"}}' \https://localhost:5000/v3/policies->{"policy": {"blob": "{foobar_user: role:developer}","id": "6159494901ff4706ac877eff50530463","links": {"self": "https://localhost:5000/v3/policies/6159494901ff4706ac877eff50530463"},"type": "application/json"}}
curl -k -s -H "X-Auth-Token: $OS_TOKEN" https://localhost:5000/v3/policies
控制API的访问和授权,所以Keystone创建了RBAC (Role-Based Access Control) 的策略来管控每个开放的API。
# /usr/share/defaults/keystone/policy.json"admin_required": "role:admin or is_admin:1""identity:list_grants": "rule:admin_required""identity:create_trust": "user_id:%(trust.trustor_user_id)s",->| service:API: [rule | 'rule':alias]| target: rule
以"identity:list_grants": "rule:admin_required"为例:
| Policy Target | API |
|---|---|
| identity:list_grants | GET /v3/projects/{project_id}/users/{user_id}/roles |
curl -k -i -H "Content-Type: application/json" -d '{ "auth": {"identity": {"methods": ["password"],"password": {"user": {"name": "lambeta","domain": { "name": "Default" },"password": "changeme"}}},"scope": {"project": {"name": "service","domain": { "name": "Default" }}}}}' https://localhost:5000/v3/auth/tokens# 获取token
curl -k -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" https://localhost:35357/v3/projects/a4e03469459b4750bd316a3117e4e475/users/624082e8dc4044268a5232ebeb5260ff/roles |json->{"error": {"code": 403,"message": "You are not authorized to perform the requested action: identity:list_grants","title": "Forbidden"}}
curl -k -H"X-Auth-Token:$TOKEN" -H "Content-type: application/json" https://localhost:35357/v3/users/624082e8dc4044268a5232ebeb5260ff/projects |json->{"links": {"next": null,"previous": null,"self": "https://localhost:35357/v3/users/624082e8dc4044268a5232ebeb5260ff/projects"},"projects": [{"description": "Service Project","domain_id": "default","enabled": true,"id": "a4e03469459b4750bd316a3117e4e475","is_domain": false,"links": {"self": "https://localhost:35357/v3/projects/a4e03469459b4750bd316a3117e4e475"},"name": "service","parent_id": "default"}]}
当前用户已经是lambeta,但是依然可以操作这个API,是因为存在这样几条policy:
"owner" : "user_id:%(user_id)s","admin_or_owner": "rule:admin_required or rule:owner","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