在网关层对用户进行接入权限管控(非后端应用的业务权限),不同的用户有访问不同api(服务)的权限,类似django admin的用户组权限功能
由于认证系统是完全可信的内部系统,简单起见使用密码授权方式
kong: https://blog.csdn.net/pushiqiang/article/details/95726137
本文使用 kong:0.14.0; 1.3.x版本后,Apis接口已经不推荐使用了,可以使用services接口
# 启动kong使用的数据库postgres/cassandra
docker run -d --name kong-database \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
postgres:9.6
# kong配置数据初始化
docker run --rm \
--link kong-database:kong-database \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
kong:0.14.0 kong migrations up
# 启动kong容器
docker run -d --name kong \
--link kong-database:kong-database \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
kong:0.14.0
服务和权限一对一关系,每一个服务或者api拥有唯一的权限名,不同的服务或api不同的权限, 通过对用户赋予不同的权限,从而限制用户访问指定的api或服务
acl白名单: 用户分组权限
ref:https://docs.konghq.com/hub/kong-inc/oauth2/
ref:https://docs.konghq.com/hub/kong-inc/acl/
用户认证服务器在Kong的内侧,我们需要通过Kong进行访问
g服务:https://api.github.com/feeds(github api接口口)
f服务:http://mockbin.com/request (http请求信息回显接口)
网关转发策略(Request path),通过请求路径管理不同服务
http://localhost:8000/g/ => https://api.github.com/feeds
http://localhost:8000/f/ => http://mockbin.com/request
curl -i -X POST \
--url http://localhost:8001/apis/ \
--data 'name=g' \
--data 'uris=/g' \
--data 'upstream_url=https://api.github.com/feeds'
curl -X POST http://localhost:8001/apis/g/plugins \
--data "name=oauth2" \
--data "config.enable_password_grant=true" \
--data "config.scopes=email,phone,address" \
--data "config.mandatory_scope=true"\
--data "config.global_credentials=true"
开启global_credentials全局凭证,否则多个api不能共用token
=>
{"created_at":1539681371000,"config":{"refresh_token_ttl":1209600,"scopes":["email","phone","address"],"mandatory_scope":true,
"provision_key":"bHR6ABHpSCAXbIIdLznfNco21WTa3Anb","hide_credentials":false,"enable_authorization_code":true,
"enable_implicit_grant":false,"global_credentials":false,"accept_http_if_already_terminated":false,
"enable_password_grant":false,"enable_client_credentials":false,"anonymous":"","token_expiration":7200,"auth_header_name":"authorization"},
"id":"5f820751-d937-4bcf-94e6-e233504e4c58","name":"oauth2","api_id":"f24c8181-bff4-4b19-8b9f-0c256a86c157","enabled":true}
记录下g服务的
provision_key: wBBr78rYxuN9jOo3VTQXrFYtG2tZLN8J
curl -X POST http://localhost:8001/apis/g/plugins \
--data "name=acl" \
--data "config.whitelist=read"
# --data "config.hide_groups_header=true"
g服务需要 read权限
curl -i -X POST \
--url http://localhost:8001/apis/ \
--data 'name=f' \
--data 'uris=/f' \
--data 'upstream_url=http://mockbin.com/request'
curl -X POST http://localhost:8001/apis/f/plugins \
--data "name=oauth2" \
--data "config.enable_password_grant=true" \
--data "config.scopes=email,phone,address" \
--data "config.mandatory_scope=true" \
--data "config.global_credentials=true"
=>
{"created_at":1539681457000,"config":{"refresh_token_ttl":1209600,"scopes":["email","phone","address"],"mandatory_scope":true,
"provision_key":"wBBr78rYxuN9jOo3VTQXrFYtG2tZLN8J","hide_credentials":false,"enable_authorization_code":true,
"enable_implicit_grant":false,"global_credentials":false,"accept_http_if_already_terminated":false,"enable_password_grant":false,
"enable_client_credentials":false,"anonymous":"","token_expiration":7200,"auth_header_name":"authorization"},
"id":"8680d0e6-3f29-41f5-a0bc-7ceff6cb4f4f","name":"oauth2","api_id":"05e03a02-770c-474d-81e7-40344fa0f469","enabled":true}
记录下f服务的
provision_key: wBBr78rYxuN9jOo3VTQXrFYtG2tZLN8J
后面获取token要用
curl -X POST http://localhost:8001/apis/f/plugins \
--data "name=acl" \
--data "config.whitelist=write"
# --data "config.hide_groups_header=true"
f服务需要 write权限
ref: https://blog.csdn.net/weixin_33836223/article/details/86849500
用户名: user123
curl -X POST http://localhost:8001/consumers/ \
--data "username=user123"
=>
{"custom_id":null,"created_at":1539681490,"username":"user123","id":"1317f755-eb65-46ea-a792-825d49869ec7"}
创建应用
curl -X POST http://localhost:8001/consumers/user123/oauth2 \
--data "name=test-app" \
--data "redirect_uri=http://test.my"
=>
{"client_id":"m0gtiqvlg8Mb08xDC2ZoQDUqHjzdjVnK","created_at":1539681543000,"id":"72910e81-3fd0-4c99-9eca-15a29ebc0ce9","redirect_uri":["http:\/\/test.my"],
"name":"test-app","client_secret":"N7R1HL9rgLdELlCJ1W6HSEEemzu0bb08","consumer_id":"1317f755-eb65-46ea-a792-825d49869ec7"}
记录下
client_id: m0gtiqvlg8Mb08xDC2ZoQDUqHjzdjVnK
client_secret: N7R1HL9rgLdELlCJ1W6HSEEemzu0bb08
curl -X POST http://localhost:8001/consumers/user123/acls \
--data "group=write"
给用户user123赋予 write权限
此时用户user123应该可以访问f服务而不能访问g服务(g: read, f:wirte)
选择任意一个服务(g/f)获取token
curl -k \
--data "client_id=m0gtiqvlg8Mb08xDC2ZoQDUqHjzdjVnK" \
--data "client_secret=N7R1HL9rgLdELlCJ1W6HSEEemzu0bb08" \
--data "provision_key=same" \
--data "scope=email" \
--data "authenticated_userid=b48bf407-c2b7-41a9-8e0f-43eead2fc60f" \
--data "grant_type=password" \
https://localhost:8443/f/oauth2/token
authenticated_userid为应用系统用户标识(比如用户id或者uuid)
=>
{"refresh_token":"pWAhNfCdJ78JN9qU1xiLCwXrOyjLqopo","token_type":"bearer","access_token":"pwA2qEQLQQmpatG4NOBE8SGB670UflH1","expires_in":7200}
访问api f
curl -i -k -X GET --url http://localhost:8000/f/?access_token=KzDR0BxQrEhQTmI2dmSphnZc5dxR6jAK
访问api g
curl -i -k -X GET --url http://localhost:8000/g/?access_token=KzDR0BxQrEhQTmI2dmSphnZc5dxR6jAK
=>
HTTP/1.1 403 Forbidden
Date: Wed, 17 Oct 2018 02:08:58 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Server: kong/0.14.1
Content-Length: 46
{"message":"You cannot consume this service"}
g服务需要 read权限
f服务需要 write权限
由于用户user123没有和read组管理,故不能访问g的api
关联user123和read组
curl -X POST http://localhost:8001/consumers/user123/acls \
--data "group=read"
再次访问api g成功
curl -i -k -X GET --url http://localhost:8000/g/?access_token=KzDR0BxQrEhQTmI2dmSphnZc5dxR6jAK
从而实现基于acl白名单方式的用户接入权限管理