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

时间:2017-07-20 14:11:37

标签: java spring google-app-engine oauth-2.0

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

https://github.com/nosix/appengine-java8-spring-oauth2

Java8标准环境中出现以下错误:

Authentication Failed: Could not obtain access token

我在Spring OAuth的源代码中添加了日志并调查了原因。错误的原因似乎是会话数据已丢失。

操作如下:

{p} preservedStateAuthorizationCodeAccessTokenProvider::getParametersForTokenRequest中为空。所以,InvalidRequestException被抛出。这是错误的原因。

setPreservedState中调用

OAuth2RestTemplate::acquireAccessToken方法。那时,preservedState设置为null。

DefaultOAuth2ClientContext实例有preservedState。 {8} preservedState实例的DefaultOAuth2ClientContext在Java8标准环境中为null。但是,它在本地环境中不是空的。

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

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

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

1 个答案:

答案 0 :(得分:1)

我有同样的问题。最后,我按如下方式实现了Spring会话的自定义SessionRepository :( see also this commit

存储库类:

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 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
}

此时此功能似乎运行良好,但它仅使用Memcache,需要改进以提高可用性。