Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
后授权Spring异步控制器响应_Spring_Asynchronous_Spring Security_Spring Web_Deferred Result - Fatal编程技术网

后授权Spring异步控制器响应

后授权Spring异步控制器响应,spring,asynchronous,spring-security,spring-web,deferred-result,Spring,Asynchronous,Spring Security,Spring Web,Deferred Result,我有一个带有GET方法的REST控制器。它返回一个资源。我想通过比较资源上的所有者字段与授权用户的登录名来验证资源是否属于授权用户。对于正常的同步请求,我会执行以下操作: @RestController @RequestMapping("/api") public class AController { private final AService aService; public AController(AService aService) { this.a

我有一个带有GET方法的REST控制器。它返回一个资源。我想通过比较
资源
上的
所有者
字段与授权用户的登录名来验证资源是否属于授权用户。对于正常的同步请求,我会执行以下操作:

@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);
    }
}
@Service
public class AService {

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

    public Resource getResource(Long id) {
        // implementation...
    }
}
但是,如果控制器方法是异步的(使用
DeferredResult
实现),该怎么办

Resource
类是一个简单的DTO:

public class Resource {

    private String ownerLogin;

    // other fields, getters, setters

}
在第二个示例中,Spring Security在
DeferredResult
实例上查找
ownerLogin
字段。我希望它将异步解析的
资源
视为
@PostAuthorize
SPEL表达式中的
返回对象


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

无法通过
后授权来实现我的目标,并完成以下操作:

使
资源
成为
用户
资源的子资源。使用
预授权
批注验证用户登录

@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;
    }
}
@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;
    }
}
@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;
    }
}