Authentication (Sa-Token)
ArchForge authenticates with Sa-Token 1.45.0, not JWT and not Spring Security.
Two independent login types share Redis-backed sessions:
| App | Util | Sa-Token type | Port |
|---|---|---|---|
| Admin | StpAdminUtil | "admin" | :8080 |
| C-end web | StpWebUtil | "web" | :8081 |
Login Flow (admin)
┌──────────┐ ┌──────────────┐ ┌──────────┐
│ Frontend │ │ LoginController│ │ TokenService│
└────┬─────┘ └──────┬───────┘ └────┬─────┘
│ POST /auth/login │ │
│ {username, password, code} │ │
├──────────────────────────────►│ │
│ │ Verify captcha │
│ │ Decrypt RSA password │
│ │ BCrypt verify │
│ │ StpAdminUtil.login(userId) │
│ │ │
│ {accessToken, refreshToken, │ │
│ expires, roles, perms} │ │
│◄──────────────────────────────┤ │
│ │ │
│ Subsequent requests: │ │
│ Authorization: Bearer <token>│ │
└──────────────────────────────►│ │Login is rate-limited: @RateLimit(key = "login", time = 60, maxCount = 5, limitType = IP) — 5 requests per minute per IP.
Token Management
Sa-Token issues a UUID access token (token-style: uuid). It is not a signed JWT.
Access Token
- Created by
StpAdminUtil.login(userId)/StpWebUtil.login(userId) - Stored in Sa-Token session (Redis)
- Sent as
Authorization: Bearer <token> - Default TTL: 7 days (
sa-token.timeout: 604800)
Refresh Token (admin)
- Endpoint:
POST /auth/refresh-token - Random UUID stored in Redis, mapped to user id
- Returns a new Sa-Token access token plus a new refresh token
Configuration
sa-token:
token-name: Authorization
token-prefix: Bearer
timeout: 604800
active-timeout: -1
is-concurrent: true
is-share: false
is-read-cookie: false
token-style: uuid
is-log: false
is-print: falseProduction secrets have no defaults. Set Redis, datasource passwords, RSA keys, and related env vars yourself. Do not ship empty prod credentials.
Authorization
Controllers use Sa-Token annotations with an explicit type:
@SaCheckLogin(type = StpAdminUtil.TYPE)
@SaCheckPermission(value = "system:user:add", type = StpAdminUtil.TYPE)
@PostMapping
public void addUser(...) { }Permission strings come from sys_menu.permission, for example system:user:add, system:role:query, monitor:job:list.
Current admin user:
SystemLoginUser loginUser = LoginContext.getAdminUser();Password Encryption
Two layers still apply:
- RSA — frontend encrypts the password with the server public key; backend decrypts with
arch-forge.rsa-private-key - BCrypt — stored hash in the database
Public Endpoints (admin)
Typically unauthenticated:
POST /auth/loginGET /auth/captchaImageGET /auth/getConfigGET /actuator/**(profile-dependent)GET /swagger-ui/**andGET /v3/api-docs/**(disabled in prod)
Captcha
arch-forge:
captcha:
enabled: true
captcha-type: math # "math" or "text"Images are generated with Kaptcha and stored temporarily in Redis.
Login Response (admin)
Admin JSON is wrapped as {code, message, data}. The data payload looks like:
{
"accessToken": "xxxxxxxx-uuid-style-token",
"refreshToken": "hex-without-dashes",
"expires": "2025/01/14 00:00:00",
"username": "admin",
"roles": ["admin"],
"permissions": ["*:*:*"]
}C-end (archforge-server-web) errors use RFC 9457 ProblemDetail instead of that envelope.
XSS Filter
XssFilter sanitizes query parameters and headers. It skips multipart/*, application/octet-stream, application/pdf, and image/*. JSON bodies still need controller-level validation.
API Request Signing
For sensitive endpoints or third-party integrations, use @ApiSign. The interceptor validates:
| Header | Description |
|---|---|
X-App-Key | Application identifier |
X-Timestamp | Request timestamp in milliseconds |
X-Nonce | One-time random string (replay protection) |
X-Sign | HMAC-SHA256 signature in lowercase hex |
HMAC-SHA256(appSecret, appKey + timestamp + nonce + body)arch-forge:
security:
sign:
enabled: true
timeoutSeconds: 300
nonceTtlSeconds: 600
apps:
test-app: test-secretIdempotent Token
@Idempotent prevents duplicate submissions:
- PARAM: Redis SETNX lock keyed by method signature + parameter hash
- TOKEN: client fetches
GET /idempotent/tokenand sendsX-Idempotent-Token - HEADER: lock based on a specified request header
Related Pages
- User Management — user account management
- Role & Permission — roles, permissions, and data scopes
- Configuration — Sa-Token, captcha, signing, and idempotent settings
- Menu Management — async route loading after login
- C-end Web —
StpWebUtilon:8081