权限检查,
如需控制到请求method (GET、POST等),即同一个URL,对应多个method。
需要控制台的scope与资源服务器的 method 相关联。(在资源服务器端配置)
同一个资源服务器内,resource的名称是不允许重复的。
同一个资源服务器内,resource的URI是允许重复的。
资源服务器path配置,当name 与 path 一起使用时,策略执行器会忽略资源的URI属性并使用您配置的路径。
如果指定了path,未指定name,则adapter将去keycloak服务器查询resource的URI的值与该path值相同的resource。
只指定name,不指定path,会报500空指针异常。
如果在资源服务器中配置了path,需确保能在keycloak中,该资源服务器的resource中找到匹配(精确匹配,如果name不为空,会根据name匹配,如果name为空,才会根据uri匹配)的resource,否则会抛异常:
Could not find matching resource on server with uri [/hello] or name [null]. Make sure you have created a resource on the server that matches with the path configuration.
如果资源服务器启用了path的配置,则所有的请求都会首先去配置中查找对应的resource,如果查找不到则报403.
即:path要么全配置,要么全不配置。
资源服务器path配置作用:建立scope与Method的映射。
所有的权限最后的落脚都是resource或者 resource下的scope。
如果一个用户不拥有一个资源服务器的任何资源,那么使用该用户的accessToken请求该资源服务器的RPT时会响应状态码403
如果使用accessToken访问一个资源服务器的资源时,资源服务器会首先拿着该accessToken去keycloak换取RPT(需保证资源服务器与keycloak网络是通的,换取RPT采用UMA还是Entitlement,取决于资源服务器的配置user-managed-access),然后再进行权限检查。
如果直接使用RPT访问一个资源服务器的资源,资源服务可以直接根据RPT中的权限信息进行鉴权,不需要再去keycloak查询,但是也需要资源服务器与keycloak的网络通畅,因为首次访问资源服务器时,资源服务器会拉取uma配置信息。
用户有权限时,获取的RPT,当用户没权限了,如果该RPT还没过期,仍然可以凭借该RPT调用资源服务器接口。
使用accessToken调用资源服务器接口时,不存在该问题,因为每次请求过来后,都会用accessToken换取新RPT。
请求资源服务器的某个URL时,如果与该URL匹配的resource有多个,则优先匹配精确度最高的(优先精确匹配),匹配成功后,如果当前用户对精确匹配的resource没有权限(即使对模糊匹配的URL有权限),那么结果仍然没权限。
关于Entitlement GET方式获取RPT:
启用授权服务后,每个Resource Server至少需要定义一个resource,
并且accesstoken所代表的用户(至少拥有resource关联的一个scope的权限)或者(拥有resource的权限),
否则拿accesstoken换取RPT时,会报403.
已知有:resource vm,scope get,
User01拥有scope-get的权限,如果resource-vm关联了该scope-get,并且vm-get未指定permissions,则user01拥有vm-get的权限;
如果该vm-get定义了permission,并且该permission关联的策略不包含user01,则user01不再拥有vm-get的权限。
即:
一个resource或者scope,如果同时关联多个permission,当用户访问该resource或者scope时,需要该resource或scope关联的所有permission都验证通过,该用户才能有权访问。(对比Java servlet filter chain 理解)
Resource vm 拥有3个scope,get、delete、create
并且为get单独定义了permission,并在资源服务器的配置文件中配置了vm-get与GET的关联
User02 拥有resource vm的权限,
User01拥有 resource vm的权限 和 vm-get的权限
那么user01 能够访问get-vm、delete-vm、create-vm
User02只能访问delete-vm和create-vm
在上述场景基础上,如果vm-get在资源服务器配置文件中未进行配置,则
user01 和user02 都能够访问get-vm、delete-vm、create-vm
如果为resource 和 resource下的scope分别定义了permission,
并且,用户仅仅拥有resource下的scope的permission权限,不拥有resource的permission权限,
那么,用户请求resource下的该scope时,仍然会报403。
有resource default,该resource未关联任何scope,
有用户user01,拥有resource default的permission权限,
那么使用user01的accesstoken换取的RPT将包含如下内容:
"authorization": {
"permissions": [
{
"resource_set_id": "29dc7dcf-9b51-49de-9b59-8a94fdbe7783",
"resource_set_name": "default"
}
]
}
基于以上场景,为resource default 关联两个scope:get和delete,
那么使用user01的accesstoken换取的RPT将包含如下内容:
"authorization": {
"permissions": [
{
"scopes": [
"urn:iot-hub:vm:delete",
"urn:iot-hub:vm:get"
],
"resource_set_id": "29dc7dcf-9b51-49de-9b59-8a94fdbe7783",
"resource_set_name": "default"
}
]
}