diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/AuthschLoginController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/AuthschLoginController.kt index d71d99df1..74fc5c5b1 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/AuthschLoginController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/AuthschLoginController.kt @@ -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 @@ -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" @@ -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 } diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/SessionFilterConfigurer.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/SessionFilterConfigurer.kt deleted file mode 100644 index 4106ff33c..000000000 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/SessionFilterConfigurer.kt +++ /dev/null @@ -1,21 +0,0 @@ -package hu.bme.sch.cmsch.component.login - -import hu.bme.sch.cmsch.config.StartupPropertyConfig -import org.springframework.security.config.annotation.SecurityConfigurerAdapter -import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.web.DefaultSecurityFilterChain -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - -class SessionFilterConfigurer( - private val startupPropertyConfig: StartupPropertyConfig -) : SecurityConfigurerAdapter() { - - override fun configure(http: HttpSecurity) { - http.addFilterAfter( - SessionIncreaseFilter(startupPropertyConfig), - UsernamePasswordAuthenticationFilter::class.java - ) - } - -} - diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/SessionIncreaseFilter.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/SessionIncreaseFilter.kt deleted file mode 100644 index 3b26b6a82..000000000 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/login/SessionIncreaseFilter.kt +++ /dev/null @@ -1,41 +0,0 @@ -package hu.bme.sch.cmsch.component.login - -import hu.bme.sch.cmsch.config.StartupPropertyConfig -import hu.bme.sch.cmsch.service.ControlPermissions -import hu.bme.sch.cmsch.util.getUserOrNull -import org.slf4j.LoggerFactory -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 - -class SessionIncreaseFilter( - private val startupPropertyConfig: StartupPropertyConfig -) : GenericFilterBean() { - - private val log = LoggerFactory.getLogger(javaClass) - - @Throws(IOException::class, ServletException::class) - override fun doFilter(servletRequest: ServletRequest, response: ServletResponse, filterChain: FilterChain) { - val request = servletRequest as HttpServletRequest - if (request.servletPath.startsWith("/admin/")) { - val session = request.getSession(true) - val user = SecurityContextHolder.getContext()?.authentication?.getUserOrNull() - if (user?.let { ControlPermissions.PERMISSION_INCREASED_SESSION_DURATION.validate(it) } == true) { - log.debug( - "Increasing session time for user {} is {}", - user.userName, - startupPropertyConfig.increasedSessionTime - ) - session.maxInactiveInterval = startupPropertyConfig.increasedSessionTime - } - } - - filterChain.doFilter(servletRequest, response) - } - -} diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenApiController.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenApiController.kt index 6e4e04f59..f116a7ef9 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenApiController.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/component/token/TokenApiController.kt @@ -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) @@ -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) diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt index e39a905cf..9ed4f9f1e 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/config/SecurityConfig.kt @@ -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 @@ -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 @@ -48,7 +48,6 @@ open class SecurityConfig( private val countdownConfigurer: Optional, 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 ) { @@ -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 { @@ -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 { diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/config/StartupPropertyConfig.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/config/StartupPropertyConfig.kt index 6b136fbc3..f6e79f0e6 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/config/StartupPropertyConfig.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/config/StartupPropertyConfig.kt @@ -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, diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/dashboard/InstanceInfoDashboard.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/dashboard/InstanceInfoDashboard.kt index 3c78de6a9..14838797f 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/dashboard/InstanceInfoDashboard.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/controller/dashboard/InstanceInfoDashboard.kt @@ -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), diff --git a/backend/src/main/kotlin/hu/bme/sch/cmsch/jwt/JwtTokenFilter.kt b/backend/src/main/kotlin/hu/bme/sch/cmsch/jwt/JwtTokenFilter.kt index e7a3637b6..dd75424a7 100644 --- a/backend/src/main/kotlin/hu/bme/sch/cmsch/jwt/JwtTokenFilter.kt +++ b/backend/src/main/kotlin/hu/bme/sch/cmsch/jwt/JwtTokenFilter.kt @@ -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( @@ -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) }