Gae + Struts2 + Spring3 + Hibernate4 + MySQL на локальном хосте не создает http-сессию, а хранилище данных всегда пусто

У меня проблема с хранилищем данных и спящим режимом, я смог интегрировать Gae + Struts2 + Spring3 + Hibernate4 + MySQL в локальный хост, и все вроде работает, но когда я пытаюсь создать сеанс в HTTP, сеанс не создается или сеанс .getLastAccessedTime() всегда 1970-01-01 (значение по умолчанию). Когда я перехожу по ссылке хранилища данных в http:localhost:8080/_ah/admin, сеанс не создается.

Я использую ESAPI для безопасности и этот метод:

public boolean isSessionTimeout() {
    HttpSession session = ESAPI.httpUtilities().getCurrentRequest().getSession(false);
    if (session == null)
        return true;
    Date deadline = new Date(session.getLastAccessedTime() + IDLE_TIMEOUT_LENGTH);
    Date now = new Date();
    return now.after(deadline);
}

всегда возвращает истину.

Я включил сеансы в appengine-web.xml и не понимаю проблемы, пока такая конфигурация работает в tomcat, но в appengine версии 1.9.2 есть какая-то проблема.

Я создаю проект в maven следующим образом:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <version>2.5.1</version>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <archiveClasses>true</archiveClasses>
                <webResources>
                    <!-- in order to interpolate version from pom into appengine-web.xml -->
                    <resource>
                        <directory>${basedir}/src/main/webapp/WEB-INF</directory>
                        <filtering>true</filtering>
                        <targetPath>WEB-INF</targetPath>
                    </resource>
                </webResources>
            </configuration>
        </plugin>

        <plugin>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-maven-plugin</artifactId>
            <version>${appengine.app.version}</version>
            <configuration>
                <jvmFlags>
                    <jvmFlag>-Dappengine.generated.dir=${project.basedir}/appengine</jvmFlag>
                    <jvmFlag>-Ddatastore.backing_store=${project.basedir}/local_db.bin</jvmFlag>
                </jvmFlags>
            </configuration>
        </plugin>

    </plugins>
</build>

У меня есть первый фильтр в моем web.xml, ESAPIFilter, который содержит:

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;

    try {
        ESAPI.httpUtilities().setCurrentHTTP(request, response);
    } catch (Exception e) {
        logger.error(Logger.SECURITY_FAILURE, "Error in ESAPI security filter: " + e.getMessage(), e);
    }

    try {
        // figure out who the current user is
        try {
            ESAPI.authenticator().login();
        } catch (AuthenticationException e) {
            request.setAttribute("message", "Unauthorized");
        }
        // log this request, obfuscating any parameter named password
        ESAPI.httpUtilities().logHTTPRequest(request, logger, Arrays.asList(obfuscate));
        // check access to this URL
        if (!ESAPI.accessController().isAuthorizedForURL(request.getRequestURI())) {
            request.setAttribute("message", "Unauthorized");
        }

        // check for CSRF attacks
        //ESAPI.httpUtilities().verifyCSRFToken(request);
        // forward this request on to the web application
        chain.doFilter(request, response);
        // set up response with content type
        ESAPI.httpUtilities().setContentType(response);
        // set no-cache headers on every response
        // only do this if the entire site should not be cached
        // otherwise you should do this strategically in your controller or actions
        ESAPI.httpUtilities().setNoCacheHeaders(response);
    } catch (Exception e) {
        logger.error(Logger.SECURITY_FAILURE, "Error in ESAPI security filter: " + e.getMessage(), e);
        request.setAttribute("message", e.getMessage());

    } finally {
        // VERY IMPORTANT
        // clear out the ThreadLocal variables in the authenticator
        // some containers could possibly reuse this thread without clearing the User
        try {
            ESAPI.clearCurrent();
        } catch (Exception e) {
            logger.error(Logger.SECURITY_FAILURE, "Error in ESAPI security filter: " + e.getMessage(), e);
        }
    }
}

person Ardi Goxhaj    schedule 11.04.2014    source источник
comment
Мне нужно реализовать собственный вход в систему, но я не могу использовать сеансы http по какой-то неизвестной причине, ah_SESSION не создается в моем локальном хранилище данных. Есть ли пример использования сеансов для Java в Appengine? Я искал, но безрезультатно...   -  person Ardi Goxhaj    schedule 12.04.2014
comment
Тот факт, что он всегда возвращает null, говорит мне о том, что вы не настроили движок приложения для интеграции с ESAPI. Например, в устаревшем приложении, в которое я интегрировал ESAPI, мне пришлось установить заводские настройки в log4j.properties, которые указывали на реализацию ведения журналов ESAPI.   -  person avgvstvs    schedule 12.04.2014
comment
Вы упустили какой-то очень важный контекст... вы полностью реализовали настройку аутентификатора ESAPI или просто добавили ESAPI в устаревшее приложение?   -  person avgvstvs    schedule 12.04.2014
comment
Javadoc для класса DefaultHttpUtilities говорит следующее: ` * Обычно это делается путем вызова метода Authenticator.login(), который * автоматически вызывает setCurrentHTTP(). Однако, если вы хотите использовать эти методы * в другом приложении, вы должны явно вызвать setCurrentHTTP() * в своем собственном коде. В любом случае вы должны вызвать ESAPI.clearCurrent(), чтобы очистить локальные * переменные потока перед повторным использованием потока. Преимущества вездесущей идентичности перевешивают недостатки такого подхода.   -  person avgvstvs    schedule 12.04.2014
comment
Судя по этой документации, у вас либо есть конфигурация с вашей конфигурацией Authenticator, либо вы явно не устанавливаете запрос, поэтому он всегда возвращает null   -  person avgvstvs    schedule 12.04.2014
comment
В моем обновлении я показываю для каждого запроса (у меня есть ESAPIFilter в качестве первого фильтра в моем файле web.xml). Я устанавливаю запрос/ответ для своего аутентификатора с помощью: ESAPI.httpUtilities().setCurrentHTTP(запрос, ответ); и, наконец, очистите threadlocal в соответствии с рекомендацией ESAPI.   -  person Ardi Goxhaj    schedule 13.04.2014


Ответы (1)


Наконец, я обнаружил проблему, так как сеанс был создан с использованием по умолчанию session.getLastAccessedTime()=0, и я установил это значение с текущим временем следующим образом:

    public boolean isSessionTimeout() {
    HttpSession session = ESAPI.httpUtilities().getCurrentRequest().getSession(false);
    if (session == null)
        return true;
    long lastAccessedTime=System.currentTimeMillis();
    if(session.getLastAccessedTime()!=0){
        lastAccessedTime=session.getLastAccessedTime();
    } 
    Date deadline = new Date(lastAccessedTime + IDLE_TIMEOUT_LENGTH);
    Date now = new Date();      
    return now.after(deadline);
}

наконец, теперь все работает, и я могу локально создать сеанс, я не пробовал это в производстве.

person Ardi Goxhaj    schedule 13.04.2014
comment
Если вы полностью решили проблему, отметьте свой ответ как принятый, чтобы мы могли удалить очередь вопросов без ответов. - person avgvstvs; 17.10.2014