<div dir="ltr">I was about to say "I am using confidential". Switching to public does indeed drop the need for preflight. Learned something new :-)<div><br></div><div>Still want me to submit a PR for the refresh preflight? Obviously using confidential doesn't add any security here, but I don't think supporting it can hurt either (and the JavaScript code supports it already.)</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 2, 2014 at 8:24 AM, Bill Burke <span dir="ltr"><<a href="mailto:bburke@redhat.com" target="_blank">bburke@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">You mean the "public" application type.<br>
<div class="HOEnZb"><div class="h5"><br>
On 12/2/2014 10:10 AM, Stian Thorgersen wrote:<br>
> The code->token and refresh token requests are being pre-flighted because there's a 'Authorization: Basic' header in there. For a GWT app you should use the confidential application type, which doesn't require a secret.<br>
><br>
> ----- Original Message -----<br>
>> From: "Alain Penders" <<a href="mailto:alain@rexorient.com">alain@rexorient.com</a>><br>
>> To: "Stian Thorgersen" <<a href="mailto:stian@redhat.com">stian@redhat.com</a>><br>
>> Cc: <a href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
>> Sent: Tuesday, 2 December, 2014 4:02:15 PM<br>
>> Subject: Re: [keycloak-dev] Fwd: Preflight for token refresh<br>
>><br>
>> Not really. It needs CORS for every URI it hits. Refresh is a different<br>
>> URI from the code->token exchange one it uses initially.<br>
>><br>
>> When Keycloak redirects back to the GWT app and the code is exchanged for<br>
>> the tokens, I see this in the Network trace:<br>
>><br>
>> First an OPTIONS request:<br>
>><br>
>><br>
>> 1. Remote Address:<br>
>> <a href="http://127.0.0.1:8080" target="_blank">127.0.0.1:8080</a><br>
>> 2. Request URL:<br>
>> <a href="http://localhost:8080/auth/realms/GameSeeder/tokens/access/codes" target="_blank">http://localhost:8080/auth/realms/GameSeeder/tokens/access/codes</a><br>
>> 3. Request Method:<br>
>> OPTIONS<br>
>> 4. Status Code:<br>
>> 200 OK<br>
>> 5. Request Headersview source<br>
>> 1. Accept:<br>
>> */*<br>
>> 2. Accept-Encoding:<br>
>> gzip, deflate, sdch<br>
>> 3. Accept-Language:<br>
>> en-US,en;q=0.8<br>
>> 4. Access-Control-Request-Headers:<br>
>> authorization, content-type<br>
>> 5. Access-Control-Request-Method:<br>
>> POST<br>
>> 6. Connection:<br>
>> keep-alive<br>
>> 7. Host:<br>
>> localhost:8080<br>
>> 8. Origin:<br>
>> <a href="http://127.0.0.1:8888" target="_blank">http://127.0.0.1:8888</a><br>
>> 9. Referer:<br>
>> <a href="http://127.0.0.1:8888/Main.html" target="_blank">http://127.0.0.1:8888/Main.html</a><br>
>> 10. User-Agent:<br>
>> Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like<br>
>> Gecko) Chrome/39.0.2171.71 Safari/537.36<br>
>> 6. Response Headersview source<br>
>> 1. Access-Control-Allow-Credentials:<br>
>> true<br>
>> 2. Access-Control-Allow-Headers:<br>
>> Origin, Accept, X-Requested-With, Content-Type,<br>
>> Access-Control-Request-Method, Access-Control-Request-Headers,<br>
>> Authorization<br>
>> 3. Access-Control-Allow-Methods:<br>
>> GET, HEAD, OPTIONS<br>
>> 4. Access-Control-Allow-Origin:<br>
>> <a href="http://127.0.0.1:8888" target="_blank">http://127.0.0.1:8888</a><br>
>> 5. Access-Control-Max-Age:<br>
>> 3600<br>
>> 6. Connection:<br>
>> keep-alive<br>
>> 7. Content-Length:<br>
>> 0<br>
>> 8. Date:<br>
>> Tue, 02 Dec 2014 14:51:47 GMT<br>
>> 9. Server:<br>
>> WildFly/8<br>
>> 10. X-Powered-By:<br>
>> Undertow/1<br>
>><br>
>><br>
>> Then the actual code exchange request:<br>
>><br>
>><br>
>> 1. Remote Address:<br>
>> <a href="http://127.0.0.1:8080" target="_blank">127.0.0.1:8080</a><br>
>> 2. Request URL:<br>
>> <a href="http://localhost:8080/auth/realms/GameSeeder/tokens/access/codes" target="_blank">http://localhost:8080/auth/realms/GameSeeder/tokens/access/codes</a><br>
>> 3. Request Method:<br>
>> POST<br>
>> 4. Status Code:<br>
>> 200 OK<br>
>> 5. Request Headersview source<br>
>> 1. Accept:<br>
>> */*<br>
>> 2. Accept-Encoding:<br>
>> gzip, deflate<br>
>> 3. Accept-Language:<br>
>> en-US,en;q=0.8<br>
>> 4. Authorization:<br>
>> Basic R2FtZVNlZWRlcjoyYTczYTQ0Yi1lMGFhLTRiMTYtODk2OC1hY2YwZTVlMGVlNTk=<br>
>> 5. Connection:<br>
>> keep-alive<br>
>> 6. Content-Length:<br>
>> 85<br>
>> 7. Content-type:<br>
>> application/x-www-form-urlencoded<br>
>> 8. Cookie:<br>
>> KEYCLOAK_IDENTITY=eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiI5NTA4ZTg2Yi04ZjdhLTRmN2UtOWYzOC1jMTFhMDdkNjUyOWMiLCJleHAiOjE0MjAxMjM5MDYsIm5iZiI6MCwiaWF0IjoxNDE3NTMxOTA2LCJpc3MiOiJHYW1lU2VlZGVyIiwic3ViIjoiOTY0ZjkwNWMtZTg2ZC00NDUzLWE3MzItYWVlMDE5NGY5YTIwIiwic2Vzc2lvbl9zdGF0ZSI6ImVjODE0NjcyLTFhOWYtNDM1ZS04YjU4LTU4ZmI4MDNiMDZkYSIsInJlc291cmNlX2FjY2VzcyI6e319.LiS51MggFZVPJ-TUlcYejPD7x6pJvgdOYCLrHV8LKiIP6BGZzS7D4W0t3xsXeKxqBr-h3cSaY_BqWKRl4RGn67SHuWvoDRrS6xKPZuWPQ08NS_iQVrIKGOATtGF2VFMutnroa4Y_UNmi5T2gZFc-wphRWRV5YG-x-DGAqd4h42U;<br>
>> KEYCLOAK_SESSION=GameSeeder/964f905c-e86d-4453-a732-aee0194f9a20/ec814672-1a9f-435e-8b58-58fb803b06da;<br>
>> KEYCLOAK_REMEMBER_ME=username:alain<br>
>> 9. Host:<br>
>> localhost:8080<br>
>> 10. Origin:<br>
>> <a href="http://127.0.0.1:8888" target="_blank">http://127.0.0.1:8888</a><br>
>> 11. Referer:<br>
>> <a href="http://127.0.0.1:8888/Main.html" target="_blank">http://127.0.0.1:8888/Main.html</a><br>
>> 12. User-Agent:<br>
>> Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like<br>
>> Gecko) Chrome/39.0.2171.71 Safari/537.36<br>
>> 6. Form Dataview sourceview URL encoded<br>
>> 1. code:<br>
>><br>
>> sCnqEAuF8YuobscjJnCKdGu6xqnZ-CsqT5prXc5i7os.b9cda44e-50d6-49dd-b30a-dee68b530662<br>
>> 7. Response Headersview source<br>
>> 1. Access-Control-Allow-Credentials:<br>
>> true<br>
>> 2. Access-Control-Allow-Headers:<br>
>> Origin, Accept, X-Requested-With, Content-Type,<br>
>> Access-Control-Request-Method, Access-Control-Request-Headers,<br>
>> Authorization<br>
>> 3. Access-Control-Allow-Methods:<br>
>> POST<br>
>> 4. Access-Control-Allow-Origin:<br>
>> <a href="http://127.0.0.1:8888" target="_blank">http://127.0.0.1:8888</a><br>
>> 5. Access-Control-Expose-Headers:<br>
>> Access-Control-Allow-Methods<br>
>> 6. Access-Control-Max-Age:<br>
>> 3600<br>
>> 7. Connection:<br>
>> keep-alive<br>
>> 8. Content-Type:<br>
>> application/json<br>
>> 9. Date:<br>
>> Tue, 02 Dec 2014 14:51:47 GMT<br>
>> 10. Server:<br>
>> WildFly/8<br>
>> 11. Transfer-Encoding:<br>
>> chunked<br>
>> 12. X-Powered-By:<br>
>> Undertow/1<br>
>><br>
>><br>
>> Now I wait 5+ minutes, forcing keycloak to use the refresh token. Since<br>
>> this uses the refresh URI for the first time, Chrome performs a preflight<br>
>> check:<br>
>><br>
>><br>
>> 1. Remote Address:<br>
>> <a href="http://127.0.0.1:8080" target="_blank">127.0.0.1:8080</a><br>
>> 2. Request URL:<br>
>> <a href="http://localhost:8080/auth/realms/GameSeeder/tokens/refresh" target="_blank">http://localhost:8080/auth/realms/GameSeeder/tokens/refresh</a><br>
>> 3. Request Method:<br>
>> OPTIONS<br>
>> 4. Status Code:<br>
>> 200 OK<br>
>> 5. Request Headersview source<br>
>> 1. Accept:<br>
>> */*<br>
>> 2. Accept-Encoding:<br>
>> gzip, deflate, sdch<br>
>> 3. Accept-Language:<br>
>> en-US,en;q=0.8<br>
>> 4. Access-Control-Request-Headers:<br>
>> authorization, content-type<br>
>> 5. Access-Control-Request-Method:<br>
>> POST<br>
>> 6. Connection:<br>
>> keep-alive<br>
>> 7. Host:<br>
>> localhost:8080<br>
>> 8. Origin:<br>
>> <a href="http://127.0.0.1:8888" target="_blank">http://127.0.0.1:8888</a><br>
>> 9. Referer:<br>
>> <a href="http://127.0.0.1:8888/Main.html" target="_blank">http://127.0.0.1:8888/Main.html</a><br>
>> 10. User-Agent:<br>
>> Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like<br>
>> Gecko) Chrome/39.0.2171.71 Safari/537.36<br>
>> 6. Response Headersview source<br>
>> 1. Access-Control-Allow-Credentials:<br>
>> true<br>
>> 2. Access-Control-Allow-Headers:<br>
>> Origin, Accept, X-Requested-With, Content-Type,<br>
>> Access-Control-Request-Method, Access-Control-Request-Headers,<br>
>> Authorization<br>
>> 3. Access-Control-Allow-Methods:<br>
>> GET, HEAD, OPTIONS<br>
>> 4. Access-Control-Allow-Origin:<br>
>> <a href="http://127.0.0.1:8888" target="_blank">http://127.0.0.1:8888</a><br>
>> 5. Access-Control-Max-Age:<br>
>> 3600<br>
>> 6. Connection:<br>
>> keep-alive<br>
>> 7. Content-Length:<br>
>> 0<br>
>> 8. Date:<br>
>> Tue, 02 Dec 2014 15:00:32 GMT<br>
>> 9. Server:<br>
>> WildFly/8<br>
>> 10. X-Powered-By:<br>
>> Undertow/1<br>
>><br>
>><br>
>> Followed by the actual refresh:<br>
>><br>
>><br>
>> 1. Remote Address:<br>
>> <a href="http://127.0.0.1:8080" target="_blank">127.0.0.1:8080</a><br>
>> 2. Request URL:<br>
>> <a href="http://localhost:8080/auth/realms/GameSeeder/tokens/refresh" target="_blank">http://localhost:8080/auth/realms/GameSeeder/tokens/refresh</a><br>
>> 3. Request Method:<br>
>> POST<br>
>> 4. Status Code:<br>
>> 200 OK<br>
>> 5. Request Headersview source<br>
>> 1. Accept:<br>
>> */*<br>
>> 2. Accept-Encoding:<br>
>> gzip, deflate<br>
>> 3. Accept-Language:<br>
>> en-US,en;q=0.8<br>
>> 4. Authorization:<br>
>> Basic R2FtZVNlZWRlcjoyYTczYTQ0Yi1lMGFhLTRiMTYtODk2OC1hY2YwZTVlMGVlNTk=<br>
>> 5. Connection:<br>
>> keep-alive<br>
>> 6. Content-Length:<br>
>> 699<br>
>> 7. Content-type:<br>
>> application/x-www-form-urlencoded<br>
>> 8. Host:<br>
>> localhost:8080<br>
>> 9. Origin:<br>
>> <a href="http://127.0.0.1:8888" target="_blank">http://127.0.0.1:8888</a><br>
>> 10. Referer:<br>
>> <a href="http://127.0.0.1:8888/Main.html" target="_blank">http://127.0.0.1:8888/Main.html</a><br>
>> 11. User-Agent:<br>
>> Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like<br>
>> Gecko) Chrome/39.0.2171.71 Safari/537.36<br>
>> 6. Form Dataview sourceview URL encoded<br>
>> 1. grant_type:<br>
>> refresh_token<br>
>> 2. refresh_token:<br>
>><br>
>> eyJhbGciOiJSUzI1NiJ9.eyJqdGkiOiJjMWZlOGUyNS0yNTlkLTQwYjYtOGFmMS0yMDU0Y2EwMTRkYWEiLCJleHAiOjE0MTc1MzkxMDcsIm5iZiI6MCwiaWF0IjoxNDE3NTMxOTA3LCJpc3MiOiJHYW1lU2VlZGVyIiwic3ViIjoiOTY0ZjkwNWMtZTg2ZC00NDUzLWE3MzItYWVlMDE5NGY5YTIwIiwidHlwIjoiUkVGUkVTSCIsImF6cCI6IkdhbWVTZWVkZXIiLCJzZXNzaW9uX3N0YXRlIjoiZWM4MTQ2NzItMWE5Zi00MzVlLThiNTgtNThmYjgwM2IwNmRhIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbInVzZXIiXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbInZpZXctcHJvZmlsZSIsIm1hbmFnZS1hY2NvdW50Il19fX0.HlAXTyosQ4SHL2WyqRVMDEwN2TXNQyqTKE8PRkbhnbhjJPq4alDP2mCBH2RV3a5KPDCTj1-H-bnKpebrV8fOWNVrQCCL5NN6t7KEYLH1hA75ak_xWSUNzz7s_ZlW9AVucuMCFk1-bXnDaQOilU9JOS2yomQYa4PvexmrbzEJ5Bs<br>
>> 7. Response Headersview source<br>
>> 1. Access-Control-Allow-Credentials:<br>
>> true<br>
>> 2. Access-Control-Allow-Headers:<br>
>> Origin, Accept, X-Requested-With, Content-Type,<br>
>> Access-Control-Request-Method, Access-Control-Request-Headers,<br>
>> Authorization<br>
>> 3. Access-Control-Allow-Methods:<br>
>> POST<br>
>> 4. Access-Control-Allow-Origin:<br>
>> <a href="http://127.0.0.1:8888" target="_blank">http://127.0.0.1:8888</a><br>
>> 5. Access-Control-Expose-Headers:<br>
>> Access-Control-Allow-Methods<br>
>> 6. Access-Control-Max-Age:<br>
>> 3600<br>
>> 7. Connection:<br>
>> keep-alive<br>
>> 8. Content-Type:<br>
>> application/json<br>
>> 9. Date:<br>
>> Tue, 02 Dec 2014 15:00:32 GMT<br>
>> 10. Server:<br>
>> WildFly/8<br>
>> 11. Transfer-Encoding:<br>
>> chunked<br>
>> 12. X-Powered-By:<br>
>> Undertow/1<br>
>><br>
>><br>
>><br>
>><br>
>> On Tue, Dec 2, 2014 at 7:49 AM, Stian Thorgersen <<a href="mailto:stian@redhat.com">stian@redhat.com</a>> wrote:<br>
>><br>
>>><br>
>>><br>
>>> ----- Original Message -----<br>
>>>> From: "Alain Penders" <<a href="mailto:alain@rexorient.com">alain@rexorient.com</a>><br>
>>>> To: "Stian Thorgersen" <<a href="mailto:stian@redhat.com">stian@redhat.com</a>><br>
>>>> Cc: <a href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
>>>> Sent: Tuesday, 2 December, 2014 3:43:13 PM<br>
>>>> Subject: Re: [keycloak-dev] Fwd: Preflight for token refresh<br>
>>>><br>
>>>> I'm testing my UI using GWTs Super Dev Mode, which means its origin is<br>
>>> set<br>
>>>> to <a href="http://127.0.0.1:8888" target="_blank">http://127.0.0.1:8888</a>. Keycloak runs on <a href="http://127.0.0.1:8080/auth" target="_blank">http://127.0.0.1:8080/auth</a><br>
>>> .<br>
>>><br>
>>> Yes, that requires CORS, but doesn't necessarily require a PREFLIGHT<br>
>>> request. My guess is that "GWTs Super Dev Mode" sets some custom headers on<br>
>>> all requests.<br>
>>><br>
>>>><br>
>>>> On Tue, Dec 2, 2014 at 7:32 AM, Stian Thorgersen <<a href="mailto:stian@redhat.com">stian@redhat.com</a>><br>
>>> wrote:<br>
>>>><br>
>>>>> It's the correct approach to add the preflight. Please send a PR and<br>
>>> we'll<br>
>>>>> merge it.<br>
>>>>><br>
>>>>> Out of curiosity do you know why it's sending a preflight in your app?<br>
>>> It<br>
>>>>> doesn't when I test it out here, which AFAIK is correct according to<br>
>>> spec<br>
>>>>> (content-type is application/x-www-form-urlencoded and there's no<br>
>>> custom<br>
>>>>> headers set).<br>
>>>>><br>
>>>>> ----- Original Message -----<br>
>>>>>> From: "Alain Penders" <<a href="mailto:alain@rexorient.com">alain@rexorient.com</a>><br>
>>>>>> To: <a href="mailto:keycloak-dev@lists.jboss.org">keycloak-dev@lists.jboss.org</a><br>
>>>>>> Sent: Tuesday, 2 December, 2014 3:04:50 PM<br>
>>>>>> Subject: [keycloak-dev] Fwd: Preflight for token refresh<br>
>>>>>><br>
>>>>>> Hi all,<br>
>>>>>><br>
>>>>>> I'm building a new app using GWT 2.7 using the Keycloak javascript<br>
>>>>> adapter<br>
>>>>>> and GWT jsInterop. This works extremely well.<br>
>>>>>><br>
>>>>>> The problem I ran into is if I walk away for 5 minutes and then try<br>
>>> to do<br>
>>>>>> something, the token refresh fails on preflight. As shown in the<br>
>>>>>> documentation, I call keycloak.updateToken(30) to refresh the base<br>
>>> token<br>
>>>>> in<br>
>>>>>> case it has expired. Since in this case it has indeed expired,<br>
>>> keycloak<br>
>>>>>> makes a call to /auth/realms/<myrealm>/tokens/refresh. The OPTIONS<br>
>>> call<br>
>>>>> to<br>
>>>>>> this location doesn't contain the Accept headers, and my app ends up<br>
>>>>> dead in<br>
>>>>>> the water.<br>
>>>>>><br>
>>>>>> To fix this, I added the following code to OpenIDConnectService:<br>
>>>>>><br>
>>>>>> /**<br>
>>>>>> * CORS preflight path for refresh token requests<br>
>>>>>> *<br>
>>>>>> * @return<br>
>>>>>> */<br>
>>>>>> @Path("refresh")<br>
>>>>>> @OPTIONS<br>
>>>>>> @Produces(MediaType.APPLICATION_JSON)<br>
>>>>>> public Response refreshAccessTokenPreflight() {<br>
>>>>>> if (logger.isDebugEnabled()) {<br>
>>>>>> logger.debugv("cors request from: {0}",<br>
>>>>>> request.getHttpHeaders().getRequestHeaders().getFirst("Origin"));<br>
>>>>>> }<br>
>>>>>> return Cors.add(request, Response.ok()).auth().preflight().build();<br>
>>>>>> }<br>
>>>>>><br>
>>>>>> If this wasn't the correct solution for my problem, I'd enjoy hearing<br>
>>>>> where I<br>
>>>>>> went wrong.<br>
>>>>>><br>
>>>>>> Thanks,<br>
>>>>>> Alain<br>
>>>>>><br>
>>>>>><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" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br>
>>>>><br>
>>>><br>
>>><br>
>><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" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br>
><br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
Bill Burke<br>
JBoss, a division of Red Hat<br>
<a href="http://bill.burkecentral.com" target="_blank">http://bill.burkecentral.com</a><br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<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" target="_blank">https://lists.jboss.org/mailman/listinfo/keycloak-dev</a><br>
</div></div></blockquote></div><br></div>