2015-05-07 22 views
1

我正在使用HMAC身份驗證過濾器。在過濾器訪問我的POST請求正文時,我能夠獲取XML。當我嘗試訪問控制器中的XML時,我得到一個空白字符串。過濾器中的xmlString給出了正確的XML,但控制器中的xmlString給出了空白字符串。我正在使用Spring MVC。導致POST請求正文變空的過濾器

我的過濾器是:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     HttpServletResponse httpResponse = (HttpServletResponse) response; 

     String authorisation = httpRequest.getHeader("authorization"); 
     String accessKeyId = authorisation.split(":")[0].split(" ")[1]; 
     String signature = authorisation.split(":")[1]; 
     String secretAccessKey = getSecretAccessKey(accessKeyId); 

     InputStream xmlStream = httpRequest.getInputStream(); 
     String xmlString = IOUtils.toString(xmlStream, "UTF-8"); 
     String encodedXml = new String(); 
     try { 
      encodedXml = HMACEncoder.calculateHMAC(xmlString, secretAccessKey); 
     } catch (SignatureException e) { 
      e.printStackTrace(); 
     } 
     if (!signature.equals(encodedXml)) 
      httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
     else 
      chain.doFilter(request, response); 
    } 

和我的控制器:

@RequestMapping(value = "/user", method = RequestMethod.POST) 
public String fetchUserString(HttpServletRequest request) { 
    InputStream xml = null; 
    String xmlString = null; 
    try { 
     xml = request.getInputStream(); 
     xmlString = IOUtils.toString(xml, "UTF-8"); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return xmlString; 
} 

回答

0

您無法讀取數據流的兩倍,在過濾器註釋代碼,只有在控制器讀取。

+0

我需要能夠讀取數據流的兩倍。在我的過濾器中,我必須檢查編碼是否正確完成。有什麼方法可以讀取它兩次或將原始流回到請求? – khateeb

+0

噢好...沒有辦法讀取流的兩倍或把內容迴流到據我所知...因此,讀取過濾器中的流,並設置內容的請求屬性。現在在您的控制器中,從請求屬性中讀取內容而不是從流中讀取內容。 – whoami

+0

爲什麼你不使用頭來保存你的整個XML(編碼如何編碼)需要授權?這是一個很好的例子,可以滿足您的需求。 https://github.com/philipsorst/angular-rest-springsecurity –

1

正如praki所建議的那樣,我把XML放在請求屬性中,在我的控制器中,我從請求屬性中獲取了XML,然後將XML放入ModelAttribute。這裏是我的代碼:

我的過濾器:

@Override 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
    HttpServletRequest httpRequest = (HttpServletRequest) request; 
    HttpServletResponse httpResponse = (HttpServletResponse) response; 
    if (httpRequest.getMethod().equalsIgnoreCase("POST")) {  
     String authorisation = httpRequest.getHeader("authorization"); 
     String accessKeyId = authorisation.split(":")[0].split(" ")[1]; 
     String signature = authorisation.split(":")[1]; 
     String secretAccessKey = getSecretAccessKey(accessKeyId);  
     ServletInputStream servletStream = httpRequest.getInputStream(); 
     String xmlString = IOUtils.toString(servletStream); 
     String encodedXml = new String(); 
     try { 
      encodedXml = HMACEncoder.calculateHMAC(xmlString, secretAccessKey); 
     } catch (SignatureException e) { 
      e.printStackTrace(); 
     } 
     httpRequest.setAttribute("content", xmlString); 
     if (!signature.equals(encodedXml)) 
      httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
     else 
      chain.doFilter(request, response); 
    } else 
     chain.doFilter(request, response); 
} 

和我的控制器:

@RequestMapping(value = "/add", method = RequestMethod.POST, produces = "application/xml") 
public @ResponseBody Catalog addCatalog(@ModelAttribute("catalog") Catalog catalog) { 
    logger.info("In addCatalog with " + catalog); 
    catalog.getHeader().setOrganizationId(IConstant.ORGANIZATION_ID_BSL); 
    try { 
     catalog = catalogService.addCatalogIntegration(catalog); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    logger.info("Returning from addCatalog with " + catalog); 
    return catalog; 
} 

@ModelAttribute("catalog") 
private Catalog getCatalog(HttpServletRequest request) throws Exception { 
    Catalog catalog = new Catalog(); 
    try { 
     String xml = (String) request.getAttribute("content"); 
     if (xml != null) { 
      JAXBContext jaxbContext = JAXBContext.newInstance(Catalog.class); 
      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
      catalog = (Catalog) unmarshaller.unmarshal(new StringReader(xml)); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return catalog; 
}