2017-07-20 30 views
3

我的示例應用程序在本地環境中工作。但是,它不適用於Java8標準環境。以下項目是示例應用程序項目。在Java8標準環境發生在Java8標準環境中使用Spring OAuth的問題

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

以下錯誤:

Authentication Failed: Could not obtain access token 

我添加日誌以彈簧的OAuth的源代碼並調查原因。錯誤的原因似乎是會話數據丟失了。

它操作如下:

preservedStateAuthorizationCodeAccessTokenProvider::getParametersForTokenRequest空。所以,InvalidRequestException被拋出。這是錯誤的原因。

setPreservedState方法在OAuth2RestTemplate::acquireAccessToken中調用。那時,preservedState被設置爲空。

DefaultOAuth2ClientContext實例有preservedStatepreservedStateDefaultOAuth2ClientContext實例在Java8標準環境中爲null。但是,在本地環境中它不是空的。

DefaultOAuth2ClientContext實例存儲在會話中。我知道它存儲在本地環境的內存和標準環境的數據存儲中。

從上面,我猜想會議數據丟失了。

我被困在調查中。是否有信息作爲解決問題的線索?

回答

1

我有同樣的問題。最後我實現了春季會議的定製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並需要改進以實現高可用性。

+0

謝謝你,這個作品!我把你的提交中的東西轉換成了Java,但除此之外沒有什麼大問題。我無法相信存儲會話在App Engine中不起作用,儘管他們說它應該:/ – Lili

+0

[The solution](https:/ /github.com/int128/gradleupdate/commit/2405310dd0da4e19cf4d4b55a16f8466c1d62cc8)的作品。我製作了[DatastoreSessionRepository](https://github.com/nosix/appengine-java8-spring-oauth2/blob/master/application/src/main/kotlin/org/musyozoku/appengine/session/DatastoreSessionRepository.kt),指對此。這也適用。非常感謝你! – nosix

+0

對於非Kotlin人員,這可能對複製粘貼有幫助(隨意用明確的代碼替換lombok) https://gist.github.com/lilianaziolek/6851c2f81be81eae2207ec863f41f484 – Lili