public Boolean verifyState ( HttpServletRequest req , HttpServletResponse res , String responseState , ConvergedClientConfig clientConfig ) { if ( responseState . length ( ) < OidcUtil . STATEVALUE_LENGTH ) { return false ; // the state does not even match the length, the verification failed } long clockSkewMillSeconds = clientConfig . getClockSkewInSeconds ( ) * 1000 ; long allowHandleTimeMillSeconds = ( clientConfig . getAuthenticationTimeLimitInSeconds ( ) * 1000 ) + clockSkewMillSeconds ; // allow 7 minutes plust clockSkew javax . servlet . http . Cookie [ ] cookies = req . getCookies ( ) ; String cookieName = ClientConstants . WAS_OIDC_STATE_KEY + HashUtils . getStrHashCode ( responseState ) ; String stateKey = CookieHelper . getCookieValue ( cookies , cookieName ) ; // this could be null if used OidcClientUtil . invalidateReferrerURLCookie ( req , res , cookieName ) ; String cookieValue = HashUtils . createStateCookieValue ( clientConfig , responseState ) ; if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "stateKey:'" + stateKey + "' cookieValue:'" + cookieValue + "'" ) ; } if ( cookieValue . equals ( stateKey ) ) { long lNumber = OidcUtil . convertNormalizedTimeStampToLong ( responseState ) ; long lDate = ( new Date ( ) ) . getTime ( ) ; // lDate can not be earlier than lNumber by clockSkewMillSeconds // lDate can not be later than lNumber by clockSkewMllSecond + allowHandleTimeSeconds long difference = lDate - lNumber ; if ( difference < 0 ) { difference *= - 1 ; if ( difference >= clockSkewMillSeconds ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "error current: " + lDate + " ran at:" + lNumber ) ; } } return difference < clockSkewMillSeconds ; } else { if ( difference >= allowHandleTimeMillSeconds ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "error current: " + lDate + " ran at:" + lNumber ) ; } } return difference < allowHandleTimeMillSeconds ; } } return false ; }
Determine the name of the state cookie based on the state name key + hashcode of response state . Retrieve that cookie value then create a check value by hashing the clinet config and resonseState again . If the hash result equals the cookie value request is valid proceed to check the clock skew .