Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with using Spring OAuth on Java8 standard environment

My sample application work on local environment. But, it does not work on Java8 standard environment. The following project is the sample application project.

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

The following error occurs in Java8 standard environment:

Authentication Failed: Could not obtain access token

I added logs to the source code of Spring OAuth and investigated the cause. The cause of the error seems to be that the session data has been lost.

It operated as follows:

preservedState is null in AuthorizationCodeAccessTokenProvider::getParametersForTokenRequest. So, InvalidRequestException is thrown. This is the cause of the error.

setPreservedState method is called in OAuth2RestTemplate::acquireAccessToken. At that time, preservedState is set to null.

DefaultOAuth2ClientContext instance has preservedState. preservedState of DefaultOAuth2ClientContext instance is null in Java8 standard environment. But, It is not null in the local environment.

DefaultOAuth2ClientContext instance are stored in the session. I understand that it is stored on memory in the local environment and in the data store in the standard environment.

From the above, I guessed that the session data was lost.

I was stuck in the investigation. Is there information that serves as a clue for solving?

like image 222
nosix Avatar asked Feb 04 '26 03:02

nosix


1 Answers

I had the same issue. Finally I implemented a custom SessionRepository of Spring Session as follows: (see also this commit)

Repository class:

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

Entity class:

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
}

This seems work well at this time but it uses only Memcache and needs to improve for high availability.

like image 121
Hidetake Iwata Avatar answered Feb 06 '26 17:02

Hidetake Iwata



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!