diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
index adb069d..b9cb430 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java
@@ -162,6 +162,13 @@ public class TokenEndpoint {
formParams = request.getDecodedFormParameters();
grantType = formParams.getFirst(OIDCLoginProtocol.GRANT_TYPE_PARAM);
+ // https://tools.ietf.org/html/rfc6749#section-5.1
+ // The authorization server MUST include the HTTP "Cache-Control" response header field
+ // with a value of "no-store" as well as the "Pragma" response header field with a value of "no-cache".
+ MultivaluedMap<String, Object> outputHeaders = httpResponse.getOutputHeaders();
+ outputHeaders.putSingle("Cache-Control", "no-store");
+ outputHeaders.putSingle("Pragma", "no-cache");
+
checkSsl();
checkRealm();
checkGrantType();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
index 78936ca..27b895a 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
@@ -81,6 +81,7 @@ import java.io.IOException;
import java.net.URI;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.Matchers.allOf;
@@ -978,6 +979,26 @@ public class AccessTokenTest extends AbstractKeycloakTest {
}
}
+ @Test
+ public void accessTokenResponseHeader() throws Exception {
+ oauth.doLogin("test-user@localhost", "password");
+
+ EventRepresentation loginEvent = events.expectLogin().assertEvent();
+
+ String sessionId = loginEvent.getSessionId();
+ String codeId = loginEvent.getDetails().get(Details.CODE_ID);
+
+ String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
+ OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
+
+ assertEquals(200, response.getStatusCode());
+
+ Map<String, String> headers = response.getHeaders();
+ assertEquals("application/json", headers.get("Content-Type"));
+ assertEquals("no-store", headers.get("Cache-Control"));
+ assertEquals("no-cache", headers.get("Pragma"));
+ }
+
private IDToken getIdToken(org.keycloak.representations.AccessTokenResponse tokenResponse) throws JWSInputException {
JWSInput input = new JWSInput(tokenResponse.getIdToken());
return input.readJsonContent(IDToken.class);