Work in progress...
This commit is contained in:
parent
69f7dfbb47
commit
a1d4d8e13f
6 changed files with 540 additions and 19 deletions
|
@ -17,11 +17,25 @@
|
|||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-testsuite-integration</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||
<artifactId>jboss-servlet-api_3.0_spec</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-testsuite-tools</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
|
||||
<!-- Needed by undertow -->
|
||||
<dependency>
|
||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||
<artifactId>jboss-servlet-api_3.1_spec</artifactId>
|
||||
<version>1.0.0.Final</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Resteasy deps specified here as we want latest version of them -->
|
||||
|
|
|
@ -4,9 +4,11 @@ import java.io.InputStream;
|
|||
|
||||
import javax.servlet.DispatcherType;
|
||||
|
||||
import io.undertow.server.handlers.resource.ClassPathResourceManager;
|
||||
import io.undertow.servlet.Servlets;
|
||||
import io.undertow.servlet.api.DeploymentInfo;
|
||||
import io.undertow.servlet.api.FilterInfo;
|
||||
import io.undertow.servlet.api.MimeMapping;
|
||||
import io.undertow.servlet.api.ServletInfo;
|
||||
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
|
||||
import org.jboss.resteasy.spi.ResteasyDeployment;
|
||||
|
@ -76,10 +78,12 @@ public class KeycloakPerfServer {
|
|||
deploymentInfo.setContextPath("/perf-app");
|
||||
|
||||
ServletInfo servlet = new ServletInfo("PerfAppServlet", PerfAppServlet.class);
|
||||
servlet.addMapping("/*");
|
||||
servlet.addMapping("/perf-servlet");
|
||||
|
||||
deploymentInfo.addServlet(servlet);
|
||||
|
||||
deploymentInfo.setResourceManager(new ClassPathResourceManager(getClass().getClassLoader()));
|
||||
|
||||
keycloakServer.getServer().deploy(deploymentInfo);
|
||||
|
||||
System.out.println("PerfApp deployed");
|
||||
|
|
|
@ -0,0 +1,376 @@
|
|||
package org.keycloak.testsuite.performance.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.PublicKey;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.jboss.resteasy.security.PemUtils;
|
||||
import org.json.JSONObject;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.RSATokenVerifier;
|
||||
import org.keycloak.VerificationException;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
import org.keycloak.jose.jws.crypto.RSAProvider;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.RefreshToken;
|
||||
import org.keycloak.services.resources.TokenService;
|
||||
import org.keycloak.util.BasicAuthHelper;
|
||||
|
||||
/**
|
||||
* TODO: Remove from here and instead merge with org.keycloak.testsuite.OAuthClient
|
||||
*
|
||||
*@author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class OAuthClient {
|
||||
|
||||
private String baseUrl = "http://localhost:8081/auth";
|
||||
|
||||
private String realm = "perf-realm";
|
||||
|
||||
private String responseType = OAuth2Constants.CODE;
|
||||
|
||||
private String grantType = "authorization_code";
|
||||
|
||||
private String clientId = "perf-app";
|
||||
|
||||
private String redirectUri = "http://localhost:8081/perf-app/perf-servlet";
|
||||
|
||||
private String state = "123";
|
||||
|
||||
private PublicKey realmPublicKey;
|
||||
|
||||
public OAuthClient() {
|
||||
try {
|
||||
JSONObject realmJson = new JSONObject(IOUtils.toString(getClass().getResourceAsStream("/perfrealm.json")));
|
||||
realmPublicKey = PemUtils.decodePublicKey(realmJson.getString("publicKey"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to retrieve realm public key", e);
|
||||
}
|
||||
}
|
||||
|
||||
public AccessTokenResponse doAccessTokenRequest(String code, String password) {
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(getAccessTokenUrl());
|
||||
|
||||
List<NameValuePair> parameters = new LinkedList<NameValuePair>();
|
||||
if (grantType != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, grantType));
|
||||
}
|
||||
if (code != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.CODE, code));
|
||||
}
|
||||
if (redirectUri != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.REDIRECT_URI, redirectUri));
|
||||
}
|
||||
if (clientId != null && password != null) {
|
||||
String authorization = BasicAuthHelper.createHeader(clientId, password);
|
||||
post.setHeader("Authorization", authorization);
|
||||
}
|
||||
else if (clientId != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
|
||||
}
|
||||
|
||||
UrlEncodedFormEntity formEntity = null;
|
||||
try {
|
||||
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
post.setEntity(formEntity);
|
||||
|
||||
try {
|
||||
return new AccessTokenResponse(client.execute(post));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to retrieve access token", e);
|
||||
}
|
||||
}
|
||||
|
||||
public AccessTokenResponse doGrantAccessTokenRequest(String clientSecret, String username, String password) throws Exception {
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(getResourceOwnerPasswordCredentialGrantUrl());
|
||||
|
||||
String authorization = BasicAuthHelper.createHeader(clientId, clientSecret);
|
||||
post.setHeader("Authorization", authorization);
|
||||
|
||||
List<NameValuePair> parameters = new LinkedList<NameValuePair>();
|
||||
parameters.add(new BasicNameValuePair("username", username));
|
||||
parameters.add(new BasicNameValuePair("password", password));
|
||||
|
||||
UrlEncodedFormEntity formEntity;
|
||||
try {
|
||||
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
post.setEntity(formEntity);
|
||||
|
||||
return new AccessTokenResponse(client.execute(post));
|
||||
}
|
||||
|
||||
public HttpResponse doLogout(String redirectUri, String sessionState) throws IOException {
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpGet get = new HttpGet(getLogoutUrl(redirectUri, sessionState));
|
||||
|
||||
return client.execute(get);
|
||||
}
|
||||
|
||||
public AccessTokenResponse doRefreshTokenRequest(String refreshToken, String password) {
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(getRefreshTokenUrl());
|
||||
|
||||
List<NameValuePair> parameters = new LinkedList<NameValuePair>();
|
||||
if (grantType != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.GRANT_TYPE, grantType));
|
||||
}
|
||||
if (refreshToken != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.REFRESH_TOKEN, refreshToken));
|
||||
}
|
||||
if (clientId != null && password != null) {
|
||||
String authorization = BasicAuthHelper.createHeader(clientId, password);
|
||||
post.setHeader("Authorization", authorization);
|
||||
}
|
||||
else if (clientId != null) {
|
||||
parameters.add(new BasicNameValuePair(OAuth2Constants.CLIENT_ID, clientId));
|
||||
}
|
||||
|
||||
UrlEncodedFormEntity formEntity;
|
||||
try {
|
||||
formEntity = new UrlEncodedFormEntity(parameters, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
post.setEntity(formEntity);
|
||||
|
||||
try {
|
||||
return new AccessTokenResponse(client.execute(post));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to retrieve access token", e);
|
||||
}
|
||||
}
|
||||
|
||||
public AccessToken verifyToken(String token) {
|
||||
try {
|
||||
return RSATokenVerifier.verifyToken(token, realmPublicKey, realm);
|
||||
} catch (VerificationException e) {
|
||||
throw new RuntimeException("Failed to verify token", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void verifyCode(String code) {
|
||||
if (!RSAProvider.verify(new JWSInput(code), realmPublicKey)) {
|
||||
throw new RuntimeException("Failed to verify code");
|
||||
}
|
||||
}
|
||||
|
||||
public RefreshToken verifyRefreshToken(String refreshToken) {
|
||||
try {
|
||||
JWSInput jws = new JWSInput(refreshToken);
|
||||
if (!RSAProvider.verify(jws, realmPublicKey)) {
|
||||
throw new RuntimeException("Invalid refresh token");
|
||||
}
|
||||
return jws.readJsonContent(RefreshToken.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Invalid refresh token", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public String getRedirectUri() {
|
||||
return redirectUri;
|
||||
}
|
||||
|
||||
public String getLoginFormUrl() {
|
||||
UriBuilder b = TokenService.loginPageUrl(UriBuilder.fromUri(baseUrl));
|
||||
if (responseType != null) {
|
||||
b.queryParam(OAuth2Constants.RESPONSE_TYPE, responseType);
|
||||
}
|
||||
if (clientId != null) {
|
||||
b.queryParam(OAuth2Constants.CLIENT_ID, clientId);
|
||||
}
|
||||
if (redirectUri != null) {
|
||||
b.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri);
|
||||
}
|
||||
if (state != null) {
|
||||
b.queryParam(OAuth2Constants.STATE, state);
|
||||
}
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public String getAccessTokenUrl() {
|
||||
UriBuilder b = TokenService.accessCodeToTokenUrl(UriBuilder.fromUri(baseUrl));
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public String getLogoutUrl(String redirectUri, String sessionState) {
|
||||
UriBuilder b = TokenService.logoutUrl(UriBuilder.fromUri(baseUrl));
|
||||
if (redirectUri != null) {
|
||||
b.queryParam(OAuth2Constants.REDIRECT_URI, redirectUri);
|
||||
}
|
||||
if (sessionState != null) {
|
||||
b.queryParam("session_state", sessionState);
|
||||
}
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public String getResourceOwnerPasswordCredentialGrantUrl() {
|
||||
UriBuilder b = TokenService.grantAccessTokenUrl(UriBuilder.fromUri(baseUrl));
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public String getRefreshTokenUrl() {
|
||||
UriBuilder b = TokenService.refreshUrl(UriBuilder.fromUri(baseUrl));
|
||||
return b.build(realm).toString();
|
||||
}
|
||||
|
||||
public OAuthClient realm(String realm) {
|
||||
this.realm = realm;
|
||||
return this;
|
||||
}
|
||||
public OAuthClient realmPublicKey(PublicKey key) {
|
||||
this.realmPublicKey = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient clientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient redirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient responseType(String responseType) {
|
||||
this.responseType = responseType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuthClient state(String state) {
|
||||
this.state = state;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public static class AuthorizationCodeResponse {
|
||||
|
||||
private String code;
|
||||
private String state;
|
||||
private String error;
|
||||
|
||||
public AuthorizationCodeResponse(OAuthClient client, HttpServletRequest req) {
|
||||
code = req.getParameter(OAuth2Constants.CODE);
|
||||
state = req.getParameter(OAuth2Constants.STATE);
|
||||
error = req.getParameter(OAuth2Constants.ERROR);
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class AccessTokenResponse {
|
||||
private int statusCode;
|
||||
|
||||
private String accessToken;
|
||||
private String tokenType;
|
||||
private int expiresIn;
|
||||
private String refreshToken;
|
||||
private String idToken;
|
||||
private String sessionState;
|
||||
|
||||
private String error;
|
||||
|
||||
public AccessTokenResponse(HttpResponse response) throws Exception {
|
||||
statusCode = response.getStatusLine().getStatusCode();
|
||||
if (!"application/json".equals(response.getHeaders("Content-Type")[0].getValue())) {
|
||||
throw new RuntimeException("Invalid content type");
|
||||
}
|
||||
|
||||
String s = IOUtils.toString(response.getEntity().getContent());
|
||||
JSONObject responseJson = new JSONObject(s);
|
||||
|
||||
if (statusCode == 200) {
|
||||
accessToken = responseJson.getString("access_token");
|
||||
tokenType = responseJson.getString("token_type");
|
||||
expiresIn = responseJson.getInt("expires_in");
|
||||
idToken = responseJson.optString("id_token");
|
||||
sessionState = responseJson.optString("session-state");
|
||||
|
||||
if (responseJson.has(OAuth2Constants.REFRESH_TOKEN)) {
|
||||
refreshToken = responseJson.getString(OAuth2Constants.REFRESH_TOKEN);
|
||||
}
|
||||
} else {
|
||||
error = responseJson.getString(OAuth2Constants.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public int getExpiresIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
public String getTokenType() {
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
public String getIdToken() {
|
||||
return idToken;
|
||||
}
|
||||
|
||||
public String getSessionState() {
|
||||
return sessionState;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,39 +1,115 @@
|
|||
package org.keycloak.testsuite.performance.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import freemarker.cache.ClassTemplateLoader;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.RefreshToken;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class PerfAppServlet extends HttpServlet {
|
||||
|
||||
private Template indexTemplate;
|
||||
private OAuthClient oauthClient;
|
||||
|
||||
@Override
|
||||
public void init() throws ServletException {
|
||||
try {
|
||||
Configuration cfg = new Configuration();
|
||||
cfg.setTemplateLoader(new ClassTemplateLoader(getClass(), "/"));
|
||||
indexTemplate = cfg.getTemplate("perf-app-resources/index.ftl");
|
||||
|
||||
oauthClient = new OAuthClient();
|
||||
} catch (IOException ioe) {
|
||||
throw new ServletException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String resourcePath = "perf-app-resources" + req.getPathInfo();
|
||||
System.out.println("Resource path: " + resourcePath);
|
||||
resp.setContentType("text/html");
|
||||
String action = req.getParameter("action");
|
||||
|
||||
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(resourcePath);
|
||||
if (inputStream == null) {
|
||||
resp.getWriter().println("Not found: " + resourcePath);
|
||||
} else {
|
||||
OutputStream servletOutputStream = resp.getOutputStream();
|
||||
|
||||
byte[] buf = new byte[1024];
|
||||
int bytesRead = 0;
|
||||
while (bytesRead != -1) {
|
||||
bytesRead = inputStream.read(buf);
|
||||
if (bytesRead != -1) {
|
||||
servletOutputStream.write(buf, 0, bytesRead);
|
||||
if (action != null) {
|
||||
if (action.equals("code")) {
|
||||
keycloakLoginRedirect(req, resp);
|
||||
return;
|
||||
} else if (action.equals("exchangeCode")) {
|
||||
exchangeCodeForToken(req, resp);
|
||||
} else if (action.equals("refresh")) {
|
||||
refreshToken(req, resp);
|
||||
} else if (action.equals("logout")) {
|
||||
logoutRedirect(req, resp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
servletOutputStream.flush();
|
||||
|
||||
String code = req.getParameter("code");
|
||||
if (code != null) {
|
||||
req.getSession().setAttribute("code", code);
|
||||
}
|
||||
|
||||
String freemarkerRedirect = freemarkerRedirect(req, resp);
|
||||
resp.getWriter().println(freemarkerRedirect);
|
||||
resp.getWriter().flush();
|
||||
}
|
||||
|
||||
protected void keycloakLoginRedirect(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String loginUrl = oauthClient.getLoginFormUrl();
|
||||
resp.sendRedirect(loginUrl);
|
||||
}
|
||||
|
||||
protected void exchangeCodeForToken(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String code = (String)req.getSession().getAttribute("code");
|
||||
OAuthClient.AccessTokenResponse atResponse = oauthClient.doAccessTokenRequest(code, "password");
|
||||
|
||||
String accessToken = atResponse.getAccessToken();
|
||||
String refreshToken = atResponse.getRefreshToken();
|
||||
req.getSession().setAttribute("accessToken", accessToken);
|
||||
req.getSession().setAttribute("refreshToken", refreshToken);
|
||||
}
|
||||
|
||||
protected void refreshToken(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
String refreshToken = (String)req.getSession().getAttribute("refreshToken");
|
||||
OAuthClient.AccessTokenResponse atResponse = oauthClient.doRefreshTokenRequest(refreshToken, "password");
|
||||
|
||||
String accessToken = atResponse.getAccessToken();
|
||||
refreshToken = atResponse.getRefreshToken();
|
||||
req.getSession().setAttribute("accessToken", accessToken);
|
||||
req.getSession().setAttribute("refreshToken", refreshToken);
|
||||
}
|
||||
|
||||
protected void logoutRedirect(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
|
||||
}
|
||||
|
||||
private String freemarkerRedirect(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
Map<String, Object> attributes = new HashMap<String, Object>();
|
||||
attributes.put("requestURI", req.getRequestURI());
|
||||
attributes.put("code", req.getSession().getAttribute("code"));
|
||||
attributes.put("accessToken", req.getSession().getAttribute("accessToken"));
|
||||
attributes.put("refreshToken", req.getSession().getAttribute("refreshToken"));
|
||||
|
||||
try {
|
||||
Writer out = new StringWriter();
|
||||
indexTemplate.process(attributes, out);
|
||||
return out.toString();
|
||||
} catch (TemplateException te) {
|
||||
throw new ServletException(te);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>PerfTest</title>
|
||||
<script>
|
||||
function updateElementWithToken(tokenStr, elementId) {
|
||||
if (tokenStr && tokenStr != "") {
|
||||
var tokenParsed = JSON.stringify(JSON.parse(decodeURIComponent(escape(window.atob( tokenStr.split('.')[1] )))), null, " ");
|
||||
document.getElementById(elementId).innerHTML = tokenParsed;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p><a href="${requestURI}?action=code">Login and get code</a> | <a href="${requestURI}?action=exchangeCode">Exchange code</a> | <a
|
||||
href="${requestURI}?action=refresh">Refresh token</a> | <a href="${requestURI}?action=logout">Logout</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<#if code??>
|
||||
Code: ${code}
|
||||
<hr />
|
||||
</#if>
|
||||
|
||||
<#if accessToken??>
|
||||
<b>accessToken: </b> ${accessToken}
|
||||
<br />
|
||||
<pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px;" id="accessTokenParsed"></pre>
|
||||
<hr />
|
||||
|
||||
<script>
|
||||
updateElementWithToken("${accessToken}", "accessTokenParsed");
|
||||
</script>
|
||||
</#if>
|
||||
|
||||
<#if refreshToken??>
|
||||
<b>refreshToken: </b> ${refreshToken}
|
||||
<br />
|
||||
<pre style="background-color: #ddd; border: 1px solid #ccc; padding: 10px;" id="refreshTokenParsed"></pre>
|
||||
<hr />
|
||||
|
||||
<script>
|
||||
updateElementWithToken("${refreshToken}", "refreshTokenParsed");
|
||||
</script>
|
||||
</#if>
|
||||
|
||||
</p>
|
||||
<br><br>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue