如何基于用户的角色实现对Spring控制器API的访问限制,并将消息发送回用户?

gev0vcfq  于 2024-01-05  发布在  Spring
关注(0)|答案(1)|浏览(193)

我已经实现了一个DataTable配置,每行都有一个删除按钮。然而,删除按钮的功能仅限于具有特定角色的用户,例如“ADMIN”。没有“ADMIN”或“EDITOR”角色的用户在尝试使用删除按钮时会遇到一个提示,通知他们未经授权的访问。
这是一个按钮,它被呈现在我的DataTable列中:

  1. <form style="display:inline !important;" action="/admin/delete/" method="post" onsubmit="return confirm('Do you really want to delete employee ${row.id} ?');">
  2. <input type="hidden" name="id" value="${row.id}" />
  3. <button class="form-command btn btn-danger btn-sm" type="submit"><i class="fa fa-trash-o"></i></button>
  4. </form>`;

字符串
这是控制器类中的删除API:

  1. @PreAuthorize("hasRole({'ROLE_ADMIN', 'ROLE_EDITOR'})")
  2. @DeleteMapping("delete")
  3. @ResponseStatus(HttpStatus.OK)
  4. void delete(@RequestBody Integer id) {
  5. deleteEntity(id);
  6. }


@PreAuthorize注解应该检查经过身份验证的用户的角色,如果他们没有被授权,则拒绝他们。事情是这样的,我想向前端用户发送一条消息,告诉他们他们没有删除行的权限。

  1. $(document).ready(function () {
  2. $('#tableID').DataTable({
  3. "processing": true,
  4. "serverSide": true,
  5. "ajax": {
  6. "url": "api-endpoint",
  7. "type": "POST",
  8. 'beforeSend': function (xhr) {
  9. xhr.setRequestHeader(csrfHeader, csrfToken);
  10. },
  11. 'data': function (d) {
  12. d.search.value = d.search.value || '';
  13. d.columns[2]['search']['value'] = d.columns[2]['search']['value'] || '';
  14. d.columns[3]['search']['value'] = d.columns[3]['search']['value'] || '';
  15. d.columns[4]['search']['value'] = d.columns[4]['search']['value'] || '';
  16. },
  17. },
  18. "columns": [
  19. // ... (other columns remain unchanged)
  20. {
  21. "data": null,
  22. "render": function (data, type, row) {
  23. let dropdownMenu = ``;
  24. let deleteForm = `
  25. <form style="display:inline !important;" action="/admin/delete/" method="post" onsubmit="return confirm('Do you really want to delete employee ${row.id} ?');">
  26. <input type="hidden" name="id" value="${row.id}" />
  27. <button class="form-command btn btn-danger btn-sm" type="submit"><i class="fa fa-trash-o"></i></button>
  28. </form>`;
  29. return dropdownMenu + "<br/>" + deleteForm;
  30. },
  31. "orderable": false
  32. }
  33. ],
  34. initComplete: function () {
  35. // ... (unchanged)
  36. }
  37. });
  38. });


我如何才能做到这一点?

yyyllmsg

yyyllmsg1#

你可以通过实现一个GlobalExceptionHandler来完成这个任务。下面是一个示例代码片段:

  1. @ControllerAdvice
  2. public class GlobalExceptionHandler {
  3. @ExceptionHandler(AccessDeniedException.class)
  4. public ResponseEntity<ProblemDetail> handleAccessDeniedException(AccessDeniedException e) {
  5. ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.UNAUTHORIZED, e.getMessage());
  6. problemDetail.setTitle("Requested Resource is UNAUTHORIZED");
  7. return new ResponseEntity<>(problemDetail, HttpStatus.UNAUTHORIZED);
  8. }
  9. }

字符串
这段代码使用@ControllerAdvice annotation定义了一个GlobalExceptionHandler。它包括一个使用@ExceptionHandler annotation的AccessDeniedException的特定异常处理方法。该方法构造了一个ProblemDetail对象,其中包含有关未授权访问的详细信息,并在一个ResponseEntity中返回它,状态为401 (UNAUTHORIZED)
此代码生成的响应类似于以下JSON结构:

  1. {
  2. "type": "about:blank",
  3. "title": "Requested Resource is UNAUTHORIZED",
  4. "status": 401,
  5. "detail": "Access Denied",
  6. "instance": "/api/secured"
  7. }

展开查看全部

相关问题