Keycloak Spring Boot适配器不允许设置keycloak.policy-enforcer-config.user-managed-access属性。

3

我试图使用SpringBoot适配器保护我的应用程序。在深入研究源代码后,我发现了一些实现中似乎存在的错误。

在KeycloakAdapterPolicyEnforcer类内部,获取用户权限的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。
但是,由于PolicyEnforcerConfig类将字段userManagedAccess定义为UserManagedAccessConfig对象,因此我无法定义它。
@JsonProperty("user-managed-access")
@JsonInclude(JsonInclude.Include.NON_NULL)
private UserManagedAccessConfig userManagedAccess;

但是没有提供任何Jackson转换器,可以将String转换为UserManagedAccessConfig。

如果没有设置此配置属性,适配器将拒绝每个请求。有没有解决此问题的临时方法?


你解决了这个问题吗?我也遇到了同样的问题。 - Dallas Phillips
2个回答

0

@scandinave的答案不支持在应用程序属性中定义的keycloak.policy-enforcer-config.*属性。以下是讨论中建议的“脏”解决方法,它可以保留策略执行器配置属性并添加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方法。

我可以请教一下 user-managed-access 的用途是什么吗?我真的很想知道。 - xbmono

0

是的,我只是使用了一个 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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接