2

私は Tomcat 7 を使用していて、いくつかのオブジェクトをセッションに保存しようとしていますが、同じクライアントから新しいリクエストがあるたびに、Tomcat が新しいセッションを作成しているように見えます。

以下は、基本的に認証と承認を行い、オブジェクトを返す別のアプリケーションを呼び出すフィルターである私のコードです。この通信にはApache httpclientを使用しています

フィルタ クラス

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  throws IOException, ServletException {

    // If the request is for any static contents do not invoke this filter
    if (!isWorthyRequest((HttpServletRequest)request)) {
        chain.doFilter(request, response);
        return;
    }

    HttpClient httpClient = null;
    try {
        if (validateApp && request instanceof HttpServletRequest) {
            HttpServletRequest httpServletRequest = (HttpServletRequest)request;
            HttpSession httpSession = httpServletRequest.getSession(false);
            if (null != httpSession && null != httpSession.getAttribute("userInfoMap")) {
                LOG.info(" User is already Authenticated :: session Id :: "+httpSession.getId()
                        +" Created At :: "+ new Date(httpSession.getCreationTime())
                +" Last Accessed At :: "+new Date(httpSession.getLastAccessedTime()));
                // The user is already Authenticated & Authorize just pass the request to next chain
            } else {
                LOG.info("Calling Authenication / Authorization Module :: URL "+securityServiceURL);
                // Calling Authentication and Authorization
                httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(securityServiceURL);
                // Getting the SM Header
                httpPost.setHeader(IaasConstants.SM_USER, httpServletRequest.getHeader(IaasConstants.SM_USER));
                List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
                // urlParameters.add(new BasicNameValuePair(IaasConstants.SOURCE_APP_NAME, "vElite"));
                urlParameters.add(new BasicNameValuePair(IaasConstants.SUB_SERVICE_NAME, IaasConstants.SERVICE_AUTHENTICATE_USER));
                httpPost.setEntity(new UrlEncodedFormEntity(urlParameters));
                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                String jsonString = null; 
                if (null != httpEntity) {
                    jsonString = EntityUtils.toString(httpEntity);
                }
                HttpServletResponse httpServletResponse = (HttpServletResponse)response;
                // User is a valid user
                if (httpResponse.getStatusLine().getStatusCode() == HttpServletResponse.SC_OK) {
                    LOG.info(" User is valid :: user :: "+httpServletRequest.getHeader(IaasConstants.SM_USER)+" jsonObject :: "+jsonString);
                    if (null != jsonString) {
                        Gson gSon = new Gson();
                        Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
                        Map<String, Object> userInfoMap = gSon.fromJson(jsonString, mapType);
                        httpSession = httpServletRequest.getSession(false);
                        if (null == httpSession) {
                            LOG.info("Session Created and the userInfoMap is stored inside session :: ");
                            httpSession = httpServletRequest.getSession(true);
                            httpSession.setAttribute(IaasConstants.USER_INFO_MAP, userInfoMap);
                        } else {
                            httpSession.setAttribute(IaasConstants.USER_INFO_MAP, userInfoMap);
                        }
                    }
                } else {
                    // Bad User
                    LOG.info("Invalid User ::: with status code :: "
                    +httpResponse.getStatusLine().getStatusCode()
                    +" Status Message :: "+httpResponse.getStatusLine().getReasonPhrase());

                    httpServletResponse.setStatus(httpResponse.getStatusLine().getStatusCode());
                    httpServletResponse.sendError(httpResponse.getStatusLine().getStatusCode());
                    httpServletResponse.flushBuffer();
                    return;
                }
            }

        }
        HttpServletResponseCopier responseCopier = new HttpServletResponseCopier((HttpServletResponse) response);
        // pass the request along the filter chain
        chain.doFilter(request, responseCopier);

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        if (null != httpClient) {
            httpClient.getConnectionManager().shutdown();
        }
    }
}

/**
 * @see Filter#init(FilterConfig)
 */
public void init(FilterConfig fConfig) throws ServletException {
    // TODO Auto-generated method stub
    this.fConfig = fConfig;
    validateApp = Boolean.valueOf(fConfig.getInitParameter(IaasConstants.VALIDATE_APP));
    securityServiceURL = fConfig.getInitParameter(IaasConstants.SECURITY_SERVICE_URL);
}

   private boolean isWorthyRequest(HttpServletRequest request) {
       String url = request.getRequestURI().toString();
       Matcher m = excludeUrls.matcher(url);

       return (!m.matches());
   }

Web.xml

<session-config>
<session-timeout>15</session-timeout>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
</session-config>

Tomcat が同じクライアントからのリクエストに対してセッションを維持するにはどうすればよいですか?

次のオプションを試しましたが、うまくいきませんでした。

  1. 次のようにグローバル context.xml に Valve を追加する <Valve className="org.apache.catalina.authenticator.BasicAuthenticator" changeSessionIdOnAuthentication="false"/>

  2. <http-only>true</http-only>オプションを web.xml から削除する

私が理解しているように、セッション固定保護の問題により、Tomcat はすべてのリクエストに対して新しいセッション ID を作成しますが、セッションを維持する他の方法はありますか?

4

1 に答える 1

4

<secure>true</secure>は、HTTPS 接続でのみCookie を設定する必要があることを意味します。HTTP を作成していると思われるため、削除します。

于 2013-10-17T20:23:07.750 に答える