1

java/jsp のフィルターを使用して、「reason」という名前のクエリ パラメーターを除外しようとしています。

基本的に、フィルターは、ユーザーがページを表示する「理由」を入力したことを確認するために配置されています。そうでない場合は、「理由を入力」ページにリダイレクトする必要があります。正当な理由を入力すると、要求したページに進むことができます。

したがって、その基本は機能します。ただし、「理由」はクエリ パラメーター (つまり、GET パラメーター) を介して送信されます。ユーザーが理由を選択すると、その理由パラメーターがユーザーが見たいページに転送されます。reason パラメータが存在するかどうかを確認することは、ユーザーが次に進むことができるかどうかをフィルターが判断する主な方法の 1 つであるため、これは問題です。

「理由」パラメーターを削除するために、拡張を試みHttpServletRequestWrapper、多数のメソッド (つまりgetPameter、など) をオーバーライドしました。ただし、パラメーターが削除されるのを見ることができませんでした。フィルターが要求されたページに転送されると、'reason' パラメーターは常にクエリ文字列 (つまり、ブラウザーの URL バーの URL) に GET パラメーターとして含まれます。

私のフィルタークラスは次のようになります。

public final class AccessRequestFilter implements Filter {

    public class FilteredRequest extends HttpServletRequestWrapper {

        public FilteredRequest(ServletRequest request) {
            super((HttpServletRequest)request);
        }

        @Override
        public String getParameter(String paramName) {
            String value = super.getParameter(paramName);

            if ("reason".equals(paramName)) {
                value = null;
            }

            return value;
        }

        @Override
        public String[] getParameterValues(String paramName) {
            String[] values = super.getParameterValues(paramName);

            if ("reason".equals(paramName)) {
                values = null;
            }

            return values;
        }

        @Override
        public Enumeration<String> getParameterNames() {
            return Collections.enumeration(getParameterMap().keySet());
        }

        @Override
        public Map<String, String[]> getParameterMap() {            
            Map<String, String[]> params = new HashMap<String, String[]>();
            Map<String, String[]> originalParams = super.getParameterMap();

            for(Object o : originalParams.entrySet()) {
                Map.Entry<String, String[]> pairs = (Map.Entry<String, String[]>) o;
                params.put(pairs.getKey(), pairs.getValue());
            }

            params.remove("reason");

            return params;
        }

        @Override
        public String getQueryString() {
            String qs = super.getQueryString();

            return qs.replaceAll("reason=", "old_reason=");
        }

        @Override
        public StringBuffer getRequestURL() {
            String qs = super.getRequestURL().toString();

            return new StringBuffer( qs.replaceAll("reason=", "old_reason=") );
        }
    }

    private FilterConfig filterConfig = null;  
    private static final Logger logger = MiscUtils.getLogger();

    public void init(FilterConfig filterConfig) throws ServletException {  
        this.filterConfig = filterConfig;  
    }  

    public void destroy() {  
        this.filterConfig = null;  
    }  

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
        logger.debug("Entering AccessRequestFilter.doFilter()");

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        HttpSession session = httpRequest.getSession();

        boolean canView = false;
        long echartAccessTime = 0L;
        String demographicNo = "";
        String reason = "";
        Date current = new Date();

        String user_no = (String) session.getAttribute("user");

        ProgramProviderDAO programProviderDAO = (ProgramProviderDAO)SpringUtils.getBean("programProviderDAO");
        ProgramQueueDao programQueueDao = (ProgramQueueDao)SpringUtils.getBean("programQueueDao");

        // Check to see if user has submitted a reason
        reason = request.getParameter("reason");
        demographicNo = request.getParameter("demographicNo");
        Long demographicNoAsLong = 0L;
        try {
            demographicNoAsLong = Long.parseLong( demographicNo );
        } catch (Exception e) {
            logger.error("Unable to parse demographic number.", e);
        }

        if (reason == null) {
            // If no reason was submitted, see if user still has time remaining on previous submission (if there was one)
            try {
                echartAccessTime = (Long)session.getServletContext().getAttribute("echartAccessTime_" + demographicNo);
            } catch (Exception e) {
                logger.warn("No access time found");
            }

            if (current.getTime() - echartAccessTime < 30000) {
                canView = true;
            }
        } else if (!reason.equals("")) {
            // TODO: validate reason
            canView = true;
            session.getServletContext().setAttribute("echartAccessTime_" + demographicNo, current.getTime());
            String ip = request.getRemoteAddr();
            // Log the access request and the reason given for access
            LogAction.addLog(user_no, "access", "eChart", demographicNo, ip, demographicNo, reason);
        }

        if (!canView) {
            // Check if provider is part of circle of care
            List<Long> programIds = new ArrayList<Long>();

            List<ProgramQueue> programQueues = programQueueDao.getAdmittedProgramQueuesByDemographicId( demographicNoAsLong );
            if (programQueues != null && programQueues.size() > 0) {
                for (ProgramQueue pq : programQueues) {
                    programIds.add( pq.getProgramId() );
                }

                List<ProgramProvider> programProviders = programProviderDAO.getProgramProviderByProviderProgramId(user_no, programIds);

                if (programProviders != null && programProviders.size() > 0) {
                    canView = true;
                }
            }
        }

        String useNewCaseMgmt;
        if((useNewCaseMgmt = request.getParameter("newCaseManagement")) != null ) {     
            session.setAttribute("newCaseManagement", useNewCaseMgmt); 
            ArrayList<String> users = (ArrayList<String>)session.getServletContext().getAttribute("CaseMgmtUsers");
            if( users != null ) {
                users.add(request.getParameter("providerNo"));
                session.getServletContext().setAttribute("CaseMgmtUsers", users);
            }
        }
        else {
            useNewCaseMgmt = (String)session.getAttribute("newCaseManagement");             
        }

        String requestURI = httpRequest.getRequestURI();
        String contextPath = httpRequest.getContextPath();

        if (!canView && !requestURI.startsWith(contextPath + "/casemgmt/accessRequest.jsp")) {
            httpResponse.sendRedirect(contextPath + "/casemgmt/accessRequest.jsp?" + httpRequest.getQueryString());
            return;
        }

        logger.debug("AccessRequestFilter chainning");
        chain.doFilter( new FilteredRequest(request), response);
    }
}

フィルタは、 というサブディレクトリに着信するすべてのリクエストと転送を傍受するように設定されていcasemgmtます。web.xml のフィルターは次のようになります。

<filter>
        <filter-name>AccessRequestFilter</filter-name>
        <filter-class>org.oscarehr.casemgmt.filter.AccessRequestFilter</filter-class>
    </filter>
...
<filter-mapping>
        <filter-name>AccessRequestFilter</filter-name>
        <url-pattern>/casemgmt/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

「理由」パラメーターを実際に削除する方法を知っている人はいますか?

4

1 に答える 1

2

サーバー側でラップして操作してもHttpServletRequest、ブラウザのアドレスバーに表示されるように、魔法のように URL に影響を与えることはありません。その URL は、ブラウザーが目的のリソースを要求するために使用したものであるため、現状のままです。ラップされたリクエストは、同じリクエストのフィルターの後に実行されているサーバー側のコードにのみ影響します。

ブラウザのアドレス バーの URL を変更したい場合は、目的の URL に正確にリダイレクトを送信する必要があります。

基本的、

if (reasonParameterIsIn(queryString)) {
    response.sendRedirect(requestURL + "?" + removeReasonParameterFrom(queryString));
    return;
}
于 2013-02-15T01:50:18.807 に答える