SpringReactive(webflux)でAOPする際に@EnableReactiveMethodSecurityの@hasAuthoritiesを使うとうまくいかないのを回避する

下記のようにcontrollerでのリクエストのログを認証情報付きで出力しようとする。

    @AfterReturning(value = "execution(* xxx.xxx.controller..*.*(..))")
    public void execNormalControllerMethod(JoinPoint jp) {
            /// ログ出力処理
    }

しかし、下記のように、@PreAuthorizeするとエラーになる。

@RestController
@RequestMapping("sample")
public class SampleController {
       @RequestMapping
       @PreAuthorize("hasAuthority('ADMIN_ROLE')")
        public Mono index(@AuthenticationPrincipal UserDetails useDetails) {
             return Mono.empty();
        }
}

エラーは下記

No MethodInvocation found: Check that an AOP invocation is in progress, and that the ExposeInvocationInterceptor is upfront in the interceptor chain. Specifically, note that advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor!

下記にて対処可能
@EnableReactiveMethodSecurityのOrderを最上位にすれば動作する

@EnableReactiveMethodSecurity(order = Ordered.HIGHEST_PRECEDENCE)

以上、設定して再起動すればOK

spring webfluxでfile upload

SpringBoot webfluxでは、ファイルアップロードはMultiPartで取得できないので、探す。
PartFileというのがよかったでこちらで実験する。

ソースはこちら

Javaはこちら

package net.ksasaki.springboot.example.controller;

import org.springframework.http.MediaType;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import reactor.core.publisher.Mono;

import java.io.File;

@Controller
@RequestMapping("")
public class SampleController {

    @RequestMapping("")
    public String index() {
        return "index";
    }

    @ResponseBody
    @PostMapping(value = "/form", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Mono form(@RequestPart("part") FilePart part) {

        File file = new File(part.filename());
        part.transferTo(file);

        return Mono.empty();
    }
}

HTMLはこちら

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="/form" enctype="multipart/form-data" method="post">
    <input type="file" name="parts">
    <button type="submit">送信</button>
</form>
</body>
</html>

無事取得できたので、メモ。