Metriche repository
- Star
- (34.398 star)
- Metriche merge PR
- (Merge medio 6g 19h) (384 PR mergiate in 30 g)
Descrizione
Before reporting an issue
- I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
Area
admin/fine-grained-permissions
Describe the bug
Hi, I want to use Fine Grained Admin Permissions. I need a policy that will allow access to the clients whose clientId starts with pre-defined prefix. For that case, I implemented my custom PolicyProvider, PolicyProviderFactory, AbstractPolicyRepresentation.
As a result, I can see my policy in the New policy dialogue but when I select it, the config is not present. There is some Code input field instead of my config prefix field of type string.
Create new policy:
Policy config window
public class ClientPrefixPolicyRepresentation extends AbstractPolicyRepresentation {
private String clientPrefix;
@Override
public String getType() {
return "client-prefix";
}
public String getClientPrefix() {
return clientPrefix;
}
public void setClientPrefix(String clientPrefix) {
this.clientPrefix = clientPrefix;
}
@Override
public String getDescription() {
return "Only allow access to clients whose ID starts with this prefix.";
}
}
public class ClientPrefixPolicyProvider implements PolicyProvider {
private final Logger logger = Logger.getLogger(ClientPrefixPolicyProvider.class);
private final BiFunction<Policy, AuthorizationProvider, ClientPrefixPolicyRepresentation> representationFunction;
public ClientPrefixPolicyProvider(
BiFunction<Policy, AuthorizationProvider, ClientPrefixPolicyRepresentation> representationFunction) {
this.representationFunction = representationFunction;
}
@Override
public void evaluate(Evaluation evaluation) {
ClientPrefixPolicyRepresentation representation = representationFunction.apply(
evaluation.getPolicy(), evaluation.getAuthorizationProvider());
ResourcePermission permission = evaluation.getPermission();
String clientUUID = permission.getResource().getName();
RealmModel realm = evaluation.getAuthorizationProvider().getRealm();
ClientModel clientModel = realm.getClientById(clientUUID);
if (clientModel != null) {
String clientId = clientModel.getClientId();
if (clientId.startsWith(representation.getClientPrefix())) {
evaluation.grant();
} else {
evaluation.deny();
}
}
}
@Override
public void close() {
}
}
@AutoService(PolicyProviderFactory.class)
public class ClientPrefixPolicyProviderFactory implements PolicyProviderFactory<ClientPrefixPolicyRepresentation> {
private final ClientPrefixPolicyProvider provider = new ClientPrefixPolicyProvider(this::toRepresentation);
@Override
public String getName() {
return "Client prefix policy";
}
@Override
public String getGroup() {
return "Identity based";
}
@Override
public PolicyProvider create(AuthorizationProvider authorizationProvider) {
return provider;
}
@Override
public ClientPrefixPolicyRepresentation toRepresentation(Policy policy,
AuthorizationProvider authorizationProvider) {
ClientPrefixPolicyRepresentation representation = new ClientPrefixPolicyRepresentation();
representation.setClientPrefix(getClientPrefix(policy));
return representation;
}
@Override
public Class<ClientPrefixPolicyRepresentation> getRepresentationType() {
return ClientPrefixPolicyRepresentation.class;
}
@Override
public PolicyProvider create(KeycloakSession keycloakSession) {
return provider;
}
@Override
public void init(Scope scope) {
}
@Override
public void postInit(KeycloakSessionFactory keycloakSessionFactory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return "client-prefix";
}
@Override
public List<ProviderConfigProperty> getConfigMetadata() {
return ProviderConfigurationBuilder.create()
.property()
.name("prefix")
.label("Client prefix")
.type("string")
.helpText("Only allow access to clients whose ID starts with this prefix.")
.required(true)
.add()
.build();
}
private String getClientPrefix(Policy policy) {
String clientPrefix = policy.getConfig().get("prefix");
if (clientPrefix != null) {
try {
return JsonSerialization.readValue(clientPrefix, String.class);
} catch (IOException e) {
throw new RuntimeException(
"Could not parse client prefix [" + clientPrefix + "] from policy config ["
+ policy.getName() + "].", e);
}
}
return "";
}
}
Can you please advice what is wrong with the implementation and how to make it work?
Version
26.3.2
Regression
- The issue is a regression
Expected behavior
Custom policy is configurable in the UI.
Actual behavior
Custom policy is not configurable in the UI.
How to Reproduce?
Implement a custom policy and go to Create new policy in the Configure -> Permissions menu
Anything else?
No response