權限控制是企業級應用核心模塊。本文基於 RBAC(基於角色的訪問控制)模型,系統講解 Java Web 中用戶權限管理的數據庫設計、核心實體、權限檢查機制及主流框架整合方案。
-- 用戶表
CREATE TABLE sys_user (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(100) NOT NULL,
salt VARCHAR(20),
status TINYINT DEFAULT 1,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 角色表
CREATE TABLE sys_role (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
code VARCHAR(50) NOT NULL UNIQUE, -- 如 ROLE_ADMIN
description VARCHAR(200)
);
-- 權限/資源表
CREATE TABLE sys_permission (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
url VARCHAR(200), -- 菜單/按鈕/接口路徑
perms VARCHAR(100), -- 權限標識 user:add
type TINYINT, -- 0目錄 1菜單 2按鈕
parent_id BIGINT DEFAULT 0,
sort INT DEFAULT 0
);
-- 用戶-角色關聯
CREATE TABLE sys_user_role (
user_id BIGINT NOT NULL,
role_id BIGINT NOT NULL,
PRIMARY KEY (user_id, role_id)
);
-- 角色-權限關聯
CREATE TABLE sys_role_permission (
role_id BIGINT NOT NULL,
permission_id BIGINT NOT NULL,
PRIMARY KEY (role_id, permission_id)
);
@Data
public class SysUser {
private Long id;
private String username;
private String password;
private Set<SysRole> roles; // 關聯角色
}
@Data
public class SysRole {
private Long id;
private String code; // ROLE_ADMIN
private Set<SysPermission> permissions; // 關聯權限
}
@Data
public class SysPermission {
private Long id;
private String perms; // user:add
private String url; // /user/add
}
roles 和 permissions 存入緩存| 方式 | 適用場景 | 實現關鍵 |
|---|---|---|
| URL 過濾器 | 粗粒度接口保護 | FilterChainProxy + FilterInvocationSecurityMetadataSource |
| 方法註解 | 細粒度業務邏輯 | @PreAuthorize("hasAuthority('user:add')") |
| 標籤/前端控制 | 頁面元素顯隱 | Thymeleaf sec:authorize / Vue 指令 v-hasPermi |
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired UserDetailsService userDetailsService;
@Autowired PasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login", "/css/**", "/js/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().permitAll();
}
}
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired SysUserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) {
SysUser user = userMapper.selectByUsername(username);
if (user == null) throw new UsernameNotFoundException("用戶不存在");
List<GrantedAuthority> authorities = user.getRoles().stream()
.flatMap(role -> role.getPermissions().stream()
.map(perm -> new SimpleGrantedAuthority(perm.getPerms())))
.collect(Collectors.toList());
return new User(user.getUsername(), user.getPassword(), authorities);
}
}
@Service
public class UserService {
@PreAuthorize("hasAuthority('user:add')")
public void addUser(UserDTO dto) { ... }
@PreAuthorize("hasRole('ADMIN') or #id == authentication.principal.id")
public void deleteUser(Long id) { ... }
}
若項目不需 Spring Security 複雜功能,Apache Shiro 更輕量:
[urls]
/login = anon
/user/** = authc, perms[user:view]
/admin/** = authc, roles[ADMIN]
// Realm 授權
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(userRoles);
info.addStringPermissions(userPerms);
return info;
}
// Vue Router
router.beforeEach((to, from, next) => {
const perms = store.getters.permissions; // ['user:add', 'user:edit']
if (to.meta.perms && !perms.includes(to.meta.perms)) {
next({ path: '/403' });
} else next();
});
// directives/hasPermi.js
export default {
mounted(el, binding) {
const perms = store.getters.permissions;
if (!perms.includes(binding.value)) el.parentNode?.removeChild(el);
}
}
// 使用
<button v-hasPermi="'user:add'">新增</button>
userId → Set<String> permissions,登錄時加載,變更時失效router.addRoutes 動態註冊DataPermissionHandler 自動拼接 dept_id IN (...)@OperLog("刪除用戶")Java Web 權限管理核心在於「用戶-角色-權限」三層映射與多層次攔截。推薦「Spring Security + JWT + Redis 緩存 + 前端指令」組合,兼顧安全性、性能與開發體驗。數據權限、審計日誌作為增強模塊按需接入。