Code getway

package com.galaxy.pltgateway.config;

import com.galaxy.pltgateway.validator.ReportSecurityValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER)
                .and()
                .authorizeRequests()
                .anyRequest()
                .permitAll();

    }

    @Bean
    public ReportSecurityValidator reportSecurityValidator() {
        return new ReportSecurityValidator();
    }

}
package com.galaxy.pltgateway.controller.basics.v1;

import com.galaxy.module.resp.SuccessResp;
import com.galaxy.pltgateway.controller.BaseController;
import com.galaxy.pltgateway.domain.basics.ReportManageDomainService;
import com.galaxy.pltgateway.enumeration.basics.ReportType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@RestController
@RequestMapping("/v1/report")
@Tag(name = "報表", description = "報表API")
public class ReportManageController extends BaseController {
    private final ReportManageDomainService reportManageDomainService;

    public ReportManageController(HttpServletRequest request,
                                  ReportManageDomainService reportManageDomainService) {
        super(request);
        this.reportManageDomainService = reportManageDomainService;
    }

    @PreAuthorize("@reportSecurityValidator.hasAuthority(#reportType)")
    @Operation(summary = "報表製作,必須傳入報表類型(ReportType)")
    @Parameter(name = "reportType", description = "報表類型 ")
    @GetMapping
    public SuccessResp<Void> startingMakeReport(@RequestParam("reportType") ReportType reportType,
                                                @RequestParam Map<String, String> searchParam) {
        reportManageDomainService.startingWorkReport(searchParam);
        return new SuccessResp<>();
    }

    @PreAuthorize("@reportSecurityValidator.hasAuthority(#reportType)")
    @Operation(summary = "報表製作,必須傳入報表類型(ReportType)")
    @Parameter(name = "reportType", description = "報表類型")
    @Parameter(name = "id", description = "報表id")
    @GetMapping("/download")
    public ResponseEntity<InputStreamResource> download(@RequestParam("reportType") ReportType reportType,
                                                        @RequestParam("id") Long id) {
        return reportManageDomainService.makeDownloadFile(reportType, id);
    }

}

package com.galaxy.pltgateway.domain.basics.impl;

import com.galaxy.pltgateway.domain.basics.ReportManageDomainService;
import com.galaxy.pltgateway.enumeration.basics.ReportType;
import com.galaxy.pltgateway.feign.client.basics.BasicsFeignClient;
import com.galaxy.pltgateway.model.basics.vo.ReportDocumentVo;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class ReportManageDomainServiceImpl implements ReportManageDomainService {
    private final BasicsFeignClient basicsFeignClient;

    @Override
    public void startingWorkReport(Map<String, String> searchParam) {
        basicsFeignClient.createReportRecord(searchParam);
    }

    @Override
    public ResponseEntity<InputStreamResource> makeDownloadFile(ReportType reportType, Long id) {

        ReportDocumentVo docVo = basicsFeignClient.getDocument(reportType, id).getData();

        String filename = reportType.name() + "." + docVo.getFileSuffix();
        String mimeType = "application/" + docVo.getFileSuffix();
        InputStreamResource file = new InputStreamResource(new ByteArrayInputStream(docVo.getBytes()));
        return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename)
                .contentType(MediaType.parseMediaType(mimeType)).body(file);
    }
}

package com.galaxy.pltgateway.domain.basics;

import com.galaxy.pltgateway.enumeration.basics.ReportType;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;

import java.util.Map;

public interface ReportManageDomainService {

    void startingWorkReport(Map<String, String> searchParam);

    ResponseEntity<InputStreamResource> makeDownloadFile(ReportType reportType, Long id);
}

package com.galaxy.pltgateway.enumeration.basics;

import lombok.AllArgsConstructor;
import lombok.Getter;


@Getter
@AllArgsConstructor
public enum ReportType {
    // FIXME authority data
    PROXY("proxy:domain:edit"), // 代理列表
    PROXY_DOMAIN("proxy:proxy:editCommission") // 代理域名
    ;
    private final String authority; // 定義在 plt_account.vs_authority.authority

}

package com.galaxy.pltgateway.feign.client.basics;

import com.galaxy.module.resp.SuccessResp;
import com.galaxy.pltgateway.config.FeignSupportConfig;
import com.galaxy.pltgateway.enumeration.basics.ReportType;
import com.galaxy.pltgateway.feign.interceptor.InternalFeignInterceptor;
import com.galaxy.pltgateway.model.basics.dto.AvatarCreateDto;
import com.galaxy.pltgateway.model.basics.dto.AvatarQryDto;
import com.galaxy.pltgateway.model.basics.dto.AvatarUpdateDto;
import com.galaxy.pltgateway.model.basics.vo.AvatarVo;
import com.galaxy.pltgateway.model.basics.vo.PlatformCurrencyVo;
import com.galaxy.pltgateway.model.basics.vo.ReportDocumentVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import java.util.List;
import java.util.Map;

@FeignClient(contextId = "plt-basics", name = "plt-basics", url = "${feign.client.plt-basics.url}", configuration = {InternalFeignInterceptor.class, FeignSupportConfig.class})
public interface BasicsFeignClient {

    @PostMapping(path = "/v1/file/image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    SuccessResp<String> uploadImage(@RequestPart(value = "file") MultipartFile file, @RequestParam("imagePathType") Integer imagePathType);

    @PostMapping(path = "/v1/file/video", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    SuccessResp<String> uploadVideo(@RequestPart(value = "file") MultipartFile file, @RequestParam("videoPathType") Integer videoPathType);

    @PostMapping("/v1/config/avatar")
    SuccessResp<Void> insertAvatar(@RequestBody @Valid AvatarCreateDto dto);

    @PutMapping("/v1/config/avatar")
    SuccessResp<Void> updateAvatar(@RequestBody @Valid AvatarUpdateDto dto);

    @DeleteMapping("/v1/config/avatar/{id}")
    SuccessResp<Void> deleteAvatar(@Positive @NotNull @PathVariable("id") Long id);

    @GetMapping("/v1/config/avatars")
    SuccessResp<List<AvatarVo>> qryAvatarByFields(@SpringQueryMap @Valid AvatarQryDto dto);

    @GetMapping("/v1/config/avatar/{id}")
    SuccessResp<AvatarVo> qryAvatarById(@Positive @NotNull @PathVariable("id") Long id);

    @GetMapping("/v1/platform/currency")
    SuccessResp<List<PlatformCurrencyVo>> getPlatformCurrencyList();

    @PostMapping("/v1/report")
    SuccessResp<Void> createReportRecord(@RequestBody Map<String, String> dto);

    @GetMapping(value = "/v1/report/download", consumes = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
    SuccessResp<ReportDocumentVo> getDocument(@RequestParam ReportType reportType, @NotNull @RequestParam Long id);

}

package com.galaxy.pltgateway.model.basics.vo;

import lombok.Data;

import javax.validation.constraints.NotNull;

@Data
public class ReportDocumentVo {
    @NotNull
    private Long id;
    @NotNull
    private byte[] bytes;
    @NotNull
    private String fileSuffix;


}

package com.galaxy.pltgateway.validator;

import com.galaxy.pltgateway.enumeration.basics.ReportType;
import com.galaxy.pltgateway.security.details.AccountDetail;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.Collection;
import java.util.Objects;


@Slf4j
@AllArgsConstructor
public class ReportSecurityValidator {

    public boolean hasAuthority(@NonNull ReportType reportType) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (Objects.isNull(authentication)) return false;

        Object principal = authentication.getPrincipal();
        if (Objects.isNull(principal)) return false;

        Collection<GrantedAuthority> authorities = ((AccountDetail) principal).getAuthorities();
        if (Objects.isNull(authorities)) return false;

        String checkAuthority = reportType.getAuthority();

        return authorities.stream()
                .map(GrantedAuthority::getAuthority)
                .anyMatch(auth -> auth.equals(checkAuthority));

    }

}