Search code examples
spring-bootoauth-2.0authorizationkeycloak

Keycloak springboot adapter does not allowed to set keycloak.policy-enforcer-config.user-managed-access property


I try to secure my application with the springboot adapter. After digging inside the source code, i have see something that seems to be a bug inside the implementation.

Inside the KeycloakAdapterPolicyEnforcer class, the method getPermissionTicket that retrieve permissions for a user contains this :

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;
}

getEnforcerConfig().getUserManagedAccess() != null is always null if you have not defined the keycloak.policy-enforcer-config.user-managed-access property inside the application.properties.

But i can't define it because of the PolicyEnforcerConfig class that defines the field userManagedAccess as a UserManagedAccessConfig object

@JsonProperty("user-managed-access")
@JsonInclude(JsonInclude.Include.NON_NULL)
private UserManagedAccessConfig userManagedAccess;

but not provides any jackson convertor to passe from String to UserManagedAccessConfig

Without this config property set, the adapter just reject every requests. Any workaround for this issue?


Solution

  • Yeah, I just use a bean instead of property file. Something like this :

    @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;
        }
    }