diff --git a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/config/WebSecurityConfig.kt b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/config/WebSecurityConfig.kt index 8162a75..928c7e9 100644 --- a/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/config/WebSecurityConfig.kt +++ b/src/main/kotlin/dev/fyloz/trial/colorrecipesexplorer/config/WebSecurityConfig.kt @@ -7,6 +7,7 @@ import dev.fyloz.trial.colorrecipesexplorer.model.EmployeePermission import dev.fyloz.trial.colorrecipesexplorer.service.EmployeeService import dev.fyloz.trial.colorrecipesexplorer.service.EmployeeServiceImpl import dev.fyloz.trial.colorrecipesexplorer.service.EmployeeUserDetailsServiceImpl +import io.jsonwebtoken.ExpiredJwtException import io.jsonwebtoken.Jwts import io.jsonwebtoken.SignatureAlgorithm import org.slf4j.Logger @@ -43,10 +44,7 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource import org.springframework.web.util.WebUtils import java.util.* import javax.annotation.PostConstruct -import javax.servlet.Filter import javax.servlet.FilterChain -import javax.servlet.ServletRequest -import javax.servlet.ServletResponse import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse @@ -245,31 +243,49 @@ class JwtAuthorizationFilter( authenticationManager: AuthenticationManager ) : BasicAuthenticationFilter(authenticationManager) { override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) { - val authorizationCookie = WebUtils.getCookie(request, authorizationCookieName) - val authorizationValue = - if (authorizationCookie != null) authorizationCookie.value else request.getHeader(authorizationCookieName) - if (authorizationValue != null && authorizationValue.startsWith("Bearer") && authorizationValue !in blacklistedJwtTokens) { - val authenticationToken = getAuthentication(authorizationValue) - SecurityContextHolder.getContext().authentication = authenticationToken - } else { + fun tryLoginFromBearer(): Boolean { + val authorizationCookie = WebUtils.getCookie(request, authorizationCookieName) + // Check for an authorization token cookie or header + val authorizationToken = if (authorizationCookie != null) + authorizationCookie.value + else + request.getHeader(authorizationCookieName) + + // An authorization token is valid if it starts with "Bearer", is not expired and is not blacklisted + if (authorizationToken != null && authorizationToken.startsWith("Bearer") && authorizationToken !in blacklistedJwtTokens) { + val authenticationToken = getAuthentication(authorizationToken) ?: return false + SecurityContextHolder.getContext().authentication = authenticationToken + return true + } + return false + } + + fun tryLoginFromDefaultGroupCookie() { val defaultGroupCookie = WebUtils.getCookie(request, defaultGroupCookieName) if (defaultGroupCookie != null) { val authenticationToken = getAuthenticationToken(defaultGroupCookie.value) SecurityContextHolder.getContext().authentication = authenticationToken } } + + if (!tryLoginFromBearer()) + tryLoginFromDefaultGroupCookie() chain.doFilter(request, response) } private fun getAuthentication(token: String): UsernamePasswordAuthenticationToken? { val jwtSecret = securityConfigurationProperties.jwtSecret Assert.notNull(jwtSecret, "No JWT secret has been defined.") - val employeeId = Jwts.parser() - .setSigningKey(jwtSecret!!.toByteArray()) - .parseClaimsJws(token.replace("Bearer", "")) - .body - .subject - return if (employeeId != null) getAuthenticationToken(employeeId) else null + return try { + val employeeId = Jwts.parser() + .setSigningKey(jwtSecret!!.toByteArray()) + .parseClaimsJws(token.replace("Bearer", "")) + .body + .subject + if (employeeId != null) getAuthenticationToken(employeeId) else null + } catch (_: ExpiredJwtException) { + null + } } private fun getAuthenticationToken(employeeId: String): UsernamePasswordAuthenticationToken {