2017-07-20 4 views
3

Meine Beispielanwendung funktioniert in der lokalen Umgebung. Aber es funktioniert nicht in der Java8-Standardumgebung. Das folgende Projekt ist das Beispielanwendungsprojekt.Problem mit der Verwendung von Spring OAuth in der Java8-Standardumgebung

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

Der folgende Fehler tritt in Java8 Standardumgebung:

Authentication Failed: Could not obtain access token 

I Protokolle an den Quellcode des Frühlings OAuth hinzugefügt und die Ursache untersucht. Die Ursache des Fehlers scheint zu sein, dass die Sitzungsdaten verloren gegangen sind.

Es funktionierte wie folgt:

preservedState in AuthorizationCodeAccessTokenProvider::getParametersForTokenRequest null ist. Also, wird geworfen. Dies ist die Ursache des Fehlers.

setPreservedState Methode wird in OAuth2RestTemplate::acquireAccessToken aufgerufen. Zu diesem Zeitpunkt ist preservedState auf null gesetzt.

DefaultOAuth2ClientContext Instanz hat preservedState. preservedState von DefaultOAuth2ClientContext Instanz ist Null in Java8-Standardumgebung. Aber, es ist nicht null in der lokalen Umgebung.

DefaultOAuth2ClientContext Instanz in der Sitzung gespeichert werden. Ich verstehe, dass es im Arbeitsspeicher in der lokalen Umgebung und im Datenspeicher in der Standardumgebung gespeichert ist.

Aus dem oben genannten, vermutete ich, dass die Sitzungsdaten verloren gingen.

Ich steckte in der Untersuchung fest. Gibt es Informationen, die als Anhaltspunkt für die Lösung dienen?

Antwort

1

Ich hatte das gleiche Problem. Schließlich implementiert ich eine benutzerdefinierte SessionRepository von Spring Session wie folgt: (see also this commit)

Repository Klasse:

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 Klasse:

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 
} 

Das zu dieser Zeit gut zu funktionieren scheint, aber es nutzt nur Memcache und muss für hohe Verfügbarkeit verbessert werden.

+0

Danke Mann, das funktioniert! Ich habe Sachen in Ihrem Commit in Java umgewandelt, aber ansonsten hatte ich keine großen Probleme.Ich kann nicht glauben, dass das Speichern von Sitzungen in App Engine nicht funktioniert, obwohl sie sagen:/ – Lili

+0

[Die Lösung] (https://github.com/int128/graduleupdate/commit/2405310dd0da4e19cf4d4b55a16f8466c1d62cc8) funktioniert. Ich habe [DatastoreSessionRepository] (https://github.com/nosix/appengine-java8-spring-oauth2/blob/master/application/src/main/kotlin/org/musyozoku/appengine/session/DatastoreSessionRepository.kt) erstellt und darauf verwiesen dazu. Das funktioniert auch. Vielen Dank! – nosix

+0

Für Leute, die nicht von Kotlin kommen, könnte dies hilfreich für das Kopieren und Einfügen sein (zögern Sie nicht, Lombok durch expliziten Code zu ersetzen) https://gist.github.com/lilianaziolek/6851c2f81be81eae2207ec863f41f484 – Lili

Verwandte Themen