Keycloak springboot 适配器不允许设置 keycloak.policy-enforcer-config.user-managed-access 属性
Keycloak springboot adapter does not allowed to set keycloak.policy-enforcer-config.user-managed-access property
我尝试使用 springboot 适配器保护我的应用程序。在深入研究源代码之后,我发现一些似乎是实现中的错误。
在 KeycloakAdapterPolicyEnforcer class 中,检索用户权限的方法 getPermissionTicket 包含:
private String getPermissionTicket(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, AuthzClient authzClient, OIDCHttpFacade httpFacade) {
if (getEnforcerConfig().getUserManagedAccess() != null) {
ProtectionResource protection = authzClient.protection();
PermissionResource permission = protection.permission();
PermissionRequest permissionRequest = new PermissionRequest();
permissionRequest.setResourceId(pathConfig.getId());
permissionRequest.setScopes(new HashSet<>(methodConfig.getScopes()));
Map<String, List<String>> claims = resolveClaims(pathConfig, httpFacade);
if (!claims.isEmpty()) {
permissionRequest.setClaims(claims);
}
return permission.create(permissionRequest).getTicket();
}
return null;
}
如果您没有在 application.properties 中定义 keycloak.policy-enforcer-config.user-managed-access 属性,getEnforcerConfig().getUserManagedAccess() != null
始终为 null。 =17=]
但我无法定义它,因为 PolicyEnforcerConfig
class 将字段 userManagedAccess 定义为 UserManagedAccessConfig 对象
@JsonProperty("user-managed-access")
@JsonInclude(JsonInclude.Include.NON_NULL)
private UserManagedAccessConfig userManagedAccess;
但未提供任何 jackson 转换器以从 String 传递到 UserManagedAccessConfig
如果不设置此配置 属性,适配器只会拒绝每个请求。此问题有任何解决方法吗?
是的,我只是使用一个 bean 而不是 属性 文件。像这样:
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
@EnableTransactionManagement
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
@Primary
public KeycloakSpringBootProperties properties() {
final KeycloakSpringBootProperties props = new KeycloakSpringBootProperties();
final PolicyEnforcerConfig policyEnforcerConfig = new PolicyEnforcerConfig();
policyEnforcerConfig.setEnforcementMode(EnforcementMode.ENFORCING);
policyEnforcerConfig.setUserManagedAccess(new UserManagedAccessConfig());
props.setPolicyEnforcerConfig(policyEnforcerConfig);
return props;
}
}
@scandinave 的回答不支持在应用程序属性中定义的 keycloak.policy-enforcer-config.*
属性。根据 discussion 中的建议,有如下 'dirty' 解决方法,它可以保留策略执行器配置属性并仅添加 UserManagedAccessConfig 对象。
public class KeycloakUMAConfigResolver extends KeycloakSpringBootConfigResolver {
public KeycloakUMAConfigResolver() throws Exception {
}
public void configureUMAConfig() {
try {
Field f = KeycloakSpringBootConfigResolver.class.getDeclaredField("adapterConfig");
f.setAccessible(true);
KeycloakSpringBootProperties properties = (KeycloakSpringBootProperties) f.get(this);
properties.getPolicyEnforcerConfig()
.setUserManagedAccess(new PolicyEnforcerConfig.UserManagedAccessConfig());
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
然后在安全配置中创建这个配置解析器 bean。
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() throws Exception {
return new KeycloakUMAConfigResolver();
}
@Bean
@Qualifier("dummy bean")
public Object dummyBeam(KeycloakUMAConfigResolver configResolver) {
configResolver.configureUMAConfig();
return new Object();
}
注意:尝试在构造函数中设置 UserManagedAccessConfig 失败,因为在构造函数中对象初始化期间 adapterConfig 字段不可用。因此使用了一个虚拟 bean 定义,然后调用了 configureUMAConfig
方法。
我尝试使用 springboot 适配器保护我的应用程序。在深入研究源代码之后,我发现一些似乎是实现中的错误。
在 KeycloakAdapterPolicyEnforcer class 中,检索用户权限的方法 getPermissionTicket 包含:
private String getPermissionTicket(PathConfig pathConfig, PolicyEnforcerConfig.MethodConfig methodConfig, AuthzClient authzClient, OIDCHttpFacade httpFacade) {
if (getEnforcerConfig().getUserManagedAccess() != null) {
ProtectionResource protection = authzClient.protection();
PermissionResource permission = protection.permission();
PermissionRequest permissionRequest = new PermissionRequest();
permissionRequest.setResourceId(pathConfig.getId());
permissionRequest.setScopes(new HashSet<>(methodConfig.getScopes()));
Map<String, List<String>> claims = resolveClaims(pathConfig, httpFacade);
if (!claims.isEmpty()) {
permissionRequest.setClaims(claims);
}
return permission.create(permissionRequest).getTicket();
}
return null;
}
如果您没有在 application.properties 中定义 keycloak.policy-enforcer-config.user-managed-access 属性,getEnforcerConfig().getUserManagedAccess() != null
始终为 null。 =17=]
但我无法定义它,因为 PolicyEnforcerConfig
class 将字段 userManagedAccess 定义为 UserManagedAccessConfig 对象
@JsonProperty("user-managed-access")
@JsonInclude(JsonInclude.Include.NON_NULL)
private UserManagedAccessConfig userManagedAccess;
但未提供任何 jackson 转换器以从 String 传递到 UserManagedAccessConfig
如果不设置此配置 属性,适配器只会拒绝每个请求。此问题有任何解决方法吗?
是的,我只是使用一个 bean 而不是 属性 文件。像这样:
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
@EnableTransactionManagement
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
@Primary
public KeycloakSpringBootProperties properties() {
final KeycloakSpringBootProperties props = new KeycloakSpringBootProperties();
final PolicyEnforcerConfig policyEnforcerConfig = new PolicyEnforcerConfig();
policyEnforcerConfig.setEnforcementMode(EnforcementMode.ENFORCING);
policyEnforcerConfig.setUserManagedAccess(new UserManagedAccessConfig());
props.setPolicyEnforcerConfig(policyEnforcerConfig);
return props;
}
}
@scandinave 的回答不支持在应用程序属性中定义的 keycloak.policy-enforcer-config.*
属性。根据 discussion 中的建议,有如下 'dirty' 解决方法,它可以保留策略执行器配置属性并仅添加 UserManagedAccessConfig 对象。
public class KeycloakUMAConfigResolver extends KeycloakSpringBootConfigResolver {
public KeycloakUMAConfigResolver() throws Exception {
}
public void configureUMAConfig() {
try {
Field f = KeycloakSpringBootConfigResolver.class.getDeclaredField("adapterConfig");
f.setAccessible(true);
KeycloakSpringBootProperties properties = (KeycloakSpringBootProperties) f.get(this);
properties.getPolicyEnforcerConfig()
.setUserManagedAccess(new PolicyEnforcerConfig.UserManagedAccessConfig());
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
然后在安全配置中创建这个配置解析器 bean。
@Bean
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() throws Exception {
return new KeycloakUMAConfigResolver();
}
@Bean
@Qualifier("dummy bean")
public Object dummyBeam(KeycloakUMAConfigResolver configResolver) {
configResolver.configureUMAConfig();
return new Object();
}
注意:尝试在构造函数中设置 UserManagedAccessConfig 失败,因为在构造函数中对象初始化期间 adapterConfig 字段不可用。因此使用了一个虚拟 bean 定义,然后调用了 configureUMAConfig
方法。