<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 &gt;= the last session refresh time.<div><br></div><div>I wouldn&#39;t make it default behavior for two reasons:<div><br></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></div><div>I think we&#39;d need to make it a realm wide configuration option.<br><div class="gmail_extra"><br><div class="gmail_quote">On 7 October 2015 at 14:12, Marek Posolda <span dir="ltr">&lt;<a href="mailto:mposolda@redhat.com" target="_blank">mposolda@redhat.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF">
    <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>
      <br>
      When user or client is deleted, all refresh/offline tokens will
      defacto become invalid as well and can&#39;t be used anymore. You&#39;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 &quot;Revocation&quot; tab of particular client.<span class="HOEnZb"><font color="#888888"><br>
      <br>
      Marek</font></span><div><div class="h5"><br>
      <br>
      On 07/10/15 04:27, Raghuram Prabhala wrote:<br>
    </div></div></div><div><div class="h5">
    <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>
          </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>
        </div>
        <div>Thanks,</div>
        <div>Raghu</div>
        <br>
        <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>
                &quot;Kuznetsov, Mike&quot; <a href="mailto:mikhail.kuznetsov@hpe.com" target="_blank">&lt;mikhail.kuznetsov@hpe.com&gt;</a><br>
                <b><span style="font-weight:bold">To:</span></b>
                <a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">&quot;keycloak-dev@lists.jboss.org&quot;</a>
                <a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">&lt;keycloak-dev@lists.jboss.org&gt;</a> <br>
                <b><span style="font-weight:bold">Cc:</span></b>
                &quot;Jagadevan, Kamal&quot;
                <a href="mailto:kamalakannan.jagadevan@hpe.com" target="_blank">&lt;kamalakannan.jagadevan@hpe.com&gt;</a> <br>
                <b><span style="font-weight:bold">Sent:</span></b>
                Tuesday, October 6, 2015 4:34 PM<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>
              </font> </div>
            <div><br>
              <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>
                      <br>
                    </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 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 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">
                          &gt;From the specs, it looks to me that this
                          is not anything mandatory. The paragraph is
                          starting &quot;For example&quot;. Feel free to create
                          JIRA, but I personally can&#39;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
                            &lt;<a rel="nofollow" shape="rect" href="mailto:mposolda@redhat.com" target="_blank">mposolda@redhat.com</a>&gt;
                            wrote:</div>
                        </div>
                        <blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
                          <div>
                            <div>
                              <div>You&#39;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&#39;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">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></span></div>
                          </div>
                        </blockquote>
                      </blockquote>
                    </div>
                    <div><span style="font-size:12.0pt">  </span></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>
      <br>
      <fieldset></fieldset>
      <br>
      <pre>_______________________________________________
keycloak-dev mailing list
<a href="mailto:keycloak-dev@lists.jboss.org" target="_blank">keycloak-dev@lists.jboss.org</a>
<a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a></pre>
    </blockquote>
    <br>
  </div></div></div>

<br>_______________________________________________<br>
keycloak-dev mailing list<br>
<a href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/keycloak-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br></blockquote></div><br></div></div></div></div>