<div dir="ltr">Hi Kamal,<div><br></div><div>Each client gets their own token and they refresh the tokens independently. Last session refresh in the user session is the last time any clients in that user session refreshed the token. It's used to know if a users session is active or not and we don't care what client it was the user used.</div><div><br></div><div>With regards to refresh tokens we need to expire/invalidate the last refresh for a specific client session within the user session. So we would need a note on each client session when they refreshed last.</div><div><br></div><div>If we did what you proposed it would basically break SSO and only one client would be able to maintain a working session.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 13 October 2015 at 02:26, Kamal Jagadevan <span dir="ltr"><<a href="mailto:j.kamal@ymail.com" target="_blank">j.kamal@ymail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div style="color:#000;background-color:#fff;font-family:times new roman,new york,times,serif;font-size:13px"><div>Hi Stian/Marek,</div><div> Thanks for your attention in the matter.</div><div>Probably you are referring to one other issue in client level, but Mike & I are referring at User level within or across client.</div><div dir="ltr"><br></div><div dir="ltr">User John Doe authenticates with his credentials and obtains token pair <b>A1R1</b></div><ol dir="ltr"><li>After A1 expires, app refreshes the token pair to <b>A2R2 </b>USING R1<br></li><li>After A2 expires, app refreshes the token pair to <b>A3R3 </b><b><span style="background-color:rgb(253,239,43)">USING <font color="#cd232c" size="3">R1</font></span></b><font size="3"><b> </b></font>(ideally it is should use R2 as it is the latest refresh token)<br></li></ol><div dir="ltr"> <br></div><div dir="ltr">In order to achieve this functionality, I was wondering why can't we use existing last refresh time from User session rather then checking it in the client session.</div><div dir="ltr">IMHO, adding one more validation in the ValidateToken method in TokenManager class like this should resolve the problem.<br></div><div dir="ltr"><br></div><div dir="ltr"> // after userSession is determined either for offline token or online token...<br></div><div dir="ltr"> if(oldToken.getIssuedAt() < userSession.getLastSessionRefresh()) {<br> throw new OAuthErrorException(OAuthErrorException.INVALID_GRANT, "Stale refresh token - already used");<br> }<br><br></div><div dir="ltr"><br></div><div dir="ltr">Please let me know if you see any pitfalls other than the backward compatibility for existing keycloak users. I can work with you to merge this change & test it in the master.</div><div dir="ltr"><br></div><div dir="ltr">Best</div><div dir="ltr">Kamal<br></div><div><br></div><div><span></span></div><br> <div style="font-family:times new roman,new york,times,serif;font-size:13px"> <div style="font-family:HelveticaNeue,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif;font-size:16px"> <div dir="ltr"> <hr size="1"> <font face="Arial" size="2"> <b><span style="font-weight:bold">From:</span></b> Stian Thorgersen <<a href="mailto:sthorger@redhat.com" target="_blank">sthorger@redhat.com</a>><br> <b><span style="font-weight:bold">To:</span></b> Marek Posolda <<a href="mailto:mposolda@redhat.com" target="_blank">mposolda@redhat.com</a>> <br><b><span style="font-weight:bold">Cc:</span></b> "Jagadevan, Kamal" <<a href="mailto:kamalakannan.jagadevan@hpe.com" target="_blank">kamalakannan.jagadevan@hpe.com</a>>; "<a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a>" <<a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a>> <br> <b><span style="font-weight:bold">Sent:</span></b> Wednesday, October 7, 2015 8:38 AM<div><div class="h5"><br> <b><span style="font-weight:bold">Subject:</span></b> Re: [keycloak-dev] Same Refresh token can be used multiple times to obtain access token<br> </div></div></font> </div><div><div class="h5"> <div><br><div><div><div dir="ltr">You're right, we'd have to introduce a lastRefresh on ClientSession</div><div><br><br></div><div><div><br clear="none"><div>On 7 October 2015 at 14:35, Marek Posolda <span dir="ltr"><<a rel="nofollow" shape="rect" href="mailto:mposolda@redhat.com" target="_blank">mposolda@redhat.com</a>></span> wrote:<br clear="none"><blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><span>
</span><div>On 07/10/15 14:23, Stian Thorgersen
wrote:<br clear="none">
</div>
<blockquote type="cite">
<div dir="ltr">We should make this configurable. For those worried
about security they can enforce new refresh tokens as well as
offline tokens will replace the old tokens. It would be fairly
simply to implement. If enabled we would only allow refresh
token where iat is >= the last session refresh time.</div>
</blockquote>
I was also thinking about this possibility. However if you have 2
clients and you refresh the token for client1, the refresh token of
client2 won't be valid as his "iat" will be older. Also SSO login
currently refreshes lastSessionRefresh on UserSession. However maybe
we can introduce lastSessionRefresh to ClientSession as well?<span><font color="#888888"><br clear="none">
<br clear="none">
Marek</font></span><div><div><br clear="none">
<blockquote type="cite">
<div dir="ltr">
<div>I wouldn't make it default behavior for two reasons:
<div><br clear="none">
</div>
<div>* It would break existing clients if they expect to
continue using the old refresh token</div>
<div>* It comes at a performance cost as clients will have to
store the new refresh tokens and offline tokens each time
they refresh the token</div>
<div>* For offline tokens Keycloak would also have to persist
the last refresh time each time the offline token is
refreshed</div>
<div><br clear="none">
</div>
<div>I think we'd need to make it a realm wide configuration
option.<br clear="none">
<div><br clear="none">
<div>On 7 October 2015 at 14:12, Marek
Posolda <span dir="ltr"><<a rel="nofollow" shape="rect" href="mailto:mposolda@redhat.com" target="_blank">mposolda@redhat.com</a>></span>
wrote:<br clear="none">
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>
<div>The points are valid and security can be always
improved, however sometimes improving security
makes things complicated with the not-so-big
advantage... IMO admin should always protect the
machine to make sure that nobody unauthorized has
access to refresh tokens. And for the transport,
HTTPS should be always used. But feel free to
create JIRA and we will see...<br clear="none">
<br clear="none">
When user or client is deleted, all
refresh/offline tokens will defacto become invalid
as well and can't be used anymore. You're right
that offline token is still valid after user
logout. User can revoke it manually in account
management or admin can revoke it in admin
console. However refresh token is invalid after
user logout. All refresh/offline tokens for
particular client can be revoked by admin by set
notBefore policy to now, which can be done in
admin console in "Revocation" tab of particular
client.<span><font color="#888888"><br clear="none">
<br clear="none">
Marek</font></span>
<div>
<div><br clear="none">
<br clear="none">
On 07/10/15 04:27, Raghuram Prabhala wrote:<br clear="none">
</div>
</div>
</div>
<div>
<div>
<blockquote type="cite">
<div style="color:#000;background-color:#fff;font-family:Courier New,courier,monaco,monospace,sans-serif;font-size:13px">
<div><span>Very valid points Mike and even I
have similar concerns. But please do
understand that even if the refresh
token is stolen or compromised,it cannot
be used by any client unless both the
client_id and client_secret are also
compromised/stolen. But nevertheless, it
is a good practice to assume the worst
and add in protective measures to
minimize the chances. </span></div>
<div><span><br clear="none">
</span></div>
<div>Marek/Bill/Stian - Even our
organization is very particular that such
potential security issues be addressed.
Can this be taken up? BTW I am not sure if
you have an API/End point to invalidate
tokens for those that are either
compromised or must be invalidated as
either the user or client is no longer
active. If you do not have one then it is
a good idea to make one available.</div>
<div><br clear="none">
</div>
<div>Thanks,</div>
<div>Raghu</div>
<br clear="none">
<div style="font-family:Courier New,courier,monaco,monospace,sans-serif;font-size:13px">
<div style="font-family:HelveticaNeue,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif;font-size:16px">
<div dir="ltr">
<hr size="1"> <font face="Arial" size="2"> <b><span style="font-weight:bold">From:</span></b>
"Kuznetsov, Mike" <a rel="nofollow" shape="rect" href="mailto:mikhail.kuznetsov@hpe.com" target="_blank"></a><a rel="nofollow" shape="rect" href="mailto:mikhail.kuznetsov@hpe.com" target="_blank"><mikhail.kuznetsov@hpe.com></a><br clear="none">
<b><span style="font-weight:bold">To:</span></b>
<a rel="nofollow" shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank">"keycloak-dev@lists.jboss.org"</a>
<a rel="nofollow" shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank"><keycloak-dev@lists.jboss.org></a>
<br clear="none">
<b><span style="font-weight:bold">Cc:</span></b>
"Jagadevan, Kamal" <a rel="nofollow" shape="rect" href="mailto:kamalakannan.jagadevan@hpe.com" target="_blank"></a><a rel="nofollow" shape="rect" href="mailto:kamalakannan.jagadevan@hpe.com" target="_blank"><kamalakannan.jagadevan@hpe.com></a>
<br clear="none">
<b><span style="font-weight:bold">Sent:</span></b>
Tuesday, October 6, 2015 4:34 PM<br clear="none">
<b><span style="font-weight:bold">Subject:</span></b>
Re: [keycloak-dev] Same Refresh
token can be used multiple times to
obtain access token<br clear="none">
</font> </div>
<div><br clear="none">
<div>
<div>
<div>
<div><span style="color:windowtext">Hello,</span></div>
<div><span style="color:windowtext"> </span></div>
<div><span style="color:windowtext">The
reason I brought this up is
that we are currently
working on migrating out
authentication from a
commercially available
product called Ping to
Keycloak. We noticed that
Ping invalidates the refresh
token after it is used once,
while Keycloak does not.</span></div>
<div><span style="color:windowtext"> </span></div>
<div><span style="color:windowtext">I
and my colleague, Kamal are
concerned that by not
invalidating the refresh
token after first use, we
may be opening a security
hole. While SSL may protect
the token in transit, we can
see a scenario where the
refresh token would be
compromised or stolen from
the client itself. In this
case, the stolen refresh
token could be used to get
new access tokens without
the owner of the client
machine knowing. </span></div>
<div><span style="color:windowtext"> </span></div>
<div><span style="color:windowtext">However,
if the behavior was changed
so that the refresh token
could only be used once,
then either:</span></div>
<div><span style="color:windowtext"><span>1.<span style="font:7.0pt">
</span></span></span><span style="color:windowtext">If
the owner of the client
machine would use the
refresh token first, then
the stolen refresh token
could not be used</span></div>
<div><span style="color:windowtext"><span>2.<span style="font:7.0pt">
</span></span></span><span style="color:windowtext">If
the stolen refresh token
would be used first, then
the client machine would not
be able to use it and the
user of that client machine
could be alerted that
something was wrong. This
user could then reset their
password or invalidate all
of their access and refresh
tokens.</span></div>
<div><span style="color:windowtext"> </span></div>
<div><span style="color:windowtext">Furthermore,
we are concerned about this
same scenario, but with the
offline token. My
understanding is that the
offline token does not
expire and that it can’t be
invalidated by logging out
the user or changing the
user’s password. Have you
thought about this scenario?</span></div>
<div><span style="color:#1f497d">
</span></div>
<div>Thank You,</div>
<div><span style="font-size:9.0pt"><br clear="none">
</span><b><span style="font-size:10.0pt">Mikhail
Kuznetsov</span></b></div>
<div><span style="font-size:9.0pt">Software
Engineer</span></div>
<div><span style="font-size:9.0pt">Hewlett
Packard Enterprise</span></div>
<div><span style="color:#1f497d">
</span></div>
<div><br clear="none">
<br clear="none">
</div>
<div>
<div>
<div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0in 0in 0in">
<div><b><span style="color:windowtext">From:</span></b><span style="color:windowtext"> Marek Posolda [<a rel="nofollow" shape="rect" href="mailto:mposolda@redhat.com" target="_blank">mailto:mposolda@redhat.com</a>]
<br clear="none">
<b>Sent:</b> Tuesday,
October 06, 2015 1:16
PM<br clear="none">
<b>To:</b> Raghu
Prabhala<br clear="none">
<b>Cc:</b> Kuznetsov,
Mike; <a rel="nofollow" shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank"></a><a rel="nofollow" shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a><br clear="none">
<b>Subject:</b> Re:
[keycloak-dev] Same
Refresh token can be
used multiple times to
obtain access token</span></div>
</div>
</div>
<div> </div>
<div>
<div>Hi Raghu,<br clear="none">
<br clear="none">
>From the specs, it
looks to me that this is
not anything mandatory.
The paragraph is starting
"For example". Feel free
to create JIRA, but I
personally can't promise
anything regarding this...<br clear="none">
<br clear="none">
Marek<br clear="none">
<br clear="none">
<br clear="none">
On 06/10/15 17:37, Raghu
Prabhala wrote:<span style="font-size:12.0pt"></span></div>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>Hi Marek - section
10.4 of rfc6749 mentions
that the prior refresh
token should be
invalidated but retained
by the server - to
handle compromise of
refresh tokens as they
are long lived. </div>
</div>
<div>
<div> </div>
</div>
<div>
<div>Thanks,</div>
</div>
<div>
<div>Raghu<br clear="none">
<br clear="none">
Sent from my iPhone</div>
</div>
<div>
<div style="margin-bottom:12.0pt"><br clear="none">
On Oct 6, 2015, at 10:53
AM, Marek Posolda <<a rel="nofollow" shape="rect" href="mailto:mposolda@redhat.com" target="_blank"></a><a rel="nofollow" shape="rect" href="mailto:mposolda@redhat.com" target="_blank">mposolda@redhat.com</a>>
wrote:</div>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<div>You're right,
same refresh token
can be used more
times. However it is
still better to use
refresh token R2 in
your step 3 instead
of using old refresh
token R1 because R2
has updated
timestamp (each
token is valid just
for 30 minutes or
so, depends on the
configured SSO
session idle
timeout).<br clear="none">
<br clear="none">
Or are you referring
that this is
security issue and
potential
possibility to Man
in the middle? If
you use HTTPS (which
is recommended for
production
environment, and
especially if you
have
unsecured/untrusted
networkl), this
shouldn't be an
issue.<br clear="none">
<br clear="none">
Marek<br clear="none">
<br clear="none">
On 06/10/15 16:34,
Kuznetsov, Mike
wrote:</div>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>Hello,</div>
<div> </div>
<div>I noticed that
with Keycloak, it
seems that refresh
tokens are still
valid after they are
used once. This
means that Keycloak
does <b>not</b>
invalidate Refresh
Tokens after they
have been used once.</div>
<div> </div>
<div>I am able to
successfully execute
the following flow:</div>
<div><span>1.<span style="font:7.0pt">
</span></span>Obtain
Access Token (A1)
and Refresh Token
(R1)</div>
<div><span>2.<span style="font:7.0pt">
</span></span>Use
Refresh Token (R1)
to obtain new Access
Token (A2) and
Refresh Token (R2)</div>
<div><span>3.<span style="font:7.0pt">
</span></span>Use
same Refresh Token
(R1) again to obtain
new Access Token
(A3) and Refresh
Token (R3)</div>
<div> </div>
<div> </div>
<div>Can you please
tell me if this is
the intended
functionality?</div>
<div> </div>
<div>Thank You,</div>
<div><span style="font-size:9.0pt"><br clear="none">
</span><b><span style="font-size:10.0pt">Mikhail
Kuznetsov</span></b></div>
<div><span style="font-size:9.0pt">Software
Engineer</span></div>
<div><span style="font-size:9.0pt">Hewlett
Packard Enterprise</span></div>
<div> </div>
<div><span style="font-size:12.0pt"><br clear="none">
<br clear="none">
<br clear="none">
</span></div>
<pre>_______________________________________________</pre>
<pre>keycloak-dev mailing list</pre>
<pre><a rel="nofollow" shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a></pre>
<pre><a rel="nofollow" shape="rect" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></pre>
</blockquote>
<div><span style="font-size:12.0pt">
</span></div>
</div>
</blockquote>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div><span style="font-size:12.0pt">_______________________________________________<br clear="none">
keycloak-dev mailing
list<br clear="none">
<a rel="nofollow" shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank"></a><a rel="nofollow" shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a><br clear="none">
<a rel="nofollow" shape="rect" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank"></a><a rel="nofollow" shape="rect" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></span></div>
</div>
</blockquote>
</blockquote>
</div>
<div><span style="font-size:12.0pt"> </span></div>
</div>
</div>
</div>
<br clear="none">
<div>_______________________________________________<br clear="none">
keycloak-dev mailing list<br clear="none">
<a rel="nofollow" shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a><br clear="none">
<a rel="nofollow" shape="rect" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></div>
<br clear="none">
<br clear="none">
</div>
</div>
</div>
</div>
<br clear="none">
<fieldset></fieldset>
<br clear="none">
<pre>_______________________________________________
keycloak-dev mailing list
<a rel="nofollow" shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a>
<a rel="nofollow" shape="rect" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></pre>
</blockquote>
<br clear="none">
</div>
</div>
</div>
<br clear="none">
_______________________________________________<br clear="none">
keycloak-dev mailing list<br clear="none">
<a rel="nofollow" shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a><br clear="none">
<a rel="nofollow" shape="rect" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br clear="none">
</blockquote>
</div>
<br clear="none">
</div>
</div>
</div>
</div>
</blockquote>
<br clear="none">
</div></div></div>
</blockquote></div><br clear="none"></div></div></div></div><br><div>_______________________________________________<br clear="none">keycloak-dev mailing list<br clear="none"><a shape="rect" href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a><br clear="none"><a shape="rect" href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></div><br><br></div> </div></div></div> </div> </div></div></blockquote></div><br></div>