同じ現象で困ってる方の助けになれば幸いでございます!
と、ほかの解決方法探し中...!
構成
Devローカルサーバーならしっかり動いている。
本番環境で問題が発生する。
デプロイしてちゃんと起動はする。
しかし、Spring Securityを使ったフォームのログインで問題。
ログインボタンを押した後、
なにごとも無かったかのように、
ログイン画面に戻る笑
どうやらGAEのセッションハンドラを使うと上手く動かぬもよう。
GAEのセッションハンドラを使わず、
GAE内のmemcacheもしくはDatastoreを使って
自前のセッションハンドラにします。
DatastoreSessionRepository
しかし、今度はローカルサーバーで認証をかけてないページでセッションクッキーが吐かれなくなった(;´Д`)
こちらは未解決。と、ほかの解決方法探し中...!
構成
- Google App Engine Java 8 Standard
- Spring Boot 1.5.9
- Spring Security
- Kotlin
- Gradle
Devローカルサーバーならしっかり動いている。
本番環境で問題が発生する。
デプロイしてちゃんと起動はする。
しかし、Spring Securityを使ったフォームのログインで問題。
ログインボタンを押した後、
なにごとも無かったかのように、
ログイン画面に戻る笑
どうやらGAEのセッションハンドラを使うと上手く動かぬもよう。
GAEのセッションハンドラを使わず、
GAE内のmemcacheもしくはDatastoreを使って
自前のセッションハンドラにします。
DatastoreSessionRepository
package com.hometest.libs.appengine.session;
import com.google.appengine.api.datastore.*
import org.springframework.session.MapSession
import org.springframework.session.SessionRepository
import org.springframework.stereotype.Component
import java.io.*
import java.util.logging.Logger
@Component
class DatastoreSessionRepository(private val datastoreService: DatastoreService) : SessionRepository<MapSession> {
private val logger = Logger.getLogger(javaClass.simpleName)
private val maxInactiveIntervalInSeconds: Int = 3600
private val kind = "Session"
private val propertyName = "serialized"
override fun createSession(): MapSession = MapSession().also { session ->
session.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds
logger.info { "createSession() = ${session.id}" }
}
override fun save(session: MapSession) {
logger.info { "save(${session.id}) with expiration ${session.maxInactiveIntervalInSeconds}" }
ByteArrayOutputStream().use { byteArray ->
ObjectOutputStream(byteArray).use { outStream ->
outStream.writeObject(session)
}
datastoreService.put(Entity(kind, session.id).apply {
// TODO: Check byteArray size. This byte array can be no bigger than 1MB.
// https://cloud.google.com/appengine/docs/standard/java/javadoc/com/google/appengine/api/datastore/Blob
setProperty(propertyName, Blob(byteArray.toByteArray()))
})
}
}
override fun getSession(id: String): MapSession? {
val blob: Blob? = try {
datastoreService.get(KeyFactory.createKey(kind, id))
.getProperty(propertyName) as? Blob
} catch (_: EntityNotFoundException) {
null
}
val session: MapSession? = blob?.let {
ByteArrayInputStream(it.bytes).use { byteArray ->
ObjectInputStream(byteArray).use { inStream ->
(inStream.readObject() as MapSession).also { session ->
session.lastAccessedTime = System.currentTimeMillis()
}
}
}
}
logger.info { "getSession($id) = ${session?.id}" }
return session
}
override fun delete(id: String) {
logger.info { "delete($id)" }
datastoreService.delete(KeyFactory.createKey(kind, id))
}
}
MemcacheSessionRepositorypackage com.hometest.libs.appengine.session;
import com.google.appengine.api.memcache.Expiration
import com.google.appengine.api.memcache.MemcacheService
import org.springframework.session.MapSession
import org.springframework.session.SessionRepository
import org.springframework.stereotype.Component
import java.util.logging.Logger
@Component
class MemcacheSessionRepository(private val memcacheService: MemcacheService) : SessionRepository<MapSession> {
private val logger = Logger.getLogger(javaClass.simpleName)
private val maxInactiveIntervalInSeconds: Int = 3600
override fun createSession() = MapSession().also { session ->
session.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds
logger.info { "createSession() = ${session.id}" }
}
override fun save(session: MapSession) {
logger.info { "save(${session.id}) with expiration ${session.maxInactiveIntervalInSeconds}" }
memcacheService.put(session.id, session, Expiration.byDeltaSeconds(session.maxInactiveIntervalInSeconds))
}
override fun getSession(id: String): MapSession? =
(memcacheService.get(id) as? MapSession)?.also { session ->
session.lastAccessedTime = System.currentTimeMillis()
}.also { session ->
logger.info { "getSession($id) = ${session?.id}" }
}
override fun delete(id: String) {
logger.info { "delete($id)" }
memcacheService.delete(id)
}
}
AppengineConfigurationpackage com.hometest.config;
import com.google.appengine.api.datastore.DatastoreService
import com.google.appengine.api.datastore.DatastoreServiceFactory
import com.google.appengine.api.memcache.MemcacheService
import com.google.appengine.api.memcache.MemcacheServiceFactory
import com.hometest.libs.appengine.session.MemcacheSessionRepository
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.session.MapSession
import org.springframework.session.web.http.SessionRepositoryFilter
@Configuration
class AppengineConfiguration {
// AppEngine Session
@Bean
fun memcacheService(): MemcacheService {
return MemcacheServiceFactory.getMemcacheService()
}
@Bean
fun datastoreService(): DatastoreService {
return DatastoreServiceFactory.getDatastoreService()
}
@Bean
fun springSessionRepositoryFilter(sessionRepository: MemcacheSessionRepository): SessionRepositoryFilter<MapSession> {
return SessionRepositoryFilter(sessionRepository)
}
// @Bean
// fun springSessionRepositoryFilter(sessionRepository: DatastoreSessionRepository): SessionRepositoryFilter<MapSession> {
// return SessionRepositoryFilter(sessionRepository)
// }
}
しかし、今度はローカルサーバーで認証をかけてないページでセッションクッキーが吐かれなくなった(;´Д`)
一旦本番では問題なくクッキー履かれていいるのでまた今度。
もし解決方法見つけたら、く、ください !
参考
- https://stackoverflow.com/questions/45217234/issue-with-using-spring-oauth-on-java8-standard-environment
- https://github.com/int128/gradleupdate/commit/2405310dd0da4e19cf4d4b55a16f8466c1d62cc8
- https://github.com/nosix/appengine-java8-spring-oauth2/blob/master/application/src/main/kotlin/org/musyozoku/appengine/session/DatastoreSessionRepository.kt
- https://gist.github.com/lilianaziolek/6851c2f81be81eae2207ec863f41f484
0 件のコメント:
コメントを投稿