在Java8标准环境中使用SpringOAuth的问题

在Java8标准环境中使用SpringOAuth的问题,java,spring,google-app-engine,oauth-2.0,Java,Spring,Google App Engine,Oauth 2.0,我的示例应用程序在本地环境中工作。但是,它不适用于Java8标准环境。下面的项目是示例应用程序项目 Java8标准环境中发生以下错误: Authentication Failed: Could not obtain access token 我在SpringOAuth的源代码中添加了日志,并调查了原因。错误的原因似乎是会话数据已丢失 其运作如下: AuthorizationCodeAccessTokenProvider::getParametersForTokenRequest中的prese

我的示例应用程序在本地环境中工作。但是,它不适用于Java8标准环境。下面的项目是示例应用程序项目

Java8标准环境中发生以下错误:

Authentication Failed: Could not obtain access token
我在SpringOAuth的源代码中添加了日志,并调查了原因。错误的原因似乎是会话数据已丢失

其运作如下:

AuthorizationCodeAccessTokenProvider::getParametersForTokenRequest
中的
preservedState
为空。因此,
InvalidRequestException
被抛出。这就是错误的原因

OAuth2RestTemplate::acquireAccessToken
中调用了
setPreservedState
方法。此时,
preservedState
被设置为null

DefaultOAuth2ClientContext
实例具有
preservedState
<在Java8标准环境中,
DefaultOAuth2ClientContext
实例的code>preservedState为空。但是,它在本地环境中不是空的

DefaultOAuth2ClientContext
实例存储在会话中。我知道它存储在本地环境的内存中,以及标准环境的数据存储中

从上面,我猜会话数据丢失了


我被困在调查中。有没有信息可以作为解决问题的线索?

我也有同样的问题。最后,我实现了一个Spring会话的定制
SessionRepository
,如下所示:()

存储库类:

class MemcacheSessionRepository(private val memcacheService: MemcacheService) : SessionRepository<MemcacheSession> {
  private val log = LoggerFactory.getLogger(javaClass)
  private val maxInactiveIntervalInSeconds: Int = 3600

  override fun createSession() = MemcacheSession().also { session ->
    session.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds
    log.debug("createSession() = {}", session.id)
  }

  override fun save(session: MemcacheSession) {
    log.debug("save({}) with expiration {}", session.id, session.maxInactiveIntervalInSeconds)
    memcacheService.put(session.id, session, Expiration.byDeltaSeconds(session.maxInactiveIntervalInSeconds))
  }

  override fun getSession(id: String): MemcacheSession? =
    (memcacheService.get(id) as? MemcacheSession)?.also { session ->
        session.setLastAccessedTimeToNow()
    }.also { session ->
        log.debug("getSession({}) = {}", id, session?.id)
    }

  override fun delete(id: String) {
    log.debug("delete({})", id)
    memcacheService.delete(id)
  }
}
class MemcacheSessionRepository(private val memcacheService:memcacheService):SessionRepository{
private val log=LoggerFactory.getLogger(javaClass)
私有val maxInactiveIntervalInSeconds:Int=3600
重写fun createSession()=MemcacheSession()。另外{session->
session.maxInactiveIntervalInSeconds=maxInactiveIntervalInSeconds
调试(“createSession()={}”,session.id)
}
覆盖乐趣保存(会话:MemcacheSession){
log.debug(“保存({})并过期{}”,session.id,session.maxInactiveIntervalInSeconds)
memcacheService.put(session.id、session、Expiration.byDeltaSeconds(session.maxInactiveIntervalInSeconds))
}
重写fun getSession(id:String):MemcacheSession=
(memcacheService.get(id)为?MemcacheSession)?。另外{session->
session.setLastAccessedTimeToNow()
}.另外{会话->
log.debug(“getSession({})={}”,id,session?.id)
}
覆盖乐趣删除(id:字符串){
debug(“delete({})”,id)
memcacheService.delete(id)
}
}
实体类:

class MemcacheSession : ExpiringSession, Serializable {
  companion object {
    const val serialVersionUID: Long = 1
  }

  private val id: String = UUID.randomUUID().toString()
  private val creationTime: Long = System.currentTimeMillis()
  private var lastAccessedTime: Long = creationTime
  private var maxInactiveIntervalInSeconds: Int = 3600
  private val attributes: MutableMap<String, Any> = mutableMapOf()

  override fun getId() = id

  override fun getCreationTime() = creationTime

  override fun getLastAccessedTime() = lastAccessedTime
  override fun setLastAccessedTime(time: Long) {
    lastAccessedTime = time
  }
  fun setLastAccessedTimeToNow() {
    lastAccessedTime = System.currentTimeMillis()
  }

  override fun getMaxInactiveIntervalInSeconds() = maxInactiveIntervalInSeconds
  override fun setMaxInactiveIntervalInSeconds(interval: Int) {
    maxInactiveIntervalInSeconds = interval
  }

  override fun removeAttribute(key: String) {
    attributes.remove(key)
  }

  override fun getAttributeNames() = attributes.keys

  override fun <T> getAttribute(key: String): T? = attributes[key] as T?

  override fun setAttribute(key: String, value: Any) {
    attributes.put(key, value)
  }

  override fun isExpired() = false
}
class MemcacheSession:ExpiringSession,可序列化{
伴星{
const val serialVersionId:Long=1
}
private val id:String=UUID.randomUUID().toString()
private val creationTime:Long=System.currentTimeMillis()
private var lastAccessedTime:Long=creationTime
私有变量maxInactiveIntervalInSeconds:Int=3600
私有val属性:MutableMap=mutableMapOf()
重写fun getId()=id
重写getCreationTime()=creationTime
覆盖getLastAccessedTime()=lastAccessedTime
覆盖乐趣设置LastAccessedTime(时间:长){
lastAccessedTime=时间
}
fun setLastAccessedTimeToNow(){
lastAccessedTime=System.currentTimeMillis()
}
重写getMaxInactiveIntervalInSeconds()=maxInactiveIntervalInSeconds
覆盖乐趣设置MaxInactiveIntervalinSeconds(间隔:Int){
maxInactiveIntervalInSeconds=间隔
}
重写fun removeAttribute(键:字符串){
属性。删除(键)
}
重写getAttributeNames()=attributes.keys
重写fun getAttribute(键:字符串):T?=属性[key]为T?
重写fun setAttribute(键:字符串,值:任意){
attributes.put(键、值)
}
override fun isExpired()=false
}

这在目前看来效果不错,但它只使用Memcache,需要改进以实现高可用性。

谢谢,这很有效!我将提交中的内容转换为Java,但除此之外没有任何重大问题。我无法相信,在App Engine开箱即用的环境中存储会话不起作用,尽管他们说它应该起作用。我提出,指的是这个。这也行得通。非常感谢你!对于非Kotlin人员,这可能有助于复制粘贴(可以用显式代码替换lombok)