casbin / jcasbin

An authorization library that supports access control models like ACL, RBAC, ABAC in Java
https://casbin.org
Apache License 2.0
2.38k stars 461 forks source link

ArrayIndexOutOfBoundsException when performing enforce #288

Closed damienmiheev closed 2 years ago

damienmiheev commented 2 years ago

I'm using org.casbin:casbin-spring-boot-starter:0.4.2 and org.casbin:jcasbin:1.27.0. Synchronisation over redis is enabled: useSyncedEnforcer: true. The policies is stored in postgres db.

The model is a simple ACL:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m =  r.sub == p.sub && r.obj == p.obj && r.act == p.act

Application is a single app, but it has multiple modules, communicated through the rabbitmq.

Time to time i'm getting ArrayIndexOutOfBoundsException error here: org/casbin/jcasbin/main/CoreEnforcer.java:524

if ((policyLen = model.model.get("p").get(pType).policy.size()) != 0) {
    policyEffects = new Effect[policyLen];
    matcherResults = new float[policyLen];
    for (int i = 0; i < model.model.get("p").get(pType).policy.size(); i++) {
        List<String> pvals = model.model.get("p").get(pType).policy.get(i);
        // Util.logPrint("Policy Rule: " + pvals);
        // Select the rule based on request size
        Map<String, Object> parameters = new HashMap<>();
        getRTokens(parameters, rvals);
        for (int j = 0; j < model.model.get("p").get(pType).tokens.length; j++) {
            String token = model.model.get("p").get(pType).tokens[j];
            parameters.put(token, pvals.get(j));
        }
        Object result = expression.execute(parameters);
        // Util.logPrint("Result: " + result);
        if (result instanceof Boolean) {
            if (!((boolean) result)) {
                policyEffects[i] = Effect.Indeterminate;  <-- here

So if i clearly understood, it initialises policyEffects = new Effect[policyLen] array of length model.model.get("p").get(pType).policy.size()), but then during the for loop, it becomes bigger.

As i said before the app is a monolith where the Enforcer is a singleton bean which is shared between the modules. Based on async rabbit message handling, different modules perform enforcer.addPolicies and enforcer.removePolicies. Meanwhile i'm getting ArrayIndexOutOfBoundsException on enforcer.batchEnforce.

I expected that enforcer is thread safe when the sychronisation over redis is enabled, but maybe I missing something? Could you please help me to solve the issue.

casbin-bot commented 2 years ago

@tangyang9464 @imp2002

hsluoyz commented 2 years ago

@imp2002

damienmiheev commented 2 years ago

Sorry guys, I rather had a problem with my redis test container / watcher configuration than casbin. Issue is not valid.

damienmiheev commented 2 years ago

Ok, now the environment is well configured, unfortunately issue is still here. All my tests are running on same docker containers stack, so the db and redis are shared between integration tests. I mentioned that the issue becomes visible, in the middle of test running, when there are already some numbers of rows in casbin_rule table.

hsluoyz commented 2 years ago

@damienmiheev plz try to troubleshoot by yourself for several days to make sure it really exists, if still valid, make a new issue