How to Integrate jCasbin Permission Management into Spring Boot Applications

This tutorial explains how backend developers can replace Shiro with jCasbin for fine‑grained permission control in Spring Boot projects, covering Maven setup, configuration files, Enforcer initialization, custom filters, and dynamic policy management.

macrozheng
macrozheng
macrozheng
How to Integrate jCasbin Permission Management into Spring Boot Applications

Introduction

As a backend developer, permission management is familiar, but Shiro has many drawbacks in distributed, front‑back separation scenarios. jCasbin offers a simpler alternative that can be quickly adopted.

1. Preparation

Based on Spring Boot, add the following Maven dependencies:

<dependency>
  <groupId>org.casbin</groupId>
  <artifactId>jcasbin</artifactId>
  <version>1.1.0</version>
</dependency>
<dependency>
  <groupId>org.casbin</groupId>
  <artifactId>jdbc-adapter</artifactId>
  <version>1.1.0</version>
</dependency>

2. Configuration Files

jCasbin stores roles and permissions in model.conf and policy.csv. Example application.properties configuration:

org.jcasbin.url=jdbc:mysql://localhost:3306/casbin?useSSL=false
org.jcasbin.driver-class-name=com.mysql.jdbc.Driver
org.jcasbin.username=root
org.jcasbin.password=root
org.jcasbin.model-path=conf/authz_model.conf

3. Initialize Permission Information

Create a class that implements InitializingBean to load the Enforcer with a JDBCAdapter and the model file.

@Component
public class EnforcerFactory implements InitializingBean {
    private static Enforcer enforcer;
    @Autowired
    private EnforcerConfigProperties enforcerConfigProperties;
    private static EnforcerConfigProperties config;
    @Override
    public void afterPropertiesSet() throws Exception {
        config = enforcerConfigProperties;
        JDBCAdapter jdbcAdapter = new JDBCAdapter(
            config.getDriverClassName(),
            config.getUrl(),
            config.getUsername(),
            config.getPassword(),
            true);
        enforcer = new Enforcer(config.getModelPath(), jdbcAdapter);
        enforcer.loadPolicy();
    }
    public static boolean addPolicy(Policy policy) {
        boolean added = enforcer.addPolicy(policy.getSub(), policy.getObj(), policy.getAct());
        enforcer.savePolicy();
        return added;
    }
    public static boolean removePolicy(Policy policy) {
        boolean removed = enforcer.removePolicy(policy.getSub(), policy.getObj(), policy.getAct());
        enforcer.savePolicy();
        return removed;
    }
    public static Enforcer getEnforcer() {
        return enforcer;
    }
}

Define a simple Policy class to encapsulate sub, obj, and act fields.

public class Policy {
    /** User or role */
    private String sub;
    /** Resource, supports * wildcard */
    private String obj;
    /** Action (HTTP method), supports * wildcard */
    private String act;
    public Policy() {}
    public Policy(String sub, String obj, String act) {
        this.sub = sub;
        this.obj = obj;
        this.act = act;
    }
    // getters and setters omitted for brevity
    @Override
    public String toString() {
        return "Policy [sub=" + sub + ", obj=" + obj + ", act=" + act + "]";
    }
}

4. Usage

Permission Control

Create a servlet filter that checks permissions using enforcer.enforce(user, path, method). If the check fails, return a JSON error response.

@WebFilter(urlPatterns = "/*", filterName = "JCasbinAuthzFilter")
@Order(Ordered.HIGHEST_PRECEDENCE)
public class JCasbinAuthzFilter implements Filter {
    private static final Logger log = LoggerFactory.getLogger(JCasbinAuthzFilter.class);
    private static Enforcer enforcer;
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String user = request.getParameter("username");
        String path = request.getRequestURI();
        String method = request.getMethod();
        enforcer = EnforcerFactory.getEnforcer();
        if (path.contains("anon")) {
            chain.doFilter(request, response);
        } else if (enforcer.enforce(user, path, method)) {
            chain.doFilter(request, response);
        } else {
            log.info("Access denied");
            Map<String, Object> result = new HashMap<>();
            result.put("code", 1001);
            result.put("msg", "User lacks permission");
            result.put("data", null);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            response.getWriter().write(JSONObject.toJSONString(result, SerializerFeature.WriteMapNullValue));
        }
    }
    // init and destroy methods omitted
}

Add/Delete Permissions

Expose controller endpoints that call EnforcerFactory.addPolicy and EnforcerFactory.removePolicy to modify policies at runtime without restarting the service.

@PutMapping("/anon/role/per")
public ResultBO<Object> addPer() {
    EnforcerFactory.addPolicy(new Policy("alice", "/user/list", "*"));
    return ResultTool.success();
}

@DeleteMapping("/anon/role/per")
public ResultBO<Object> deletePer() {
    EnforcerFactory.removePolicy(new Policy("alice", "/user/list", "*"));
    return ResultTool.success();
}

Conclusion

jCasbin can be combined with Spring Cloud Zuul to achieve unified login and permission control by extending ZuulFilter. The presented approach provides a lightweight, dynamic, and database‑driven permission system for Spring Boot backends.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

access controlpermissionspring-bootjCasbin
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.