我正在尝试使用 Keycloak AuthzClient 在资源服务器中注册资源和相关权限。
我有一个启用了 authz 服务的资源服务器“resourceserver”。
使用 AuthzClient,使用包含资源服务器的客户端 ID 和机密的 json 文件进行初始化,我可以获得一个 pat。
...
authzClient.obtainAccessToken().getToken();
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("myresource");
resource.setUris(new HashSet<>(Collections.singletonList("urn:resourceserver:resourcetype1:myresource")));
resource.setOwnerManagedAccess(true);
resource.setType("urn:resourceserver:resourcetype1");
resource.addScope("read", "write");
resource = authzClient.protection(pat).resource().create(resource);
UmaPermissionRepresentation permissionRepresentation = new UmaPermissionRepresentation();
permissionRepresentation.setName("myresourcepermissions");
permissionRepresentation.setDescription("foo");
permissionRepresentation.addRole("somerole");
UmaPermissionRepresentation result = authzClient.protection(pat).policy(resource.getId()).create(permissionRepresentation)
执行此代码后,我可以在 keycloak 管理 UI 中看到已创建资源和范围,但似乎没有显示策略/权限。
我相信这可能是有意的,因为这个 keycloak 管理 UI 只显示类型为客户端、角色、js 等的策略,而不是 UmaPermissionRepresentation 创建的“uma”。
authz/protection/uma-policy
但是,通过使用我的 pat查询,我可以看到 Keycloak 中存在该策略。
所以那里有东西。现在测试它。我创建了一个普通用户并为其分配了领域角色somerole
。使用这个用户和一些任意的公共客户端,我可以获得一个 RPT。
首先使用密码授权获取访问令牌:
grant_type=password&username=joe&password=password&client_id=somepublicclient
然后将其交换为 RPT:
grant_type=urn:ietf:params:oauth:grant-type:uma-ticket&audience=resourceserver
RPT 回来了,如果我查看它的内容,我可以看到授权块让我可以访问 myresource 资源。
somerole
但是,当我尝试使用服务帐户(我也授予角色)使用客户端凭据流来获取初始访问令牌的类似流程时:
grant_type=client_credentials&client_id=serviceaccount1&client_secret=77c1ffa8-0ea8-420c-ad45-e1a69a03838d
我能够获得一个 RPT,但该 RPT 在授权/权限块中不包含 myresource,只有默认资源。
我一直试图理解为什么会这样。我也尝试过在 UmaPermissionRepresentation 中使用.addClient("serviceaccount1")
or .addUser("service-account-serviceaccount1")
,但是,该策略似乎没有生效,我的服务帐户无权访问该资源。
这是使用 Keycloak 4.8.0.Final。
注意:使用 keycloak 管理客户端,我可以创建实际执行此操作的策略/权限;但在我的环境中,这会导致其他问题,因为我需要分配给管理客户端的角色(例如查看所有客户端以检索 id 等)