Carma Robot created CXF-5684:
--------------------------------

             Summary: Flaw in token storing logic when configured to allow 
token renewal after expiry
                 Key: CXF-5684
                 URL: https://issues.apache.org/jira/browse/CXF-5684
             Project: CXF
          Issue Type: Bug
          Components: STS
    Affects Versions: 2.7.10
         Environment: Linux 3.11.0-18-generic x64, Karaf 2.3.2, OpenJDK 64-Bit 
Server VM version 24.45-b08 
            Reporter: Carma Robot


There seems to be a fundamental flaw in the STS logic for token renewal when 
configuration allows for renewal beyond token expiration.

The flaw in logic seems to be in both the SAMLTokenProvider and the 
SAMLTokenRenewer. In brief, when tokens are added to the default token store, 
and when allowRenewalAfterExipiry is set to true, the tokens are stored in a 
way that causes them to expire before you can perform a second token renewal.

This reason why this flaw does not show up in your system tests is because you 
are only testing one renewal and the logic for storing a token in 
SAMLTokenProvider is different than in SAMLTokenRenewer. If you would change 
your renewal system test to renew the renewed token you would catch this error.

Here is the relevant code. I will start with SAMLTokenProvider. In the method 
createToken:

            if (tokenParameters.getTokenStore() != null && signatureValue != 
null
                && signatureValue.length > 0) {
                Date expires = new Date();
                long currentTime = expires.getTime();
                expires.setTime(currentTime + (conditionsProvider.getLifetime() 
* 1000L));
                
                SecurityToken securityToken = new 
SecurityToken(assertion.getId(), null, expires);

The token is stored with an expiration that is essentially the current time + 
the lifetime parameter. This means the token is cleared out of the cache after 
a period of time equal to the "lifetime" setting. If the lifetime setting is 
larger than token TTL in the request submitted by the STSClient (like in your 
system test) then renewal will be possible because the token will not get 
cleared out of the cache before you renew.

However, consider the logic for storing the token in 
SAMLRenewer.storeTokenInCache():

        if (tokenStore != null && signatureValue != null && 
signatureValue.length > 0) {
            DateTime validTill = null;
            if (assertion.getSamlVersion().equals(SAMLVersion.VERSION_20)) {
                validTill = 
assertion.getSaml2().getConditions().getNotOnOrAfter();
            } else {
                validTill = 
assertion.getSaml1().getConditions().getNotOnOrAfter();
            }

            SecurityToken securityToken = new SecurityToken(assertion.getId(), 
null, validTill.toDate());

In this case you are setting the token expiration to be exactly equal to the 
TTL in the request for security token. Which means that when the token expires 
and you try to renew the token it's no longer in the cache!

I believe what should be happening is that you should add the value of the 
SAMLTokenRenewer maxExpiry field to the "validTill" date. Also the logic in 
SAMLTokenRenewer should be the same as the logic in SAMLTokenProvider. Right 
now the logic is duplicated in two different places and that can't be good for 
maintainability.

I hope this is clear enough. The bottom line is that the token cache is using 
the expiry that you are setting when creating the SecurityToken object to 
decide when to clear the token out of the cache. If you don't set this value 
appropriately the token will not be in the cache when you try to renew it.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to