Information Security 23 min read

Sa-Token Java Authentication and Authorization Framework: Overview, Core Concepts, and SpringBoot Integration

This article introduces the lightweight Sa-Token Java framework, explains its login and permission authentication mechanisms, demonstrates essential API usage with code examples, and provides step‑by‑step integration guides for SpringBoot and WebFlux, covering configuration, session handling, role checks, wildcard permissions, and global exception handling.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Sa-Token Java Authentication and Authorization Framework: Overview, Core Concepts, and SpringBoot Integration

1. Technology Selection

When implementing login and authorization, Spring Boot + Spring Security is often too heavy for lightweight projects, and Spring Boot + Shiro conflicts with Spring Boot’s AOP, leading to the choice of Sa‑Token.

2. Sa‑Token Overview

2.1 Simple Introduction

Sa‑Token is a lightweight Java permission authentication framework that addresses login authentication, permission authentication, single sign‑on, OAuth2.0, distributed sessions, and micro‑service gateway authentication.

2.2 Login Authentication

Design Idea

Protected endpoints require a session check; if the session is valid, data is returned, otherwise an exception is thrown.

The login flow is: user submits name + password → login API validates credentials → a Token is issued → the Token is stored in a Cookie and sent with subsequent requests.

StpUtil.login(Object id);

Sa‑Token automatically handles checks such as account bans, existing logins, token generation, and Cookie injection.

@RequestMapping("doLogin")
public SaResult doLogin(String name, String pwd) {
    if ("zhang".equals(name) && "123456".equals(pwd)) {
        StpUtil.login(10001);
        return SaResult.ok("登录成功");
    }
    return SaResult.error("登录失败");
}

Cookie automatically stores the Token, so the backend does not need to return the Token explicitly.

Session Operations

StpUtil.logout();
StpUtil.isLogin();
StpUtil.checkLogin();

TokenInfo can be queried to obtain details such as token name, value, login status, loginId, expiration, and device.

{
  "code":200,
  "msg":"ok",
  "data":{
    "tokenName":"satoken",
    "tokenValue":"e67b99f1-3d7a-4a8d-bb2f-e888a0805633",
    "isLogin":true,
    "loginId":"10001",
    "loginType":"login",
    "tokenTimeout":2591977,
    "sessionTimeout":2591977,
    "tokenSessionTimeout":-2,
    "tokenActivityTimeout":-1,
    "loginDevice":"default-device"
  }
}

Testing Example

@RestController
@RequestMapping("/acc/")
public class LoginController {
    @RequestMapping("doLogin")
    public SaResult doLogin(String name, String pwd) {
        if ("zhang".equals(name) && "123456".equals(pwd)) {
            StpUtil.login(10001);
            return SaResult.ok("登录成功");
        }
        return SaResult.error("登录失败");
    }
    @RequestMapping("isLogin")
    public SaResult isLogin() {
        return SaResult.ok("是否登录:" + StpUtil.isLogin());
    }
    @RequestMapping("tokenInfo")
    public SaResult tokenInfo() {
        return SaResult.data(StpUtil.getTokenInfo());
    }
    @RequestMapping("logout")
    public SaResult logout() {
        StpUtil.logout();
        return SaResult.ok();
    }
}

2.3 Permission Authentication

Design Idea

Permission checks simply verify whether the current account possesses a specific permission code; if not, access is denied.

Getting Permission List

@Component
public class StpInterfaceImpl implements StpInterface {
    @Override
    public List
getPermissionList(Object loginId, String loginType) {
        List
list = new ArrayList<>();
        list.add("101");
        list.add("user-add");
        list.add("user-delete");
        list.add("user-update");
        list.add("user-get");
        list.add("article-get");
        return list;
    }
    @Override
    public List
getRoleList(Object loginId, String loginType) {
        List
list = new ArrayList<>();
        list.add("admin");
        list.add("super-admin");
        return list;
    }
}

Permission APIs

StpUtil.getPermissionList();
StpUtil.hasPermission("user-update");
StpUtil.checkPermission("user-update");
StpUtil.checkPermissionAnd("user-update", "user-delete");
StpUtil.checkPermissionOr("user-update", "user-delete");

Role APIs

StpUtil.getRoleList();
StpUtil.hasRole("super-admin");
StpUtil.checkRole("super-admin");
StpUtil.checkRoleAnd("super-admin", "shop-admin");
StpUtil.checkRoleOr("super-admin", "shop-admin");

Wildcard Permissions

StpUtil.hasPermission("user-add"); // true when "user*" granted
StpUtil.hasPermission("art-add"); // false
StpUtil.hasPermission("index.js"); // true when "*.js" granted

Front‑end vs Back‑end Authentication

Even if the front‑end performs UI‑level checks, the back‑end must still enforce authentication to ensure security.

3. Feature Overview

Login authentication (single‑device, multi‑device, exclusive login, remember‑me)

Permission & role authentication

Session sharing, custom sessions

Kick‑out, account banning

Redis/Memcached persistence

Distributed sessions (JWT, data‑center)

Gateway authentication (Gateway, ShenYu, Zuul)

SSO, OAuth2.0, secondary authentication

Basic auth, independent Redis, temporary tokens, impersonation, button‑level control, etc.

4. Sa‑Token Usage

4.1 Adding Dependency

cn.dev33
sa-token-spring-boot-starter
1.30.0
implementation 'cn.dev33:sa-token-spring-boot-starter:1.30.0'

4.2 SpringBoot Integration Example

@SpringBootApplication
public class SaTokenDemoApplication {
    public static void main(String[] args) throws JsonProcessingException {
        SpringApplication.run(SaTokenDemoApplication.class, args);
        System.out.println("启动成功:Sa-Token配置如下:" + SaManager.getConfig());
    }
}
@RestController
@RequestMapping("/user/")
public class UserController {
    @RequestMapping("doLogin")
    public String doLogin(String username, String password) {
        if ("zhang".equals(username) && "123456".equals(password)) {
            StpUtil.login(10001);
            return "登录成功";
        }
        return "登录失败";
    }
    @RequestMapping("isLogin")
    public String isLogin() {
        return "当前会话是否登录:" + StpUtil.isLogin();
    }
}

4.3 WebFlux Integration Example

@Configuration
public class SaTokenConfigure {
    @Bean
    public SaReactorFilter getSaReactorFilter() {
        return new SaReactorFilter()
            .addInclude("/**")
            .addExclude("/favicon.ico")
            .setAuth(obj -> System.out.println("---------- sa全局认证"))
            .setError(e -> {
                System.out.println("---------- sa全局异常 ");
                return SaResult.error(e.getMessage());
            });
    }
}
@RestController
@RequestMapping("/user/")
public class UserController {
    @RequestMapping("doLogin")
    public String doLogin(String username, String password) {
        if ("zhang".equals(username) && "123456".equals(password)) {
            StpUtil.login(10001);
            return "登录成功";
        }
        return "登录失败";
    }
    @RequestMapping("isLogin")
    public String isLogin() {
        return "当前会话是否登录:" + StpUtil.isLogin();
    }
}

5. Conclusion

Sa‑Token is a lightweight, easy‑to‑integrate Java authentication and authorization framework that simplifies login, permission checks, session management, and provides extensive features for modern backend systems.

JavapermissionsecurityAuthenticationSpringBootauthorizationSa-Token
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

login 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.