2017-08-15 16 views
1

リクエストペイロードを取得し、それを復号化し、有効なJSONであるかどうかをチェックし、チェーンに入り、サービス。事は、それまでは、私は体を書き換える方法を見つけることができていない。なぜ私はそれを書き直したいのですか?サービスではJSONが必要で、リクエストには本文に暗号化されたテキストが含まれているため、解読するとその本文が暗号化されたJSONになります。また、サービスから復帰すると、jsonを暗号化するように応答を書き直す必要があります。私は多くのフォーラムや質問を読みましたが、実際の解決策には到達できませんでした。HttpServletRequestでPOSTリクエストボディを書き換える方法

ここに私のコードです:

RequestLoginFilter.java

@WebFilter("/RequestLoginFilter") 
public class RequestLoginFilter implements Filter{ 

    protected final static Log logger = LogFactory.getLog(RequestLoginFilter.class); 

    private ServletContext context; 

    private CryptoUtil crypto; 

    public void init(FilterConfig fConfig) throws ServletException { 
     this.context = fConfig.getServletContext(); 
     this.context.log("RequestLoggingFilter initialized"); 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
//  use wrapper to read multiple times the content 
     AuthenticationRequestWrapper req = new AuthenticationRequestWrapper((HttpServletRequest) request); 
     HttpServletResponse resp = (HttpServletResponse) response; 

     String payload = req.getPayload(); 
     try { 
      String decryptedPayload = crypto.decrypt(payload); 
      JSONUtils.convertJSONStringToObject(decryptedPayload, LoginTokenTO.class); 
     } catch (GeneralSecurityException e) { 
      logger.error("Error when trying to decrypt payload '"+payload+"'"); 
      throw new ServletException("Error when trying to decrypt payload '"+payload+"'", e); 
     } 
     chain.doFilter(req, resp); 
     System.out.println("a ver"); 
    } 

    @Override 
    public void destroy() { 
     // TODO Auto-generated method stub 

    } 

} 

そしてまた、ラッパーは念のため、:

AuthenticationRequestWrapper.java

public class AuthenticationRequestWrapper extends HttpServletRequestWrapper { 

    protected final static Log logger = LogFactory.getLog(AuthenticationRequestWrapper.class); 

    private final String payload; 

    public AuthenticationRequestWrapper (HttpServletRequest request) throws AuthenticationException { 
     super(request); 

     // read the original payload into the payload variable 
     StringBuilder stringBuilder = new StringBuilder(); 
     BufferedReader bufferedReader = null; 
     try { 
      // read the payload into the StringBuilder 
      InputStream inputStream = request.getInputStream(); 
      if (inputStream != null) { 
       bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 
       char[] charBuffer = new char[128]; 
       int bytesRead = -1; 
       while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { 
        stringBuilder.append(charBuffer, 0, bytesRead); 
       } 
      } else { 
       // make an empty string since there is no payload 
       stringBuilder.append(""); 
      } 
     } catch (IOException ex) { 
      logger.error("Error reading the request payload", ex); 
      throw new AuthenticationException("Error reading the request payload", ex); 
     } finally { 
      if (bufferedReader != null) { 
       try { 
        bufferedReader.close(); 
       } catch (IOException iox) { 
        // ignore 
       } 
      } 
     } 
     payload = stringBuilder.toString(); 
    } 

    @Override 
    public ServletInputStream getInputStream() throws IOException { 
     final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(payload.getBytes()); 
     ServletInputStream inputStream = new ServletInputStream() { 
      public int read() 
       throws IOException { 
       return byteArrayInputStream.read(); 
      } 
     }; 
     return inputStream; 
    } 

    public String getPayload() { 
     return payload; 
    } 
} 

うまくいけば、ここで誰かが私がこの仕事を得るためにどのように得ることができるのかを知っていればいいと思う。

ありがとうございました。

答えて

1

あなたが求めているのはおそらく技術的に可能ですが、私にとって正しいアプローチのようには聞こえません。

必要なものは、着信要求(エンドポイント)とサービスの間にあるセキュリティレイヤーです。要求の本文を書き直すことは、奇妙なことです(おそらくあなたが問題を抱えている理由を説明しているでしょう)。 Filterにこれを行う理由がありますか?結局のところ、filtersはリクエストをフィルタリングするように設計されていますが、書き直すのではありません;

さらに論理的/透過的な解決策は、要求をサービス層に渡す前にエンドポイントにすべての着信要求を受け入れ、このようなもの:

public void handleRequest(Request request) { 
    try { 
     IncomingRequest x = securityManager.decrypt(request); 
     Response r = myService.handleRequest(x); 
     handleResponse(securityManager.encrypt(r)); 
    }catch(InvlidateMessage x) { 
     handleInvalidMessage... 
    }catch(BusinessException x) { 
     handleBusinessException... 
    } 
} 
関連する問題