[Users | Trunk]: Add client secret method

This commit is contained in:
Konstantinos Triantafyllou 2020-11-12 10:36:20 +00:00
parent 66706b74c7
commit 63aeb7e8a1
4 changed files with 240 additions and 177 deletions

View File

@ -11,6 +11,7 @@ import org.apache.http.HttpResponse;
import org.apache.log4j.Logger;
import org.mitre.openid.connect.model.OIDCAuthenticationToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.method.P;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
@ -52,12 +53,6 @@ public class RegisterServiceServlet extends HttpServlet {
String idParam = request.getParameter("id");
String serviceName = (String) request.getSession().getAttribute("first_name");
String keyType = (String) request.getSession().getAttribute("key_radio");
String jwksUri = (String) request.getSession().getAttribute("uri");
String jwksString = (String) request.getSession().getAttribute("value");
if (idParam != null && !idParam.isEmpty()) { // EDIT CASE
System.out.println("In edit");
try {
@ -67,7 +62,7 @@ public class RegisterServiceServlet extends HttpServlet {
if (registeredService != null && registeredServicesUtils.isAuthorized(userid, id)) {
ServiceResponse serviceResponse = tokenUtils.getRegisteredService(registeredService.getClientId(), registeredService.getRegistrationAccessToken());
updateFormFields(request, serviceName, keyType, serviceResponse);
updateFormFields(request, registeredService.getName(), registeredService.getKeyType(), serviceResponse);
} else {
if (registeredService == null) {
@ -84,13 +79,13 @@ public class RegisterServiceServlet extends HttpServlet {
}
}
} catch(NumberFormatException nfe){
} catch (NumberFormatException nfe) {
System.out.println("WRONG FORMAT");
request.getSession().setAttribute("message", "Invalid service id.");
response.sendRedirect("./registeredServices");
logger.error("Invalid service id.", nfe);
} catch(SQLException sqle){
} catch (SQLException sqle) {
System.out.println("SQL PROBLEM");
request.getSession().setAttribute("message", "Could not fetch registered service.");
response.sendRedirect("./registeredServices");
@ -99,6 +94,10 @@ public class RegisterServiceServlet extends HttpServlet {
} else {// NEW SERVICE CASE
//Careful! Redirects in method
request.getSession().setAttribute("first_name", null);
request.getSession().setAttribute("key_type", null);
request.getSession().setAttribute("jwksUri", null);
request.getSession().setAttribute("value", null);
checkNumberOfRegisteredServices(request, response, authentication);
}
@ -107,22 +106,16 @@ public class RegisterServiceServlet extends HttpServlet {
}
private void updateFormFields(HttpServletRequest request, String serviceName, String keyType, ServiceResponse serviceResponse) {
System.out.println("UPDATING FORM");
if (serviceName == null || serviceName.trim().isEmpty()) {
request.getSession().setAttribute("first_name", serviceResponse.getClientName());
}
if (keyType == null || keyType.trim().isEmpty()) {
System.out.println("Service response URI " + serviceResponse.getJwksUri());
if (serviceResponse.getJwksUri() != null) {
request.getSession().setAttribute("key_radio","uri");
request.getSession().setAttribute("first_name", serviceName);
System.out.println("Service response URI " + serviceResponse.getJwksUri());
request.getSession().setAttribute("key_type", keyType);
if (keyType != null) {
if (keyType.equals("uri")) {
request.getSession().setAttribute("jwksUri", serviceResponse.getJwksUri());
} else {
request.getSession().setAttribute("key_radio", "value");
Key key;
if (serviceResponse.getJwks()!= null) {
if (serviceResponse.getJwks() != null) {
key = serviceResponse.getJwks().keys[0];
} else {
key = new Key();
@ -155,39 +148,41 @@ public class RegisterServiceServlet extends HttpServlet {
request.getSession().setAttribute("first_name_error", true);
canProceed = false;
}
String keyType = request.getParameter("key_radio").trim();
String keyType = request.getParameter("key_type");
String jwksUri = null;
String jwksString = null;
Jwks jwks = null;
if(keyType != null) {
keyType = keyType.trim();
if (keyType.equals("uri")) {
jwksUri = request.getParameter("uri");
request.getSession().setAttribute("jwksUri", jwksUri);
if (keyType.equals("uri")) {
jwksUri = request.getParameter("uri");
request.getSession().setAttribute("jwksUri", jwksUri);
String[] schemes = {"https"};
UrlValidator urlValidator = new UrlValidator(schemes);
if (!urlValidator.isValid(jwksUri)) {
request.getSession().setAttribute("uri_error", true);
canProceed = false;
}
} else {
jwksString = request.getParameter("value");
try {
Gson gson = new GsonBuilder().registerTypeAdapter(Jwks.class, new JwksDeserializer()).create();
String jwksSet = String.format("{\"keys\":[%s]}", jwksString);
jwks = gson.fromJson(jwksSet, Jwks.class);
request.getSession().setAttribute("value", jwksString);
String[] schemes = {"https"};
UrlValidator urlValidator = new UrlValidator(schemes);
if (!urlValidator.isValid(jwksUri)){
request.getSession().setAttribute("uri_error", true);
canProceed = false;
}
} else {
jwksString = request.getParameter("value");
try {
Gson gson = new GsonBuilder().registerTypeAdapter(Jwks.class, new JwksDeserializer()).create();
String jwksSet = String.format("{\"keys\":[%s]}", jwksString);
jwks = gson.fromJson(jwksSet, Jwks.class);
request.getSession().setAttribute("value", jwksString);
if (jwks.getKeys() == null || jwks.getKeys().length == 0) {
System.out.println("Something wrong with the keys.");
request.getSession().setAttribute("value_error", true);
canProceed = false;
}
if (jwks.getKeys() == null || jwks.getKeys().length == 0) {
System.out.println("Something wrong with the keys.");
} catch (JsonParseException jpe) {
request.getSession().setAttribute("value_error", true);
canProceed = false;
}
} catch (JsonParseException jpe) {
request.getSession().setAttribute("value_error", true);
canProceed = false;
}
}
String userid = authentication.getSub();
@ -198,38 +193,52 @@ public class RegisterServiceServlet extends HttpServlet {
String serverMessage;
if(mode.equals("create")) {
if (mode.equals("create")) {
//Careful! Redirects in method
checkNumberOfRegisteredServices(request, response, authentication);
String serverRequestJSON;
if (keyType.equals("uri")){
String serverRequestJSON = null;
if(keyType == null) {
serverRequestJSON = createServiceJson(null, name, email);
} else if (keyType.equals("uri")) {
serverRequestJSON = createServiceJson(null, name, email, jwksUri);
} else {
} else if (keyType.equals("value")){
serverRequestJSON = createServiceJson(null, name, email, jwks);
}
if(serverRequestJSON != null) {
System.out.println("SERVER JSON " + serverRequestJSON);
serverMessage = tokenUtils.registerService(serverRequestJSON);
logger.debug(serverMessage);
if (serverMessage == null) {
request.getSession().setAttribute("message", "There was an error registering your service. Please try again later.");
response.sendRedirect("./registeredServices");
return;
}
serviceResponse = new Gson().fromJson(serverMessage, ServiceResponse.class);
String client_id = serviceResponse.getClientId();
System.out.println("SERVER JSON " + serverRequestJSON);
RegisteredService registeredService = new RegisteredService(client_id, userid, name, serviceResponse.getRegistrationAccessToken(), keyType);
serverMessage = tokenUtils.registerService(serverRequestJSON);
logger.debug(serverMessage);
if (serverMessage == null) {
request.getSession().setAttribute("message", "There was an error registering your service. Please try again later.");
response.sendRedirect("./registeredServices");
return;
}
serviceResponse = new Gson().fromJson(serverMessage, ServiceResponse.class);
String client_id = serviceResponse.getClientId();
String owner = userid;
try {
registeredServicesUtils.addRegistedService(registeredService);
if(registeredService.getKeyType() != null) {
request.getSession().setAttribute("success",
"Your service has been successfully registered!<br>" +
"<b>Client ID<b>: " + serviceResponse.getClientId());
} else {
request.getSession().setAttribute("success",
"Your service has been successfully registered!<br>" +
"<b>Client ID</b>: " + serviceResponse.getClientId() +
"<br><span style=\"word-wrap: break-word\"><b>Client Secret</b>: " + serviceResponse.getClientSecret() + "</span>");
}
RegisteredService registeredService = new RegisteredService(client_id, owner, name, serviceResponse.getRegistrationAccessToken());
try {
registeredServicesUtils.addRegistedService(registeredService);
request.getSession().setAttribute("success", "Your service has been successfully registered!The id of your service is " +
serviceResponse.getClientId());
} catch (SQLException sqle) {
logger.error("Fail to save service.", sqle);
} catch (SQLException sqle) {
logger.error("Fail to save service.", sqle);
request.getSession().setAttribute("message", "There was an error registering your service. Please try again later.");
response.sendRedirect("./registeredServices");
return;
}
} else {
logger.error("Service request JSON is null");
request.getSession().setAttribute("message", "There was an error registering your service. Please try again later.");
response.sendRedirect("./registeredServices");
return;
@ -251,61 +260,69 @@ public class RegisterServiceServlet extends HttpServlet {
RegisteredService registeredService = registeredServicesUtils.getRegisteredServiceDao().fetchRegisteredServiceById(serviceIdInt);
if (registeredService != null && registeredService.getClientId() != null) {
String serverRequestJSON;
if (keyType.equals("uri")){
String serverRequestJSON = null;
if (keyType == null) {
serverRequestJSON = createServiceJson(registeredService.getClientId(), name, email);
} else if (keyType.equals("uri")) {
serverRequestJSON = createServiceJson(registeredService.getClientId(), name, email, jwksUri);
} else {
} else if (keyType.equals("value")) {
serverRequestJSON = createServiceJson(registeredService.getClientId(), name, email, jwks);
}
System.out.println("SERVER JSON " + serverRequestJSON);
HttpResponse resp = tokenUtils.updateService(registeredService.getClientId(), serverRequestJSON, registeredService.getRegistrationAccessToken());
if (resp.getStatusLine().getStatusCode()==200) {
System.out.println("NAME >>>>" + name);
registeredService.setName(name);
if (serverRequestJSON != null) {
System.out.println("SERVER JSON " + serverRequestJSON);
HttpResponse resp = tokenUtils.updateService(registeredService.getClientId(), serverRequestJSON, registeredService.getRegistrationAccessToken());
if (resp.getStatusLine().getStatusCode() == 200) {
System.out.println("NAME >>>>" + name);
registeredService.setName(name);
System.out.println("Client Id " + registeredService.getClientId());
try {
registeredServicesUtils.getRegisteredServiceDao().update(registeredService);
} catch (SQLException sqle) {
logger.error("Unable to contact db.", sqle);
request.getSession().setAttribute("message", "Fail to delete the service. Please try again later.");
response.setContentType("text/html");
request.getRequestDispatcher("./registeredServices.jsp").include(request, response);
return;
System.out.println("Client Id " + registeredService.getClientId());
try {
registeredServicesUtils.getRegisteredServiceDao().update(registeredService);
} catch (SQLException sqle) {
logger.error("Unable to contact db.", sqle);
request.getSession().setAttribute("message", "Fail to delete the service. Please try again later.");
response.setContentType("text/html");
request.getRequestDispatcher("./registeredServices.jsp").include(request, response);
return;
}
request.getSession().setAttribute("success",
"Your service has been successfully updated!<br>" +
"<b>Client ID</b>: " + registeredService.getClientId());
}
request.getSession().setAttribute("success", "Your service with name " + name + " was successfully updated.The id of your service " +
"is " + registeredService.getClientId());
} else {
request.getSession().setAttribute("message", "Service with id " + serviceId + " does not exist.");
response.sendRedirect("./registeredServices");
return;
}
} else {
request.getSession().setAttribute("message", "Service with id " + serviceId + " does not exist.");
logger.error("Service request JSON is null");
request.getSession().setAttribute("message", "There was an error registering your service. Please try again later.");
response.sendRedirect("./registeredServices");
return;
}
} catch(SQLException sqle){
logger.error("Unable to access service with id " + serviceId, sqle);
request.getSession().setAttribute("message", "There was an error accessing your service.");
response.sendRedirect("./registeredServices");
} catch (SQLException sqle) {
logger.error("Unable to access service with id " + serviceId, sqle);
request.getSession().setAttribute("message", "There was an error accessing your service.");
response.sendRedirect("./registeredServices");
} catch (NumberFormatException nfe) {
logger.error("Unable to access service with id " + serviceId, nfe);
request.getSession().setAttribute("message", "Service with id " + serviceId + " does not exist.");
response.sendRedirect("./registeredServices");
}
} catch(NumberFormatException nfe){
logger.error("Unable to access service with id " + serviceId, nfe);
request.getSession().setAttribute("message", "Service with id " + serviceId + " does not exist.");
response.sendRedirect("./registeredServices");
}
}
}
} else {
//something is wrong with the form and the error messages will appear
request.getSession().setAttribute("first_name", name);
request.getSession().setAttribute("key_radio", keyType);
request.getSession().setAttribute("uri", jwksUri);
request.getSession().setAttribute("value", jwksString);
request.getSession().setAttribute("key_type", keyType);
request.getSession().setAttribute("uri", jwksUri);
request.getSession().setAttribute("value", jwksString);
if ( serviceId != null && !serviceId.isEmpty()) {
request.getRequestDispatcher("./registerService.jsp?id="+serviceId).forward(request, response);
if (serviceId != null && !serviceId.isEmpty()) {
request.getRequestDispatcher("./registerService.jsp?id=" + serviceId).forward(request, response);
} else {
request.getRequestDispatcher("./registerService.jsp").include(request, response);
@ -318,8 +335,8 @@ public class RegisterServiceServlet extends HttpServlet {
}
private void checkmode(String mode) {
if (mode!=null && !mode.isEmpty()) {
if(!mode.equals("edit")||mode.equals("create")) {
if (mode != null && !mode.isEmpty()) {
if (!mode.equals("edit") || mode.equals("create")) {
mode = "create";
}
} else {
@ -328,7 +345,7 @@ public class RegisterServiceServlet extends HttpServlet {
}
private boolean keyIsValid(String keyType, String jwksUri, String jwksString) {
return (keyType.equals("uri") && jwksUri != null && !jwksUri.isEmpty()) ||
return keyType == null || (keyType.equals("uri") && jwksUri != null && !jwksUri.isEmpty()) ||
keyType.equals("value") && jwksString != null && !jwksString.isEmpty();
}
@ -358,6 +375,20 @@ public class RegisterServiceServlet extends HttpServlet {
}
}
private static String createServiceJson(String clientId, String name, String email) {
ServiceRequest serviceJSON = new ServiceRequest();
serviceJSON.setClientId(clientId);
serviceJSON.setClientName(name);
serviceJSON.setContacts(new String[]{email});
serviceJSON.setToken_endpoint_auth_method("client_secret_basic");
serviceJSON.setTokenEndpointAuthSigningAlg(null);
GsonBuilder builder = new GsonBuilder();
builder.serializeNulls();
Gson gson = builder.create();
System.out.println("Created json " + serviceJSON);
return gson.toJson(serviceJSON);
}
private static String createServiceJson(String clientId, String name, String email, String jwksURI) {
ServiceRequest serviceJSON = new ServiceRequest();
serviceJSON.setClientId(clientId);
@ -368,7 +399,7 @@ public class RegisterServiceServlet extends HttpServlet {
GsonBuilder builder = new GsonBuilder();
builder.serializeNulls();
Gson gson = builder.create();
System.out.println("Created json " +serviceJSON);
System.out.println("Created json " + serviceJSON);
return gson.toJson(serviceJSON);
}
@ -382,7 +413,7 @@ public class RegisterServiceServlet extends HttpServlet {
GsonBuilder builder = new GsonBuilder();
builder.serializeNulls();
Gson gson = builder.create();
System.out.println("Created json " +serviceJSON);
System.out.println("Created json " + serviceJSON);
return gson.toJson(serviceJSON);
}

View File

@ -33,7 +33,7 @@ public class TokenUtils {
HttpPost httppost = new HttpPost( issuer + "register");
httppost.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
StringEntity params = new StringEntity(serverRequestJSON.toString());
StringEntity params = new StringEntity(serverRequestJSON);
httppost.setEntity(params);
CloseableHttpClient httpclient = HttpClients.createDefault();

View File

@ -68,11 +68,12 @@
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<div class="alert alert-success" aria-hidden="true" style="display: none;"></div>
<div class="alert alert-danger" aria-hidden="true" style="display: none;"></div>
<h4 class="uk-text-bold uk-text-center">General</h4>
<div class="uk-margin-medium-top">
<label class="uk-form-label uk-text-bold" for="first_name">Name*</label>
<div class="uk-margin-small">Give a name to your service</div>
<input id="first_name" name="first_name" type="text" placeholder="Name (*)"
class="uk-input ${first_name_error == true?'uk-form-danger':''}" onkeyup="validate()" onfocusout="nameTouched = true;validate()" value="${first_name}">
class="uk-input ${first_name_error == true?'uk-form-danger':''}"
onkeyup="validate()" onfocusout="nameTouched = true;validate()" value="${(first_name != null)?first_name:''}">
<c:choose>
<c:when test="${first_name_error == true}">
<div id="first_name_error" class="uk-text-danger uk-text-small">Please enter a name for your service.
@ -85,47 +86,47 @@
<c:remove var="first_name" scope="session"/>
<c:remove var="first_name_error" scope="session"/>
</div>
<h4 class="uk-text-bold uk-text-center">Access</h4>
<div class="uk-margin-medium-top">
<label class="uk-form-label uk-text-bold">Scope</label>
<input disabled value="openid" class="uk-input">
<label class="uk-form-label uk-text-bold">Security level</label>
<div class="uk-margin">Security level hint</div>
<div class="uk-margin-small-top">
<span class="uk-margin-small-right">
<input id="basic" class="uk-radio uk-margin-small-right" type="radio"
name="security_level"
value="basic" ${key_type == null ? 'checked' : ''}>
<label class="clickable" for="by_value">Basic</label>
</span>
<span>
<input id="advanced" class="uk-radio uk-margin-small-right" type="radio"
name="security_level" value="advanced" ${key_type != null ? 'checked' : ''}>
<label class="clickable" for="by_uri">Advanced</label>
</span>
</div>
</div>
<div class="uk-margin-medium-top">
<label class="uk-form-label uk-text-bold">Grant Types</label>
<input disabled value="client credentials" class="uk-input">
</div>
<h4 class="uk-text-bold uk-text-center">Credentials</h4>
<div class="uk-margin-medium-top">
<label class="uk-form-label uk-text-bold">Authentication Method</label>
<input disabled value="Asymmetrically-signed JWT assertion" class="uk-input">
</div>
<div class="uk-margin-medium-top">
<label class="uk-form-label uk-text-bold">Token Endpoint Authentication
Signing Algorithm</label>
<input disabled value="RSASSA using SHA-256 hash algorithm" class="uk-input">
</div>
<div class="uk-margin-medium-top">
<div id="public-key" class="uk-margin-medium-top">
<label class="uk-form-label uk-text-bold">Public Key</label>
<span class="uk-float-right">
<span class="uk-margin-small-right">
<input id="by_value" class="uk-radio uk-margin-small-right" type="radio"
name="key_radio"
value="value" ${(key_radio == 'value' || key_radio == '' || key_radio == null) ? 'checked' : ''}>
name="key_type"
value="value" ${(key_type == 'value') ? 'checked' : ''}>
<label class="clickable" for="by_value">By Value</label>
</span>
<span>
<input id="by_uri" class="uk-radio uk-margin-small-right" type="radio"
name="key_radio" value="uri" ${key_radio == 'uri' ? 'checked' : ''}>
name="key_type"
value="uri" ${key_type == 'uri' ? 'checked' : ''}>
<label class="clickable" for="by_uri">By URI</label>
</span>
</span>
<c:remove var="key_radio" scope="session"/>
<c:remove var="key_type" scope="session"/>
<div class="uk-margin">Public Key hint</div>
<div id="value_input">
<textarea id="value" name="value" type="textarea"
placeholder='{"kty": ..., "e": ... , "use": ... , "kid": ..., "alg": ... , "n": ...}'
onfocusout="valueTouched = true;validate()"
onkeyup="validate()"
class="uk-textarea ${value_error == true?'uk-form-danger':''}" rows="10">${value}</textarea>
class="uk-textarea ${value_error == true?'uk-form-danger':''}" rows="10">${(value != null)?value:''}</textarea>
<c:choose>
<c:when test="${value_error == true}">
<div id="value_error" class="uk-text-danger uk-text-small">Please provide a valid JSON. The format should be
@ -142,7 +143,7 @@
<div id="uri_input" style="display:none;">
<input id="uri" name="uri" type="text" placeholder="https://" onfocusout="uriTouched = true;validate()"
onkeyup="validate()"
class="uk-input ${uri_error == true?'uk-form-danger':''}" value="${jwksUri}">
class="uk-input ${uri_error == true?'uk-form-danger':''}" value="${(jwksUri != null)?jwksUri:''}">
<c:choose>
<c:when test="${uri_error == true}">
<div id="uri_error" class="uk-text-danger uk-text-small">
@ -192,24 +193,44 @@
var uriTouched = false;
$(document).ready(function () {
checkRadio();
if($('input[name=mode]').val() === 'edit') {
$("#basic").prop("disabled", true);
$("#advanced").prop("disabled", true);
}
if($('#value_error').is(':visible')) {
$("#value_input").get(0).scrollIntoView();
} else if($('#uri_error').is(':visible')) {
$("#uri_input").get(0).scrollIntoView();
}
$('input[type=radio][name=key_radio]').change(function () {
$('input[type=radio][name=security_level]').change(function () {
var securityLevel = $('input[type=radio][name=security_level]:checked').val();
if(securityLevel === 'advanced') {
$("#by_value").prop("checked", true);
} else {
$("#by_value").prop("checked", false);
$("#by_uri").prop("checked", false);
}
checkRadio();
});
$('input[type=radio][name=key_type]').change(function () {
checkRadio();
});
});
function checkRadio() {
var radio = $('input[type=radio][name=key_radio]:checked').val();
if (radio === 'uri') {
$("#uri_input").show();
$("#value_input").hide();
} else if (radio === 'value') {
$("#uri_input").hide();
$("#value_input").show();
var securityLevel = $('input[type=radio][name=security_level]:checked').val();
if(securityLevel === 'basic') {
$("#public-key").hide();
} else {
var keyType = $('input[type=radio][name=key_type]:checked').val();
$("#public-key").show();
if (keyType === 'uri') {
$("#uri_input").show();
$("#value_input").hide();
} else if (keyType === 'value') {
$("#uri_input").hide();
$("#value_input").show();
}
}
validate();
}
@ -225,7 +246,6 @@
if (nameTouched) {
name.addClass('uk-form-danger');
$("#first_name_error").show();
$("#first_name").get(0).scrollIntoView();
}
isValid = false;
} else {
@ -235,35 +255,39 @@
}
}
}
var radio = $('input[type=radio][name=key_radio]:checked');
if (radio.val() === 'value') {
if (!validateJSON()) {
if (valueTouched) {
$("#value").addClass('uk-form-danger');
$("#value_error").show();
var securityLevel = $('input[type=radio][name=security_level]:checked').val();
if(securityLevel === 'advanced') {
var keyType = $('input[type=radio][name=key_type]:checked');
if (keyType.val() === 'value') {
if (!validateJSON()) {
if (valueTouched) {
$("#value").addClass('uk-form-danger');
$("#value_error").show();
}
isValid = false;
} else {
if (valueTouched) {
$("#value").removeClass('uk-form-danger');
$("#value_error").hide();
}
}
isValid = false;
} else {
if (valueTouched) {
$("#value").removeClass('uk-form-danger');
$("#value_error").hide();
}
}
}
if (radio.val() === 'uri') {
if (!validateURI()) {
if (uriTouched) {
$("#uri").addClass('uk-form-danger');
$("#uri_error").show();
}
isValid = false;
} else {
if (uriTouched) {
$("#uri").removeClass('uk-form-danger');
$("#uri_error").hide();
}
if (keyType.val() === 'uri') {
if (!validateURI()) {
if (uriTouched) {
$("#uri").addClass('uk-form-danger');
$("#uri_error").show();
}
isValid = false;
} else {
if (uriTouched) {
$("#uri").removeClass('uk-form-danger');
$("#uri_error").hide();
}
}
}
}
if (isValid) {
create.prop('disabled', false);
}

View File

@ -143,12 +143,20 @@
<p><span class="uk-text-primary">Service Id:</span> ${services[key].clientId}</p>
<p><span class="uk-text-primary">Scope:</span> openid</p>
<p><span class="uk-text-primary">Grant type:</span> client credentials</p>
<p><span class="uk-text-primary">Authentication Method</span> Asymmetrically-signed JWT assertion</p>
<p><span class="uk-text-primary">Token Endpoint Authentication Signing Algorithm</span> RSASSA using
SHA-256 hash algorithm</p>
<p><span class="uk-text-primary">Public Key</span>
<pre><code>${keys[key]}</code></pre>
</p>
<c:choose>
<c:when test="${registeredService.keyType == null}">
<p><span class="uk-text-primary">Client secret:</span> ${services[key].clientSecret}</p>
<p><span class="uk-text-primary">Authentication Method</span> Client Secret Basic</p>
</c:when>
<c:otherwise>
<p><span class="uk-text-primary">Authentication Method</span> Asymmetrically-signed JWT assertion</p>
<p><span class="uk-text-primary">Token Endpoint Authentication Signing Algorithm</span> RSASSA using
SHA-256 hash algorithm</p>
<p><span class="uk-text-primary">Public Key</span>
<pre><code>${keys[key]}</code></pre>
</p>
</c:otherwise>
</c:choose>
<p><span class="uk-text-primary">Creation Date:</span>
<jsp:useBean id="date" class="java.util.Date"/>
<jsp:setProperty name="date" property="time" value="${services[key].clientIdIssuedAt*1000}"/>