-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #809 from navikt/kotlin-filter
convert filters to kotlin
- Loading branch information
Showing
14 changed files
with
564 additions
and
554 deletions.
There are no files selected for viewing
3 changes: 2 additions & 1 deletion
3
...rc/main/java/no/nav/security/token/support/core/context/TokenValidationContextHolder.java
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 |
---|---|---|
@@ -1,8 +1,9 @@ | ||
package no.nav.security.token.support.core.context; | ||
|
||
|
||
public interface TokenValidationContextHolder { | ||
|
||
TokenValidationContext getTokenValidationContext(); | ||
|
||
void setTokenValidationContext(TokenValidationContext tokenValidationContext); | ||
} | ||
} |
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
92 changes: 0 additions & 92 deletions
92
...ation-filter/src/main/java/no/nav/security/token/support/filter/JwtTokenExpiryFilter.java
This file was deleted.
Oops, something went wrong.
85 changes: 0 additions & 85 deletions
85
...n-filter/src/main/java/no/nav/security/token/support/filter/JwtTokenValidationFilter.java
This file was deleted.
Oops, something went wrong.
83 changes: 83 additions & 0 deletions
83
...ation-filter/src/main/kotlin/no/nav/security/token/support/filter/JwtTokenExpiryFilter.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,83 @@ | ||
package no.nav.security.token.support.filter | ||
|
||
import jakarta.servlet.Filter | ||
import jakarta.servlet.FilterChain | ||
import jakarta.servlet.FilterConfig | ||
import jakarta.servlet.ServletException | ||
import jakarta.servlet.ServletRequest | ||
import jakarta.servlet.ServletResponse | ||
import jakarta.servlet.http.HttpServletRequest | ||
import jakarta.servlet.http.HttpServletResponse | ||
import java.io.IOException | ||
import java.time.LocalDateTime | ||
import java.time.ZoneId | ||
import java.time.temporal.ChronoUnit.MINUTES | ||
import java.util.Date | ||
import org.slf4j.Logger | ||
import org.slf4j.LoggerFactory | ||
import no.nav.security.token.support.core.JwtTokenConstants | ||
import no.nav.security.token.support.core.context.TokenValidationContextHolder | ||
import no.nav.security.token.support.core.jwt.JwtTokenClaims | ||
|
||
/** | ||
* Checks the expiry time in a validated token against a preconfigured threshold | ||
* and returns a custom http header if this threshold is reached. | ||
* | ||
* | ||
* Can be used to check if the token is about to expire and inform the caller | ||
*/ | ||
class JwtTokenExpiryFilter(private val contextHolder : TokenValidationContextHolder, private val expiryThresholdInMinutes : Long) : Filter { | ||
|
||
override fun doFilter(request : ServletRequest, response : ServletResponse, chain : FilterChain) { | ||
if (request is HttpServletRequest) { | ||
addHeaderOnTokenExpiryThreshold(response as HttpServletResponse) | ||
chain.doFilter(request, response) | ||
} | ||
else { | ||
chain.doFilter(request, response) | ||
} | ||
} | ||
|
||
override fun destroy() {} | ||
|
||
override fun init(filterConfig : FilterConfig) {} | ||
|
||
private fun addHeaderOnTokenExpiryThreshold(response : HttpServletResponse) { | ||
val tokenValidationContext = contextHolder.tokenValidationContext | ||
LOG.debug("Getting TokenValidationContext: {}", tokenValidationContext) | ||
if (tokenValidationContext != null) { | ||
LOG.debug("Getting issuers from validationcontext {}", tokenValidationContext.issuers) | ||
for (issuer in tokenValidationContext.issuers) { | ||
val jwtTokenClaims = tokenValidationContext.getClaims(issuer) | ||
if (tokenExpiresBeforeThreshold(jwtTokenClaims)) { | ||
LOG.debug("Setting response header {}", JwtTokenConstants.TOKEN_EXPIRES_SOON_HEADER) | ||
response.setHeader(JwtTokenConstants.TOKEN_EXPIRES_SOON_HEADER, "true") | ||
} | ||
else { | ||
LOG.debug("Token is still within expiry threshold.") | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun tokenExpiresBeforeThreshold(jwtTokenClaims : JwtTokenClaims) : Boolean { | ||
val expiryDate = jwtTokenClaims["exp"] as Date | ||
val expiry = LocalDateTime.ofInstant(expiryDate.toInstant(), ZoneId.systemDefault()) | ||
val minutesUntilExpiry = LocalDateTime.now().until(expiry, MINUTES) | ||
LOG.debug("Checking token at time {} with expirationTime {} for how many minutes until expiry: {}", | ||
LocalDateTime.now(), expiry, minutesUntilExpiry) | ||
if (minutesUntilExpiry <= expiryThresholdInMinutes) { | ||
LOG.debug("There are {} minutes until expiry which is equal to or less than the configured threshold {}", | ||
minutesUntilExpiry, expiryThresholdInMinutes) | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
override fun toString() = ("${javaClass.getSimpleName()} [contextHolder=$contextHolder, expiryThresholdInMinutes=$expiryThresholdInMinutes]") | ||
|
||
companion object { | ||
|
||
private val LOG : Logger = LoggerFactory.getLogger(JwtTokenExpiryFilter::class.java) | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
...n-filter/src/main/kotlin/no/nav/security/token/support/filter/JwtTokenValidationFilter.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,53 @@ | ||
package no.nav.security.token.support.filter | ||
|
||
import jakarta.servlet.Filter | ||
import jakarta.servlet.FilterChain | ||
import jakarta.servlet.FilterConfig | ||
import jakarta.servlet.ServletRequest | ||
import jakarta.servlet.ServletResponse | ||
import jakarta.servlet.http.HttpServletRequest | ||
import jakarta.servlet.http.HttpServletResponse | ||
import no.nav.security.token.support.core.context.TokenValidationContextHolder | ||
import no.nav.security.token.support.core.http.HttpRequest | ||
import no.nav.security.token.support.core.http.HttpRequest.NameValue | ||
import no.nav.security.token.support.core.validation.JwtTokenValidationHandler | ||
|
||
open class JwtTokenValidationFilter(private val jwtTokenValidationHandler : JwtTokenValidationHandler, private val contextHolder : TokenValidationContextHolder) : Filter { | ||
|
||
override fun destroy() {} | ||
|
||
override fun doFilter(request : ServletRequest, response : ServletResponse, chain : FilterChain) { | ||
if (request is HttpServletRequest) { | ||
doTokenValidation(request, response as HttpServletResponse, chain) | ||
} | ||
else { | ||
chain.doFilter(request, response) | ||
} | ||
} | ||
|
||
override fun init(filterConfig : FilterConfig) {} | ||
|
||
private fun doTokenValidation(request : HttpServletRequest, response : HttpServletResponse, chain : FilterChain) { | ||
contextHolder.tokenValidationContext = jwtTokenValidationHandler.getValidatedTokens(fromHttpServletRequest(request)) | ||
try { | ||
chain.doFilter(request, response) | ||
} | ||
finally { | ||
contextHolder.tokenValidationContext = null | ||
} | ||
} | ||
|
||
companion object { | ||
|
||
@JvmStatic | ||
fun fromHttpServletRequest(request: HttpServletRequest) = object : HttpRequest { | ||
override fun getHeader(headerName: String) = request.getHeader(headerName) | ||
override fun getCookies() = request.cookies?.map { | ||
object : NameValue { | ||
override fun getName() = it.name | ||
override fun getValue() = it.value | ||
} | ||
}?.toTypedArray() | ||
} | ||
} | ||
} |
Oops, something went wrong.