Build a Secure Permission System with SpringBoot, MyBatis & Shiro

This article introduces the open‑source renren‑security permission management solution, detailing its architecture, core modules, and how to implement authentication and authorization with Apache Shiro in a SpringBoot‑MyBatis stack, including code examples for login, role‑based access, XSS/SQL filtering, and deployment options.

21CTO
21CTO
21CTO
Build a Secure Permission System with SpringBoot, MyBatis & Shiro

System security is a non‑negotiable aspect of software development, and permission control is tightly coupled with it. The open‑source renren‑security project provides a lightweight permission management system built with SpringBoot, MyBatis, and Apache Shiro, offering low entry barriers and ready‑to‑use features such as distributed deployment, Quartz clustering, department management, data permissions, and cloud storage.

Project Features

Fine‑grained permission control down to pages or buttons, covering most use cases.

Comprehensive department and data‑level permissions implemented via annotations.

Robust XSS protection and script filtering to prevent attacks.

Support for major databases: MySQL, Oracle, SQL Server, PostgreSQL, etc.

Runtime screenshot
Runtime screenshot

System Architecture

The system is organized into clear modules: common , admin , and api .

common : A jar‑based library shared by other modules, providing utilities such as time handling, pagination, SQL filtering, XSS filtering, Redis aspects, and custom exception handling.

admin : The management console packaged as a WAR, following a front‑end/back‑end separation model. It includes user, role, department, menu management, scheduled tasks, file upload, API validation, and Redis caching, supporting both single‑node and cluster deployments.

api : The API layer, also packaged as a WAR, exposing endpoints for front‑end UI calls. It handles user registration, login, permission verification, and user information retrieval, and integrates Swagger2 for API documentation.

System architecture diagram
System architecture diagram

The design emphasizes security: both pages and APIs perform permission checks via Shiro. During login, the user’s credentials are validated, roles are retrieved, and Shiro enforces access control on UI elements and API calls. SQL and XSS filtering are applied before persisting data.

Permission verification flow
Permission verification flow

Shiro Authentication and Authorization

Authentication requires a custom Realm extending AuthorizingRealm and overriding doGetAuthenticationInfo (for login) and doGetAuthorizationInfo (for permission retrieval).

Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
subject.login(token); // triggers Shiro authentication

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
    UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
    SysUserEntity user = new SysUserEntity();
    user.setUsername(token.getUsername());
    user = sysUserDao.selectOne(user);
    if (user == null) {
        throw new UnknownAccountException("账号或密码不正确");
    }
    return new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
}

After successful authentication, SecurityUtils.getSubject() can retrieve the authenticated user anywhere in the system, enabling features such as automatic login.

Permissions are stored as tags in the database; a user possessing a tag gains the corresponding operation rights. During authorization, the system loads all permission tags for the user and builds a SimpleAuthorizationInfo object.

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    SysUserEntity user = (SysUserEntity) principals.getPrimaryPrincipal();
    Long userId = user.getUserId();
    Set<String> permsSet = new HashSet<>();
    List<String> permsList = sysUserDao.queryAllPerms(userId);
    for (String perms : permsList) {
        if (StringUtils.isBlank(perms)) continue;
        permsSet.addAll(Arrays.asList(perms.trim().split(",")));
    }
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    info.setStringPermissions(permsSet);
    return info;
}

Shiro’s permission checks can be applied at two levels:

Page level : Using #if shiro.hasPermission("sys:del") in templates to conditionally render buttons or links.

Method level : Annotating controller methods with @RequiresPermissions("sys:del") to enforce access control.

<#if shiro.hasPermission("sys:add")>
    <a class="btn btn-primary" @click="add">新增</a>
</#if>
<#if shiro.hasPermission("sys:del")>
    <a class="btn btn-primary" @click="del">删除</a>
</#if>
@RequestMapping("/delete")
@RequiresPermissions("sys:del")
public R delete(long deptId) {
    List<Long> deptList = sysDeptService.queryDetpIdList(deptId);
    if (deptList.size() > 0) {
        return R.error("请先删除子部门");
    }
    sysDeptService.deleteById(deptId);
    return R.ok();
}

Beyond permission control, the project also includes common backend features such as Quartz distributed scheduling, dynamic multi‑data‑source switching, and clustered session management. The source code is available at https://gitee.com/renrenio/renren-security .

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.

JavaSpringBootpermission managementShiro
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

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.