@@ -2,21 +2,26 @@ package io.openfuture.api.config.filter
22
33import com.fasterxml.jackson.databind.ObjectMapper
44import io.openfuture.api.config.propety.AuthorizationProperties
5+ import org.springframework.http.HttpStatus.UNAUTHORIZED
6+ import io.openfuture.api.domain.exception.ExceptionResponse
57import io.openfuture.api.domain.key.WalletApiCreateRequest
68import io.openfuture.api.service.ApplicationService
79import io.openfuture.api.util.CustomHttpRequestWrapper
810import io.openfuture.api.util.KeyGeneratorUtils
11+ import io.openfuture.api.util.currentEpochs
912import io.openfuture.api.util.differenceEpochs
10- import org.springframework.http.HttpHeaders
1113import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
1214import org.springframework.security.core.authority.SimpleGrantedAuthority
1315import org.springframework.security.core.context.SecurityContextHolder
1416import javax.servlet.*
1517import javax.servlet.http.HttpServletRequest
18+ import javax.servlet.http.HttpServletResponse
1619
1720
1821class PublicApiAuthorizationFilter (
19- private val applicationService : ApplicationService
22+ private val applicationService : ApplicationService ,
23+ private val mapper : ObjectMapper ,
24+ private val properties : AuthorizationProperties
2025): Filter {
2126
2227 override fun init (filterConfig : FilterConfig ? ) {
@@ -25,29 +30,35 @@ class PublicApiAuthorizationFilter(
2530
2631 override fun doFilter (request : ServletRequest , response : ServletResponse , chain : FilterChain ) {
2732 request as HttpServletRequest
33+ response as HttpServletResponse
2834
29- if (request.requestURI.startsWith(" /public" ) && null == SecurityContextHolder .getContext().authentication && request.getHeader(" X-API-KEY" ) != null ) {
35+ if (request.requestURI.startsWith(" /public" ) && request.getHeader(" X-API-KEY" ) != null ) {
3036
3137 val accessKey = request.getHeader(" X-API-KEY" )
3238 val signature = request.getHeader(" X-API-SIGNATURE" )
39+ val expirePeriod = 10L ;
3340
3441 val requestWrapper = CustomHttpRequestWrapper (request)
35- val walletApiCreateRequest = ObjectMapper () .readValue(requestWrapper.bodyInStringFormat, WalletApiCreateRequest ::class .java)
42+ val walletApiCreateRequest = mapper .readValue(requestWrapper.bodyInStringFormat, WalletApiCreateRequest ::class .java)
3643
37- val diffMinutes = differenceEpochs(System .currentTimeMillis() / 1000L , walletApiCreateRequest.timestamp.toLong())
44+ val diffMinutes = differenceEpochs(currentEpochs() , walletApiCreateRequest.timestamp.toLong())
3845
3946 val application = applicationService.getByAccessKey(accessKey)
4047
4148 val hmacSha256 = application.let {
4249 KeyGeneratorUtils .calcHmacSha256(it.apiSecretKey, walletApiCreateRequest.toString())
4350 }
4451
45- if (hmacSha256 == signature && diffMinutes < 10 ){
46- val token = UsernamePasswordAuthenticationToken (application.user, null ,
47- application.user.roles.map { SimpleGrantedAuthority (" ROLE_APPLICATION" ) })
48- SecurityContextHolder .getContext().authentication = token
52+ if (hmacSha256 != signature || diffMinutes > expirePeriod) {
53+ val exceptionResponse = ExceptionResponse (UNAUTHORIZED .value(), " Signature mismatch or request timeout" )
54+ response.status = exceptionResponse.status
55+ response.writer.write(mapper.writeValueAsString(exceptionResponse))
56+ return
4957 }
5058
59+ val token = UsernamePasswordAuthenticationToken (application.user, null , listOf (SimpleGrantedAuthority (" ROLE_APPLICATION" )))
60+ SecurityContextHolder .getContext().authentication = token
61+
5162 chain.doFilter(requestWrapper, response);
5263 return
5364 }
0 commit comments