代码之家  ›  专栏  ›  技术社区  ›  Sachin

Spring Session响应MongoDB-如何处理属性

  •  0
  • Sachin  · 技术社区  · 1 年前

    我对如何使用MongoDB Session和Spring Session处理属性感到困惑。我使用Redis时遇到了这个问题,但由于缺乏Spring的支持、几个池化错误以及Redis缓存的费用,这意味着我希望切换到MongoDB

    我想将此保存为会话的属性,但不确定如何保存:

    @Repository
    internal class MongoAuthorizationRequestRepository(
        private val mongoSerialiserConfig: MongoSerialiserConfig
    ) : ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> {
    
        private val logger = LoggerFactory.getLogger(MongoSecurityContextRepository::class.java)
        private val springAuthorizationRequestAttrName: String = "AUTHORIZATION_REQUEST"
    
        override fun saveAuthorizationRequest(
            authorizationRequest: OAuth2AuthorizationRequest?,
            exchange: ServerWebExchange
        ): Mono<Void> {
            logger.info("SAVING AUTHORIZATION REQUEST")
    
            return exchange.session
                .doOnNext { session ->
                    if (authorizationRequest?.state == null) {
                        logger.info("Authorization Request State cannot be empty")
                    } else {
                        session.attributes[springAuthorizationRequestAttrName] = authorizationRequest
                        logger.info("Authorization Request state: ${authorizationRequest.state}")
                        logger.info("Saved Authorization Request $authorizationRequest in WebSession: $session")
                    }
                }.then()
        }
    
        override fun loadAuthorizationRequest(exchange: ServerWebExchange): Mono<OAuth2AuthorizationRequest?> {
            logger.info("LOADING AUTHORIZATION REQUEST")
            val state = getStateParameter(exchange) ?: return Mono.empty()
            return exchange.session
                .flatMap { session ->
                    val authorizationRequest = getAuthorizationRequest(session)
                    if (state == authorizationRequest?.state) {
                        logger.info("Loading authorization request")
                        Mono.just(authorizationRequest)
                    } else {
                        logger.warn("State in request does not match Authorization Request state in Session: $session")
                        Mono.empty()
                    }
                }
        }
    
        override fun removeAuthorizationRequest(exchange: ServerWebExchange): Mono<OAuth2AuthorizationRequest?> {
            logger.info("REMOVING AUTHORIZATION REQUEST")
            val state = getStateParameter(exchange) ?: return Mono.empty()
            return exchange.session
                .flatMap { session ->
                    val authorizationRequest = getAuthorizationRequest(session)
                    if (state == authorizationRequest?.state) {
                        session.attributes.remove(this.springAuthorizationRequestAttrName)
                        logger.info("Removed authorization request")
                        Mono.just(authorizationRequest)
                    } else {
                        logger.info("State in request does not match Authorization Request state in Session: $session")
                        Mono.empty()
                    }
                }
        }
    
        // Helper methods
        private fun getStateParameter(exchange: ServerWebExchange): String? {
            requireNotNull(exchange) { "exchange cannot be null" }
            return exchange.request.queryParams[OAuth2ParameterNames.STATE]?.firstOrNull()
        }
    
        private fun getAuthorizationRequest(session: WebSession): OAuth2AuthorizationRequest? {
            Assert.notNull(session, "session cannot be null")
            val authRequestAttr = session.getAttribute<Map<String, Any>>(springAuthorizationRequestAttrName)
            if (authRequestAttr != null) {
                // Deserialize from Map to SecurityContext
                val map = authRequestAttr as? Map<String, Any>
                try {
                    val authorizationRequest = mongoSerialiserConfig.customObjectMapper()
                        .convertValue(map, OAuth2AuthorizationRequest::class.java)
                    logger.info("Successfully deserialized Authorization Request: $authorizationRequest")
                    return authorizationRequest
                } catch (e: Exception) {
                    logger.error("Error deserializing Authorization Request: ${e.message}", e)
                    return null
                }
            } else {
                logger.warn("No Authorization Request found in WebSession")
                return null
            }
        }
    
    }
    

    已有2个转换器可用:

    https://github.com/spring-projects/spring-session/blob/main/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/JacksonMongoSessionConverter.java

    https://github.com/spring-projects/spring-session/blob/main/spring-session-data-mongodb/src/main/java/org/springframework/session/data/mongo/JdkMongoSessionConverter.java

     fun jdkMongoSessionConverter(): JdkMongoSessionConverter {
            val converter = JdkMongoSessionConverter(Duration.ofMinutes(7200))
            return converter
        }
    
        @Bean
        fun jacksonMongoSessionConverter(
            mongoSerialiserConfig: MongoSerialiserConfig
        ): JacksonMongoSessionConverter {
            return JacksonMongoSessionConverter(mongoSerialiserConfig.customObjectMapper())
        }
    

    我在第二个名为customObjectMapper的对象映射器中添加了一个自定义对象映射器。这篇文章允许的代码太多,所以可以在这里找到:

    https://github.com/dreamstar-enterprises/docs/blob/master/Spring%20BFF/bff/auth/serialisers/MongoSerialiserConfig.kt

    但我遇到的问题是,转换器使用MongoSession和docDB,而不是来自交易所的Websession。那么,你是如何序列化和去序列化的呢?

    有什么想法吗?

    0 回复  |  直到 1 年前
    推荐文章