Skip to content

Commit

Permalink
Make backend session stateless
Browse files Browse the repository at this point in the history
  • Loading branch information
Isti01 committed Sep 10, 2024
1 parent f99db9d commit 4a5089d
Show file tree
Hide file tree
Showing 8 changed files with 21 additions and 112 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package hu.bme.sch.cmsch.component.login

import hu.bme.sch.cmsch.component.app.ApplicationComponent
import hu.bme.sch.cmsch.component.token.SESSION_TOKEN_COLLECTOR_ATTRIBUTE
import hu.bme.sch.cmsch.config.StartupPropertyConfig
import hu.bme.sch.cmsch.service.JwtTokenProvider
import hu.bme.sch.cmsch.util.getUserOrNull
import jakarta.servlet.http.Cookie
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
Expand Down Expand Up @@ -37,11 +35,7 @@ class AuthschLoginController(
}

@GetMapping("/control/post-login")
fun postLogin(request: HttpServletRequest, httpResponse: HttpServletResponse, auth: Authentication?) {
if (request.getSession(true).getAttribute(SESSION_TOKEN_COLLECTOR_ATTRIBUTE) != null) {
httpResponse.sendRedirect("/api/token-after-login")
return
}
fun postLogin(httpResponse: HttpServletResponse, auth: Authentication?) {
httpResponse.sendRedirect(
if (auth != null && auth.isAuthenticated)
"/control/open-site"
Expand All @@ -51,21 +45,17 @@ class AuthschLoginController(
}

@GetMapping("/control/login")
fun loginDefault(request: HttpServletRequest): String {
fun loginDefault(): String {
return "redirect:${applicationComponent.siteUrl.getValue()}login"
}

@GetMapping("/control/logout")
fun logout(request: HttpServletRequest, auth: Authentication?, httpResponse: HttpServletResponse): String {
fun logout(auth: Authentication?, httpResponse: HttpServletResponse): String {
log.info("Logging out from user {}", auth?.getUserOrNull()?.internalId ?: "n/a")

try {
httpResponse.addCookie(createJwtCookie(null).apply { maxAge = 0 })
SecurityContextHolder.getContext().authentication = null
val session = request.getSession(false)
session?.invalidate()
request.changeSessionId()

} catch (e: Exception) {
// It should be logged out anyway
}
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import org.springframework.web.bind.annotation.*
import java.net.URLEncoder
import java.nio.charset.StandardCharsets

const val SESSION_TOKEN_COLLECTOR_ATTRIBUTE = "TOKEN_COLLECTOR_ATTRIBUTE"

@Controller
@RequestMapping("/api")
@ConditionalOnBean(TokenComponent::class)
Expand Down Expand Up @@ -56,23 +54,11 @@ class TokenApiController(
}
}

@GetMapping("/token-after-login")
fun submitTokenAfterLogin(request: HttpServletRequest, auth: Authentication): String {
val token = request.getSession(true).getAttribute(SESSION_TOKEN_COLLECTOR_ATTRIBUTE)?.toString()
request.getSession(true).setAttribute(SESSION_TOKEN_COLLECTOR_ATTRIBUTE, null)
return if (token == null) {
"redirect:${applicationComponent.siteUrl.getValue()}?error=failed-to-redeem"
} else {
collectToken(auth, token)
}
}

@GetMapping("/qr/{token}")
fun readQrManually(@PathVariable token: String, request: HttpServletRequest, auth: Authentication?): String {
fun readQrManually(@PathVariable token: String, auth: Authentication?): String {
return try {
val user = auth?.getUserOrNull()
if (user == null) {
request.getSession(true).setAttribute(SESSION_TOKEN_COLLECTOR_ATTRIBUTE, token)
"redirect:${applicationComponent.siteUrl.getValue()}login"
} else {
collectToken(auth, token)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper
import hu.bme.sch.cmsch.component.countdown.CountdownFilterConfigurer
import hu.bme.sch.cmsch.component.login.LoginComponent
import hu.bme.sch.cmsch.component.login.LoginService
import hu.bme.sch.cmsch.component.login.SessionFilterConfigurer
import hu.bme.sch.cmsch.component.login.authsch.CmschAuthschUser
import hu.bme.sch.cmsch.component.login.authsch.ProfileResponse
import hu.bme.sch.cmsch.component.login.google.CmschGoogleUser
Expand All @@ -26,6 +25,7 @@ import org.springframework.retry.annotation.EnableRetry
import org.springframework.security.config.Customizer
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
Expand All @@ -48,7 +48,6 @@ open class SecurityConfig(
private val countdownConfigurer: Optional<CountdownFilterConfigurer>,
private val authschLoginService: LoginService,
private val loginComponent: LoginComponent,
private val startupPropertyConfig: StartupPropertyConfig,
@Value("\${custom.keycloak.base-url:http://localhost:8081/auth/realms/master}") private val keycloakBaseUrl: String,
private val auditLogService: AuditLogService
) {
Expand Down Expand Up @@ -143,7 +142,7 @@ open class SecurityConfig(
http.formLogin { it.disable() }
http.exceptionHandling { it.accessDeniedPage("/403") }
http.with(JwtConfigurer(jwtTokenProvider), Customizer.withDefaults())
http.with(SessionFilterConfigurer(startupPropertyConfig), Customizer.withDefaults())
http.sessionManagement { it.sessionCreationPolicy(SessionCreationPolicy.STATELESS) }
http.oauth2Login { oauth2 ->
oauth2.loginPage("/oauth2/authorization")
.authorizationEndpoint {
Expand All @@ -162,7 +161,8 @@ open class SecurityConfig(
}
}
.userService { resolveAuthschUser(it) }
}.defaultSuccessUrl("/control/post-login")
}
.defaultSuccessUrl("/control/post-login")
}
countdownConfigurer.ifPresent { http.with(it, Customizer.withDefaults()) }
http.csrf {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ data class StartupPropertyConfig @ConstructorBinding constructor(
val challengeOwnershipMode: OwnershipType,
val raceOwnershipMode: OwnershipType,

// Increased session
val increasedSessionTime: Int,

// Microservice
val masterRole: Boolean,
val riddleMicroserviceEnabled: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ class InstanceInfoDashboard(
listOf("Mailgun token length", startupPropertyConfig.mailgunToken.length.toString()),
listOf("JWT enabled", startupPropertyConfig.jwtEnabled.toString()),
listOf("Session validity (ms)", startupPropertyConfig.sessionValidityInMilliseconds.toString()),
listOf("Increased session time (ms)", startupPropertyConfig.increasedSessionTime.toString()),
listOf("Profile QR enabled", startupPropertyConfig.profileQrEnabled.toString()),
listOf("Profile QR prefix", startupPropertyConfig.profileQrPrefix),
listOf("Profile generation target", startupPropertyConfig.profileGenerationTarget),
Expand Down
27 changes: 13 additions & 14 deletions backend/src/main/kotlin/hu/bme/sch/cmsch/jwt/JwtTokenFilter.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package hu.bme.sch.cmsch.jwt

import hu.bme.sch.cmsch.service.JwtTokenProvider
import org.slf4j.LoggerFactory
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.web.filter.GenericFilterBean
import java.io.IOException
import jakarta.servlet.FilterChain
import jakarta.servlet.ServletException
import jakarta.servlet.ServletRequest
import jakarta.servlet.ServletResponse
import jakarta.servlet.http.HttpServletRequest
import org.slf4j.LoggerFactory
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.web.filter.GenericFilterBean
import java.io.IOException


class JwtTokenFilter(
Expand All @@ -22,17 +22,16 @@ class JwtTokenFilter(
@Throws(IOException::class, ServletException::class)
override fun doFilter(req: ServletRequest, res: ServletResponse, filterChain: FilterChain) {
val httpRequest = req as HttpServletRequest
if (httpRequest.servletPath.startsWith("/api/")) {
val token: String? = jwtTokenProvider.resolveToken(httpRequest)
try {
if (token != null && jwtTokenProvider.validateToken(token)) {
val auth: Authentication = jwtTokenProvider.getAuthentication(token)
SecurityContextHolder.getContext().authentication = auth
}
} catch (e: Exception) {
log.warn("Invalid token: {} user cannot be resolved because: {}", token, e.message)
val token: String? = jwtTokenProvider.resolveToken(httpRequest)
try {
if (token != null && jwtTokenProvider.validateToken(token)) {
val auth: Authentication = jwtTokenProvider.getAuthentication(token)
SecurityContextHolder.getContext().authentication = auth
}
} catch (e: Exception) {
log.warn("Invalid token: {} user cannot be resolved because: {}", token, e.message)
}

filterChain.doFilter(req, res)
}

Expand Down

0 comments on commit 4a5089d

Please sign in to comment.