簡體   English   中英

Spring 啟動請求 Header 驗證

[英]Spring Boot Request Header Validation

我正在使用 Spring Boot 2.3.8 創建 rest 服務。 我需要驗證請求標頭,以便它應該具有某些標頭,否則會引發錯誤。 這對於所有方法或服務應該是通用的。 我在下面嘗試過,

public ResponseEntity<Object> addEmployee(
        @RequestHeader(name = "header1", required = true) String header1,
        @RequestHeader(name = "header2", required = true) String header2,
        @RequestBody Employee employee) 
                 throws Exception 
    { 

但是我需要為所有控制器中的所有方法添加它。 如果是這種情況,我如何為全球所有服務拋出諸如“請求標頭中缺少 Header1”/“請求標頭中缺少標頭 2”之類的錯誤?

如果您有 Zuul,那么您可以在預路由中讀取請求 header 屬性,並在驗證失敗時回復填充錯誤的請求。

這是一個橫切關注點,應該使用AOP來完成。 由於您使用的是Spring ,您可以執行以下操作:

  1. 創建一個名為ValidateHeaders的注釋:

    public @interface ValidateHeaders {}

  2. 創建一個@Before通知,攔截使用@ValidateHeaders注釋的方法:

     @Before("@annotation(com.somepackage.ValidateHeaders)") public void controllerProxy(JoinPoint jp) { Object[] args = jp.getArgs(); //validation logic, throw exception if validation fails }

請注意,您必須使用反射提取字段:

Annotation[][] pa = ms.getMethod().getParameterAnnotations();

您可以遍歷所有注釋並搜索請求標頭:

if(annotations[i][j].annotationType().getName().contains("RequestHeader")) {
    RequestHeader requestHeader = (RequestHeader) m.getParameterAnnotations()[i][j];
    //now access fields in requestHeader to do the validation
}

這是一篇可以讓您開始使用建議類型的文章: https://www.baeldung.com/spring-aop-advice-tutorial

對於全局使用,您可以注冊一個攔截器。

@Component
public class MyHandlerInterceptor implements HandlerInterceptor {
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception arg3) throws Exception {
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView model) throws Exception {
    }

   @Override
   public boolean preHandle(HttpServletRequest request,
   HttpServletResponse response, Object handler) throws Exception {

    
    //here check headers contained in request object
    if (request.getHeader("header1") == null || request.getHeader("header2") == null) {
      response.getWriter().write("something");
      response.setStatus(someErrorCode);

      return false;
   }

   return true;
} 

然后注冊

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

@Autowired
private MyHandlerInterceptor interceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(interceptor).addPathPatterns("/**");
 }
}

這就是過濾器的用途。 您想根據 header 是否存在過濾掉請求,如果丟失則返回錯誤。 如果您不希望將它用於所有請求,則擴展OncePerRequestFilter可選擇覆蓋shouldNotFilter或者您可以實現普通Filter並使用FilterRegistrationBean僅為特定路徑注冊它。

然后在過濾器中你可以拋出一個異常並讓 Spring 弄清楚如何顯示它,或者實際上將響應設置為有意義的東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM