如何实现Spring Controller API角色权限限制并返回前端权限提示?
问题需求
已实现每行带删除按钮的DataTable,后端通过@PreAuthorize("hasRole({'ROLE_ADMIN', 'ROLE_EDITOR'})")校验角色,仅管理员和编辑可执行删除。需要在前端给无权限用户操作删除按钮时,显示权限不足的提示。
方案一:前端预判断用户角色(推荐,减少无效请求)
核心思路:页面渲染时从后端获取当前用户角色,在DataTable渲染删除按钮时,根据角色决定显示正常按钮还是无权限提示/禁用按钮。
步骤1:页面传入用户角色
后端渲染页面时,将当前用户角色存入全局变量或隐藏域:
<!-- 隐藏域方式 --> <input type="hidden" id="currentUserRole" value="${currentUser.authorities[0].authority}"> <!-- 或全局JS变量 --> <script> const CURRENT_USER_ROLE = "${currentUser.authorities[0].authority}"; </script>
步骤2:修改DataTable的渲染逻辑
在columns的render函数中判断角色,动态生成删除按钮:
"render": function (data, type, row) { let dropdownMenu = ``; let deleteBtn = ``; // 判断是否拥有删除权限 const canDelete = CURRENT_USER_ROLE === 'ROLE_ADMIN' || CURRENT_USER_ROLE === 'ROLE_EDITOR'; if (canDelete) { // 有权限:显示正常删除表单 deleteBtn = ` <form style="display:inline !important;" action="/admin/delete/" method="post" onsubmit="return confirm('确定要删除员工 ${row.id} 吗?');"> <input type="hidden" name="id" value="${row.id}" /> <button class="form-command btn btn-danger btn-sm" type="submit"><i class="fa fa-trash-o"></i></button> </form>`; } else { // 无权限:显示禁用按钮,点击弹提示 deleteBtn = ` <button class="form-command btn btn-danger btn-sm disabled" onclick="alert('权限不足,无法执行删除操作');"> <i class="fa fa-trash-o"></i> </button>`; } return dropdownMenu + "<br/>" + deleteBtn; }
方案二:异步校验权限后提交(适合角色动态变化场景)
核心思路:点击删除按钮时,先调用后端权限校验接口,确认有权限再执行删除,避免页面暴露角色信息。
步骤1:后端新增权限校验接口
@GetMapping("/admin/check-delete-permission") @ResponseBody public boolean checkDeletePermission() { // 借助Spring Security自动校验当前用户角色 Authentication auth = SecurityContextHolder.getContext().getAuthentication(); return auth.getAuthorities().stream() .anyMatch(grantedAuth -> grantedAuth.getAuthority().equals("ROLE_ADMIN") || grantedAuth.getAuthority().equals("ROLE_EDITOR")); }
步骤2:前端修改删除逻辑
将表单提交改为异步校验后再执行:
// 权限校验函数 async function validateDeletePermission() { try { const response = await fetch('/admin/check-delete-permission', { method: 'GET', headers: { [csrfHeader]: csrfToken } }); return await response.json(); } catch (err) { console.error('权限校验失败:', err); return false; } } // 处理删除提交 async function handleDelete(event, userId) { event.preventDefault(); // 阻止默认表单提交 if (!confirm(`确定要删除员工 ${userId} 吗?`)) return; const hasPermission = await validateDeletePermission(); if (!hasPermission) { alert('权限不足,无法执行删除操作'); return; } // 有权限则手动提交表单 event.target.submit(); } // 修改DataTable的render函数 "render": function (data, type, row) { let dropdownMenu = ``; const deleteForm = ` <form style="display:inline !important;" action="/admin/delete/" method="post" onsubmit="return handleDelete(event, ${row.id});"> <input type="hidden" name="id" value="${row.id}" /> <button class="form-command btn btn-danger btn-sm" type="submit"><i class="fa fa-trash-o"></i></button> </form>`; return dropdownMenu + "<br/>" + deleteForm; }
方案三:拦截后端权限错误提示(兼容现有逻辑)
核心思路:将删除请求改为AJAX提交,全局拦截后端返回的403状态码,统一弹出权限提示。
步骤1:修改前端删除为AJAX请求
// 删除操作函数 function deleteEmployee(userId) { if (!confirm(`确定要删除员工 ${userId} 吗?`)) return; $.ajax({ url: '/admin/delete/', type: 'DELETE', contentType: 'application/json', headers: { [csrfHeader]: csrfToken }, data: JSON.stringify(userId), success: function() { // 删除成功后刷新DataTable $('#tableID').DataTable().ajax.reload(); }, error: function(xhr) { if (xhr.status === 403) { alert('权限不足,无法执行删除操作'); } else { alert('删除失败,请稍后重试'); } } }); } // 修改DataTable的render函数 "render": function (data, type, row) { let dropdownMenu = ``; const deleteBtn = ` <button class="form-command btn btn-danger btn-sm" onclick="deleteEmployee(${row.id});"> <i class="fa fa-trash-o"></i> </button>`; return dropdownMenu + "<br/>" + deleteBtn; }
说明
后端@DeleteMapping保持原有逻辑即可,Spring Security在权限不足时会自动返回403状态码,前端通过AJAX的error回调捕获并提示。
内容的提问来源于stack exchange,提问作者Jaiylon
相关产品推荐
相关产品推荐

