-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9a1935f
commit e7dd69d
Showing
7 changed files
with
234 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.example.bff.auth.sessions | ||
|
||
import org.springframework.session.SessionIdGenerator | ||
|
||
/**********************************************************************************************************************/ | ||
/**************************************************** SESSION ID GENERATOR ********************************************/ | ||
/**********************************************************************************************************************/ | ||
|
||
// more here: | ||
// https://docs.spring.io/spring-session/reference/configuration/common.html#changing-how-session-ids-are-generated | ||
|
||
internal class CustomSessionIdGenerator : SessionIdGenerator { | ||
|
||
override fun generate(): String { | ||
// use a UUID with a custom prefix or other unique generation logic | ||
return "BFF-${java.util.UUID.randomUUID()}" | ||
} | ||
|
||
} | ||
|
||
/**********************************************************************************************************************/ | ||
/**************************************************** END OF KOTLIN ***************************************************/ | ||
/**********************************************************************************************************************/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package com.example.bff.auth.sessions | ||
|
||
import com.example.bff.props.SpringSessionProperties | ||
import org.springframework.context.annotation.Bean | ||
import org.springframework.context.annotation.Configuration | ||
import org.springframework.data.redis.core.ReactiveRedisOperations | ||
import org.springframework.session.MapSession | ||
import org.springframework.session.config.ReactiveSessionRepositoryCustomizer | ||
import org.springframework.session.data.redis.ReactiveRedisIndexedSessionRepository | ||
import org.springframework.session.data.redis.RedisSessionMapper | ||
import reactor.core.publisher.Mono | ||
import java.util.function.BiFunction | ||
|
||
/**********************************************************************************************************************/ | ||
/************************************************ REDIS CONFIGURATION *************************************************/ | ||
/**********************************************************************************************************************/ | ||
|
||
// more here: | ||
// https://docs.spring.io/spring-session/reference/configuration/redis.html#configuring-redis-session-mapper | ||
|
||
@Configuration | ||
internal class RedisSessionMapperConfig() { | ||
|
||
/** | ||
* Customizes the ReactiveRedisIndexedSessionRepository to use the SafeSessionMapper. | ||
*/ | ||
@Bean | ||
fun redisSessionRepositoryCustomizer(): ReactiveSessionRepositoryCustomizer<ReactiveRedisIndexedSessionRepository> { | ||
return ReactiveSessionRepositoryCustomizer { redisSessionRepository -> | ||
redisSessionRepository.setRedisSessionMapper( | ||
SafeRedisSessionMapper( | ||
redisSessionRepository.sessionRedisOperations | ||
) | ||
) | ||
} | ||
} | ||
|
||
/** | ||
* Implementation of SafeSessionMapper. | ||
*/ | ||
internal class SafeRedisSessionMapper( | ||
private var redisOperations: ReactiveRedisOperations<String, Any> | ||
) : BiFunction<String, Map<String, Any>, Mono<MapSession>>{ | ||
|
||
private val redisProperties = SpringSessionProperties() | ||
private val delegate = RedisSessionMapper() | ||
|
||
/** | ||
* Custom session mapper that delegates to the default RedisSessionMapper. | ||
* If an exception occurs, the session is deleted from Redis. | ||
*/ | ||
override fun apply(sessionId: String, map: Map<String, Any>): Mono<MapSession> { | ||
return Mono.defer { | ||
try { | ||
// attempt to apply the session mapping | ||
Mono.just(delegate.apply(sessionId, map)) | ||
} catch (ex: IllegalStateException) { | ||
// handle exception: delete session from Redis and return empty Mono | ||
redisOperations.delete("${redisProperties.redis?.namespace}:$sessionId") | ||
.then(Mono.empty<MapSession>()) | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
/**********************************************************************************************************************/ | ||
/**************************************************** END OF KOTLIN ***************************************************/ | ||
/**********************************************************************************************************************/ |
21 changes: 21 additions & 0 deletions
21
Spring BFF/bff/auth/sessions/SessionApplicationListener.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.example.bff.auth.sessions | ||
|
||
import com.example.bff.auth.redis.RedisConnectionFactoryConfig | ||
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer | ||
import org.springframework.stereotype.Component | ||
|
||
/**********************************************************************************************************************/ | ||
/************************************************ REDIS CONFIGURATION *************************************************/ | ||
/**********************************************************************************************************************/ | ||
|
||
// more here: | ||
// https://docs.spring.io/spring-session/reference/http-session.html#httpsession-redis-jc | ||
// https://docs.spring.io/spring-session/reference/http-session.html#_servlet_container_initialization_2 | ||
|
||
@Component | ||
internal class SessionApplicationInitialiser | ||
: AbstractHttpSessionApplicationInitializer(RedisConnectionFactoryConfig::class.java) | ||
|
||
/**********************************************************************************************************************/ | ||
/**************************************************** END OF KOTLIN ***************************************************/ | ||
/**********************************************************************************************************************/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.example.bff.auth.sessions | ||
|
||
import org.springframework.context.event.EventListener | ||
import org.springframework.session.events.SessionCreatedEvent | ||
import org.springframework.session.events.SessionDeletedEvent | ||
import org.springframework.session.events.SessionExpiredEvent | ||
import org.springframework.stereotype.Component | ||
import reactor.core.publisher.Mono | ||
|
||
/**********************************************************************************************************************/ | ||
/************************************************** SESSION CONFIGURATION *********************************************/ | ||
/**********************************************************************************************************************/ | ||
|
||
// more here: | ||
// https://docs.spring.io/spring-session/reference/configuration/reactive-redis-indexed.html#listening-session-events | ||
|
||
@Component | ||
// session event listener | ||
internal class SessionListenerConfig { | ||
|
||
@EventListener | ||
fun processSessionCreatedEvent(event: SessionCreatedEvent): Mono<Void> { | ||
return Mono.fromRunnable { | ||
// Log or print information about the created session | ||
println("Session created: ${event.sessionId}") | ||
// Your logic for session created event | ||
} | ||
} | ||
|
||
@EventListener | ||
fun processSessionDeletedEvent(event: SessionDeletedEvent): Mono<Void> { | ||
return Mono.fromRunnable { | ||
// Log or print information about the deleted session | ||
println("Session deleted: ${event.sessionId}") | ||
// Your logic for session deleted event | ||
} | ||
} | ||
|
||
@EventListener | ||
fun processSessionExpiredEvent(event: SessionExpiredEvent): Mono<Void> { | ||
return Mono.fromRunnable { | ||
// Log or print information about the expired session | ||
println("Session expired: ${event.sessionId}") | ||
// Your logic for session expired event | ||
} | ||
} | ||
} | ||
|
||
/**********************************************************************************************************************/ | ||
/**************************************************** END OF KOTLIN ***************************************************/ | ||
/**********************************************************************************************************************/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.example.bff.auth.sessions | ||
|
||
import org.springframework.session.FindByIndexNameSessionRepository | ||
import org.springframework.session.ReactiveFindByIndexNameSessionRepository | ||
import org.springframework.session.Session | ||
import org.springframework.session.data.redis.ReactiveRedisIndexedSessionRepository | ||
import org.springframework.session.data.redis.ReactiveRedisIndexedSessionRepository.RedisSession | ||
import org.springframework.stereotype.Service | ||
import reactor.core.publisher.Flux | ||
import reactor.core.publisher.Mono | ||
import java.security.Principal | ||
|
||
/**********************************************************************************************************************/ | ||
/************************************************ SESSION CONFIGURATION ***********************************************/ | ||
/**********************************************************************************************************************/ | ||
|
||
// more here: | ||
// https://docs.spring.io/spring-session/reference/configuration/redis.html#finding-all-user-sessions | ||
|
||
@Service | ||
internal class SessionService( | ||
private val sessions: ReactiveFindByIndexNameSessionRepository<RedisSession>, | ||
private val redisIndexedSessionRepository: ReactiveRedisIndexedSessionRepository | ||
) { | ||
|
||
/** | ||
* Retrieves all sessions for a specific user. | ||
* @param principal the principal whose sessions need to be retrieved | ||
* @return a Flux of sessions for the specified user | ||
*/ | ||
fun getSessions(principal: Principal): Flux<Session> { | ||
return sessions.findByPrincipalName(principal.name) | ||
.flatMapMany { sessionsMap -> | ||
Flux.fromIterable(sessionsMap.values) | ||
} | ||
} | ||
|
||
/** | ||
* Removes a specific session for a user. | ||
* @param principal the principal whose session needs to be removed | ||
* @param sessionIdToDelete the ID of the session to be removed | ||
* @return a Mono indicating completion or error | ||
*/ | ||
fun removeSession(principal: Principal, sessionIdToDelete: String): Mono<Void> { | ||
return sessions.findByPrincipalName(principal.name) | ||
.flatMap { userSessions -> | ||
if (userSessions.containsKey(sessionIdToDelete)) { | ||
redisIndexedSessionRepository.deleteById(sessionIdToDelete) | ||
} else { | ||
Mono.empty() | ||
} | ||
} | ||
} | ||
} | ||
|
||
/**********************************************************************************************************************/ | ||
/**************************************************** END OF KOTLIN ***************************************************/ | ||
/**********************************************************************************************************************/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters