代码之家  ›  专栏  ›  技术社区  ›  jannis Anjali

后授权Spring异步控制器响应

  •  0
  • jannis Anjali  · 技术社区  · 9 年前

    owner 上的字段 Resource

    @RestController
    @RequestMapping("/api")
    public class AController {
    
        private final AService aService;
    
        public AController(AService aService) {
            this.aService = aService;
        }
    
        @GetMapping("/resources/{id}")
        @PostAuthorize("returnObject.ownerLogin == authentication.name")
        public Resource getResource(@PathVariable Long id) {
            return aService.getResource(id);
        }
    }
    

    但是,如果控制器方法是异步的(使用 DeferredResult )?

    @RestController
    @RequestMapping("/api")
    public class AController {
    
        private final AService aService;
    
        public AController(AService aService) {
            this.aService = aService;
        }
    
        @GetMapping("/resources/{id}")
        @PostAuthorize("returnObject.ownerLogin == authentication.name")
        public DeferredResult<Resource> getResource(@PathVariable Long id) {
            DeferredResult<Resource> deferredResult = new DeferredResult<>();
    
            aService
                .getResourceAsync(id)
                .thenAccept(resource -> {
                    deferredResult.setResult(resource);
                });
    
            return deferredResult;
        }
    }
    

    AService 界面如下所示:

    @Service
    public class AService {
    
        @Async
        public CompletableFuture<Resource> getResourceAsync(Long id) {
            // implementation...
        }
    
        public Resource getResource(Long id) {
            // implementation...
        }
    }
    

    类是一个简单的DTO:

    public class Resource {
    
        private String ownerLogin;
    
        // other fields, getters, setters
    
    }
    

    在第二个示例中,Spring Security显然在寻找 ownerLogin 例子我希望它处理异步解析的 作为 returnObject 在 @PostAuthorize

    有可能吗?也许有人可以建议另一种方法?欢迎提出任何建议。

    1 回复  |  直到 9 年前
        1
  •  0
  •   jannis Anjali    9 年前

    无法实现我的目标 PostAuthorize

    Resource 的子资源 User PreAuthorize 验证用户登录的注释。

    @RestController
    @RequestMapping("/api")
    public class AController {
    
        private final AService aService;
    
        public AController(AService aService) {
            this.aService = aService;
        }
    
        @GetMapping("/users/{login:" + Constants.LOGIN_REGEX + "}/resources/{id}")
        @PreAuthorize("#login == authentication.name")
        public DeferredResult<Resource> getResource(@PathVariable String login, @PathVariable Long id) {
            DeferredResult<Resource> deferredResult = new DeferredResult<>();
    
            aService
                .getResourceAsync(login, id)
                .thenAccept(resource -> {
                    deferredResult.setResult(resource);
                });
    
            return deferredResult;
        }
    }
    

    添加了所有权签入 AService 如果 资源 所有者和请求用户的登录名不匹配引发异常,该异常解析为 404 HTTP状态:

    @Service
    public class AService {
    
        private final ARepository aRepository;
    
        public AController(ARepository aRepository) {
            this.aRepository = aRepository;
        }
    
        @Async
        public CompletableFuture<Resource> getResourceAsync(String owner, Long id) {
            Resource resource = aRepository.getResource(id);
    
            if (!resource.owner.equals(owner)) {
                // resolves to 404 response code
                throw ResourceNotFounException();
            }
    
            return resource;
        }
    }
    
    推荐文章