0

私はGETメソッドを持つRESTコントローラを持っています。リソースを返します。 Resourceownerフィールドを許可されたユーザーのログインと比較することによって、リソースが許可ユーザーに属しているかどうかを確認したいと思います。通常の同期要求で、私はこのような何かをしたい:投稿を承認するSpring非同期コントローラの応答

@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で実装)何? AServiceインターフェースは次のようになります

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

は:春のセキュリティはobiously上ownerLoginフィールドを探します2番目の例では

public class Resource { 

    private String ownerLogin; 

    // other fields, getters, setters 

} 

@Service 
public class AService { 

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

    public Resource getResource(Long id) { 
     // implementation... 
    } 
} 

そしてResourceクラスは、単純なDTOですDeferredResultインスタンス。私は@PostAuthorizeのSPEL式の中でResourcereturnObjectとして非同期的に解決したいと思っています。

可能ですか?たぶん誰かがalternatveのアプローチを提案できますか?どんな提案も大歓迎です。

答えて

0

PostAuthorizeと私の目標を達成し、次やってendeddませんでした:ResourceUserリソースのサブリソースを

を作りました。 PreAuthorizeアノテーションを使用してユーザーのログインを検証しました。

@RestController 
@RequestMapping("/api") 
public class AController { 

    private final AService aService; 

    public AController(AService aService) { 
     this.aService = aService; 
    } 

    @GetMapping("https://stackoverflow.com/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に所有権チェックを追加しました。 Resourceオーナーとリクエストしているユーザーのログインが一致しない場合、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; 
    } 
} 
関連する問題