ソフトウェアエンジニアの日常の雑記

日々思ったことをまとめます

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

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>

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

aws escのecs_params.yml の設定

本家はこちら

AWS ECS のタスク定義で使うもの。(docker-composeの形式ではサポートしていないものが多いので)

下記を定義しておく。

version: 1
task_definition:
  ecs_network_mode: string
  task_role_arn: string
  task_execution_role: string
  task_size:
    cpu_limit: string
    mem_limit: string
  services:
    <service_name>:
      essential: boolean
      cpu_shares: integer
      mem_limit: string
      mem_reservation: string
      healthcheck:
        test: ["CMD", "curl -f http://localhost"]
        interval: string
        timeout: string
        retries: integer
        start_period: string 
run_params:
  network_configuration:
    awsvpc_configuration:
      subnets: 
        - subnet_id1 
        - subnet_id2
      security_groups: 
        - secgroup_id1
        - secgroup_id2
      assign_public_ip: ENABLED

下記のような感じでファイルを指定すれば読み込んでくれる

$ ecs-cli --ecs-params ${ecs_params.yml} 

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>

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

AWS fargateで Task failed ELB health checks in (elb elb-name) がでた際には...

本家はこちら

自分が携わってるサービスではaws fargateでデフォルトで設定してると発生する。 そのときの、対策メモ

fargateのスピンアップは遅い(自分のアプリでは)

fargateはコンテナの起動後から、すぐにELBが負荷分散のチェックが入るようで、デフォルトの設定だとすぐにタイムアウトして、Task failed ELB health checks in (elb elb-name)これを投げる。なんか、AWSでよくあるセキュリティグループとかの設定がー...とか思うんだけど、一番よくあるのは、このケース。 fargateの設定の中に、ヘルスチェックの猶予期間があるけど、これはデフォルトで120秒くらいにはしておこうと思う... ターゲットグループの方でチェックしてもいいけど、アプリ切り替えとかしたときに、そっちの設定変更するときとか大変だし。

アベイラビリティゾーンの設定が...

よくプライベートセグメントとパブリックセグメントでわけてたりするんですけど、設定間違ってパブリックにしたりしてて、ELBが期待してるセグメントと違うことがあった。

他にもあったら追記します

AWS fargateで Task failed ELB health checks in (elb elb-name) がでた際には...

本家はこちら

自分が携わってるサービスではaws fargateでデフォルトで設定してると発生する。 そのときの、対策メモ

fargateのスピンアップは遅い(自分のアプリでは)

fargateはコンテナの起動後から、すぐにELBが負荷分散のチェックが入るようで、デフォルトの設定だとすぐにタイムアウトして、Task failed ELB health checks in (elb elb-name)これを投げる。なんか、AWSでよくあるセキュリティグループとかの設定がー...とか思うんだけど、一番よくあるのは、このケース。 fargateの設定の中に、ヘルスチェックの猶予期間があるけど、これはデフォルトで120秒くらいにはしておこうと思う... ターゲットグループの方でチェックしてもいいけど、アプリ切り替えとかしたときに、そっちの設定変更するときとか大変だし。

アベイラビリティゾーンの設定が...

よくプライベートセグメントとパブリックセグメントでわけてたりするんですけど、設定間違ってパブリックにしたりしてて、ELBが期待してるセグメントと違うことがあった。

他にもあったら追記します