Add logging to the policy providers for general debugging purposes
Signed-off-by: Alice W <105500542+alice-wondered@users.noreply.github.com>
This commit is contained in:
parent
2eb31f8dbb
commit
cf19c06341
17 changed files with 72 additions and 7 deletions
|
@ -51,6 +51,11 @@
|
|||
<artifactId>keycloak-server-spi-private</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -17,11 +17,10 @@
|
|||
*/
|
||||
package org.keycloak.authorization.policy.provider.aggregated;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
|
@ -36,9 +35,11 @@ import org.keycloak.authorization.policy.provider.PolicyProvider;
|
|||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class AggregatePolicyProvider implements PolicyProvider {
|
||||
private static final Logger logger = Logger.getLogger(AggregatePolicyProvider.class);
|
||||
|
||||
@Override
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
logger.debugv("Aggregate policy {} evaluating using parent class", evaluation.getPolicy().getName());
|
||||
DecisionResultCollector decision = new DecisionResultCollector() {
|
||||
@Override
|
||||
protected void onComplete(Result result) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.keycloak.authorization.policy.provider.client;
|
|||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
|
@ -13,6 +14,7 @@ import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation
|
|||
|
||||
public class ClientPolicyProvider implements PolicyProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ClientPolicyProvider.class);
|
||||
private final BiFunction<Policy, AuthorizationProvider, ClientPolicyRepresentation> representationFunction;
|
||||
|
||||
public ClientPolicyProvider(BiFunction<Policy, AuthorizationProvider, ClientPolicyRepresentation> representationFunction) {
|
||||
|
@ -31,6 +33,7 @@ public class ClientPolicyProvider implements PolicyProvider {
|
|||
|
||||
if (context.getAttributes().containsValue("kc.client.id", clientModel.getClientId())) {
|
||||
evaluation.grant();
|
||||
logger.debugv("Client policy {} matched with client {} and was granted", evaluation.getPolicy().getName(), clientModel.getClientId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.keycloak.authorization.policy.provider.clientscope;
|
|||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.identity.Identity;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
|
@ -34,6 +35,7 @@ import org.keycloak.representations.idm.authorization.ClientScopePolicyRepresent
|
|||
*/
|
||||
public class ClientScopePolicyProvider implements PolicyProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ClientScopePolicyProvider.class);
|
||||
private final BiFunction<Policy, AuthorizationProvider, ClientScopePolicyRepresentation> representationFunction;
|
||||
|
||||
public ClientScopePolicyProvider(
|
||||
|
@ -68,6 +70,7 @@ public class ClientScopePolicyProvider implements PolicyProvider {
|
|||
}
|
||||
}
|
||||
}
|
||||
logger.debugv("Client Scope Policy {} evaluated to {}", policy.getName(), evaluation.getEffect());
|
||||
}
|
||||
|
||||
private boolean hasClientScope(Identity identity, ClientScopeModel clientScope) {
|
||||
|
|
|
@ -21,6 +21,7 @@ import static org.keycloak.models.utils.ModelToRepresentation.buildGroupPath;
|
|||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.attribute.Attributes;
|
||||
import org.keycloak.authorization.attribute.Attributes.Entry;
|
||||
|
@ -36,6 +37,7 @@ import org.keycloak.representations.idm.authorization.GroupPolicyRepresentation;
|
|||
*/
|
||||
public class GroupPolicyProvider implements PolicyProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(GroupPolicyProvider.class);
|
||||
private final BiFunction<Policy, AuthorizationProvider, GroupPolicyRepresentation> representationFunction;
|
||||
|
||||
public GroupPolicyProvider(BiFunction<Policy, AuthorizationProvider, GroupPolicyRepresentation> representationFunction) {
|
||||
|
@ -75,6 +77,7 @@ public class GroupPolicyProvider implements PolicyProvider {
|
|||
}
|
||||
}
|
||||
}
|
||||
logger.debugv("Groups policy {} evaluated to {} with identity groups {}", policy.getName(), evaluation.getEffect(), groupsClaim);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.function.BiFunction;
|
|||
import javax.script.ScriptContext;
|
||||
import javax.script.SimpleScriptContext;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
|
@ -33,6 +34,8 @@ import org.keycloak.scripting.EvaluatableScriptAdapter;
|
|||
*/
|
||||
class JSPolicyProvider implements PolicyProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(JSPolicyProvider.class);
|
||||
|
||||
private final BiFunction<AuthorizationProvider, Policy, EvaluatableScriptAdapter> evaluatableScript;
|
||||
|
||||
JSPolicyProvider(final BiFunction<AuthorizationProvider, Policy, EvaluatableScriptAdapter> evaluatableScript) {
|
||||
|
@ -51,6 +54,7 @@ class JSPolicyProvider implements PolicyProvider {
|
|||
context.setAttribute("$evaluation", evaluation, ScriptContext.ENGINE_SCOPE);
|
||||
|
||||
adapter.eval(context);
|
||||
logger.debugv("JS Policy {} evaluated to status {}", policy.getName(), evaluation.getEffect());
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException("Error evaluating JS Policy [" + policy.getName() + "].", e);
|
||||
|
|
|
@ -5,7 +5,6 @@ import org.keycloak.authorization.AuthorizationProvider;
|
|||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.policy.provider.PolicyProvider;
|
||||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
|
|
@ -16,8 +16,12 @@
|
|||
*/
|
||||
package org.keycloak.authorization.policy.provider.permission;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.Decision.Effect;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.policy.evaluation.DefaultEvaluation;
|
||||
|
@ -32,6 +36,8 @@ import java.util.Map;
|
|||
*/
|
||||
public abstract class AbstractPermissionProvider implements PolicyProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AbstractPermissionProvider.class);
|
||||
|
||||
@Override
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
AuthorizationProvider authorization = evaluation.getAuthorizationProvider();
|
||||
|
@ -60,6 +66,7 @@ public abstract class AbstractPermissionProvider implements PolicyProvider {
|
|||
defaultEvaluation.setEffect(effect);
|
||||
}
|
||||
}
|
||||
logger.debugv("Policy {} was evaluated with status {} in {} mode after processing {} associated policies: {}", policy.getName(), evaluation.getEffect(), policy.getDecisionStrategy(), policy.getAssociatedPolicies().size(), policy.getAssociatedPolicies());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.keycloak.authorization.policy.provider.permission;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
|
@ -30,8 +31,11 @@ import java.util.Map;
|
|||
*/
|
||||
public class ResourcePolicyProvider extends AbstractPermissionProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ResourcePolicyProvider.class);
|
||||
|
||||
@Override
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
logger.debugv("Resource policy {} evaluating using parent class", evaluation.getPolicy().getName());
|
||||
DefaultEvaluation defaultEvaluation = DefaultEvaluation.class.cast(evaluation);
|
||||
Map<Policy, Map<Object, Decision.Effect>> decisionCache = defaultEvaluation.getDecisionCache();
|
||||
Policy policy = defaultEvaluation.getParentPolicy();
|
||||
|
@ -43,7 +47,6 @@ public class ResourcePolicyProvider extends AbstractPermissionProvider {
|
|||
defaultEvaluation.setEffect(effect);
|
||||
return;
|
||||
}
|
||||
|
||||
super.evaluate(evaluation);
|
||||
|
||||
decisions.put(permission.getResource(), defaultEvaluation.getEffect());
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
*/
|
||||
package org.keycloak.authorization.policy.provider.permission;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.Decision;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.model.Scope;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.policy.evaluation.DefaultEvaluation;
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
|
@ -31,8 +31,11 @@ import java.util.Map;
|
|||
*/
|
||||
public class ScopePolicyProvider extends AbstractPermissionProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ScopePolicyProvider.class);
|
||||
|
||||
@Override
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
logger.debugv("Scope policy {} evaluating using parent class", evaluation.getPolicy().getName());
|
||||
DefaultEvaluation defaultEvaluation = DefaultEvaluation.class.cast(evaluation);
|
||||
Map<Policy, Map<Object, Decision.Effect>> decisionCache = defaultEvaluation.getDecisionCache();
|
||||
Policy policy = defaultEvaluation.getParentPolicy();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.keycloak.authorization.policy.provider.permission;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.identity.Identity;
|
||||
import org.keycloak.authorization.model.Resource;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
|
@ -26,8 +27,11 @@ import org.keycloak.authorization.policy.evaluation.Evaluation;
|
|||
*/
|
||||
public class UMAPolicyProvider extends AbstractPermissionProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(UMAPolicyProvider.class);
|
||||
|
||||
@Override
|
||||
public void evaluate(Evaluation evaluation) {
|
||||
logger.debugv("UMA policy {} evaluating using parent class", evaluation.getPolicy().getName());
|
||||
ResourcePermission permission = evaluation.getPermission();
|
||||
Resource resource = permission.getResource();
|
||||
|
||||
|
@ -36,6 +40,7 @@ public class UMAPolicyProvider extends AbstractPermissionProvider {
|
|||
|
||||
// no need to evaluate UMA permissions to resource owner resources
|
||||
if (resource.getOwner().equals(identity.getId())) {
|
||||
logger.debugv("UMA resource is owned by the current user, bypassing evaluation");
|
||||
evaluation.grant();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.function.BiFunction;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.attribute.Attributes;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
|
@ -42,6 +43,7 @@ import com.fasterxml.jackson.databind.JsonNode;
|
|||
*/
|
||||
public class RegexPolicyProvider implements PolicyProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(RegexPolicyProvider.class);
|
||||
private final BiFunction<Policy, AuthorizationProvider, RegexPolicyRepresentation> representationFunction;
|
||||
|
||||
public RegexPolicyProvider(BiFunction<Policy, AuthorizationProvider, RegexPolicyRepresentation> representationFunction) {
|
||||
|
@ -66,6 +68,7 @@ public class RegexPolicyProvider implements PolicyProvider {
|
|||
Matcher matcher = pattern.matcher(value);
|
||||
if (matcher.matches()) {
|
||||
evaluation.grant();
|
||||
logger.debugv("policy {} evaluated with status {} on identity {} and claim value {}", policy.getName(), evaluation.getEffect(), evaluation.getContext().getIdentity().getId(), getClaimValue(evaluation, policy));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.keycloak.authorization.policy.provider.role;
|
|||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.identity.Identity;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
|
@ -37,6 +38,8 @@ public class RolePolicyProvider implements PolicyProvider {
|
|||
|
||||
private final BiFunction<Policy, AuthorizationProvider, RolePolicyRepresentation> representationFunction;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(RolePolicyProvider.class);
|
||||
|
||||
public RolePolicyProvider(BiFunction<Policy, AuthorizationProvider, RolePolicyRepresentation> representationFunction) {
|
||||
this.representationFunction = representationFunction;
|
||||
}
|
||||
|
@ -63,6 +66,7 @@ public class RolePolicyProvider implements PolicyProvider {
|
|||
}
|
||||
}
|
||||
}
|
||||
logger.debugv("policy {} evaluated with status {} on identity {}", policy.getName(), evaluation.getEffect(), identity.getId());
|
||||
}
|
||||
|
||||
private boolean hasRole(Identity identity, RoleModel role, RealmModel realm) {
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.attribute.Attributes;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
|
@ -32,6 +33,8 @@ import org.keycloak.authorization.policy.provider.PolicyProvider;
|
|||
*/
|
||||
public class TimePolicyProvider implements PolicyProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(TimePolicyProvider.class);
|
||||
|
||||
static String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
static String CONTEXT_TIME_ENTRY = "kc.time.date_time";
|
||||
|
@ -40,6 +43,7 @@ public class TimePolicyProvider implements PolicyProvider {
|
|||
public void evaluate(Evaluation evaluation) {
|
||||
Policy policy = evaluation.getPolicy();
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_PATTERN);
|
||||
logger.debugv("Time policy {} evaluating", policy.getName());
|
||||
try {
|
||||
String contextTime = null;
|
||||
EvaluationContext context = evaluation.getContext();
|
||||
|
@ -54,6 +58,7 @@ public class TimePolicyProvider implements PolicyProvider {
|
|||
String notBefore = policy.getConfig().get("nbf");
|
||||
if (notBefore != null && !"".equals(notBefore)) {
|
||||
if (actualDate.before(dateFormat.parse(format(notBefore)))) {
|
||||
logger.debugv("Provided date is before the accepted date: (nbf) ", notBefore);
|
||||
evaluation.deny();
|
||||
return;
|
||||
}
|
||||
|
@ -62,6 +67,7 @@ public class TimePolicyProvider implements PolicyProvider {
|
|||
String notOnOrAfter = policy.getConfig().get("noa");
|
||||
if (notOnOrAfter != null && !"".equals(notOnOrAfter)) {
|
||||
if (actualDate.after(dateFormat.parse(format(notOnOrAfter)))) {
|
||||
logger.debugv("Provided date is after the accepted date: (noa) {}", notOnOrAfter);
|
||||
evaluation.deny();
|
||||
return;
|
||||
}
|
||||
|
@ -72,6 +78,7 @@ public class TimePolicyProvider implements PolicyProvider {
|
|||
|| isInvalid(actualDate, Calendar.YEAR, "year", policy)
|
||||
|| isInvalid(actualDate, Calendar.HOUR_OF_DAY, "hour", policy)
|
||||
|| isInvalid(actualDate, Calendar.MINUTE, "minute", policy)) {
|
||||
logger.debugv("Invalid date provided to time policy {}", policy.getName());
|
||||
evaluation.deny();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
package org.keycloak.authorization.policy.provider.user;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.policy.evaluation.Evaluation;
|
||||
|
@ -32,6 +32,8 @@ import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
|
|||
*/
|
||||
public class UserPolicyProvider implements PolicyProvider {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(UserPolicyProvider.class);
|
||||
|
||||
private final BiFunction<Policy, AuthorizationProvider, UserPolicyRepresentation> representationFunction;
|
||||
|
||||
public UserPolicyProvider(BiFunction<Policy, AuthorizationProvider, UserPolicyRepresentation> representationFunction) {
|
||||
|
@ -49,6 +51,7 @@ public class UserPolicyProvider implements PolicyProvider {
|
|||
break;
|
||||
}
|
||||
}
|
||||
logger.debugv("User policy {} evaluated to status {} on identity {} with accepted users: {}", evaluation.getPolicy().getName(), evaluation.getEffect(), evaluation.getContext().getIdentity().getId(), representation.getUsers());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -122,10 +122,15 @@ public class DefaultEvaluation implements Evaluation {
|
|||
return this.parentPolicy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Effect getEffect() {
|
||||
return effect;
|
||||
}
|
||||
|
||||
public Decision getDecision() {
|
||||
return decision;
|
||||
}
|
||||
|
||||
public Map<Policy, Map<Object, Effect>> getDecisionCache() {
|
||||
return decisionCache;
|
||||
}
|
||||
|
@ -266,6 +271,7 @@ public class DefaultEvaluation implements Evaluation {
|
|||
this.effect = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEffect(Effect effect) {
|
||||
this.effect = effect;
|
||||
this.decision.onDecision(this);
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
package org.keycloak.authorization.policy.evaluation;
|
||||
|
||||
import org.keycloak.authorization.AuthorizationProvider;
|
||||
import org.keycloak.authorization.Decision.Effect;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.permission.ResourcePermission;
|
||||
import org.keycloak.authorization.policy.provider.PolicyProvider;
|
||||
|
||||
/**
|
||||
* <p>An {@link Evaluation} is mainly used by {@link org.keycloak.authorization.policy.provider.PolicyProvider} in order to evaluate a single
|
||||
* <p>An {@link Evaluation} is mainly used by {@link PolicyProvider} in order to evaluate a single
|
||||
* and specific {@link ResourcePermission} against the configured policies.
|
||||
*
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
|
@ -74,4 +76,8 @@ public interface Evaluation {
|
|||
* Denies the requested permission if a decision was not made yet.
|
||||
*/
|
||||
void denyIfNoEffect();
|
||||
|
||||
Effect getEffect();
|
||||
|
||||
void setEffect(Effect effect);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue