KEYCLOAK-1295 pluggable client authentication. Support authenticate clients with signed JWT
This commit is contained in:
1 parent
a4e16ca9c7
commit
7028496601
74 files changed
+2630
-397
No files matched your search
@@ -623,10 +623,67 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||
},
|
||||
client : function(ClientLoader) {
|
||||
return ClientLoader();
|
||||
},
|
||||
clientAuthenticatorProviders : function(ClientAuthenticatorProvidersLoader) {
|
||||
return ClientAuthenticatorProvidersLoader();
|
||||
}
|
||||
},
|
||||
controller : 'ClientCredentialsCtrl'
|
||||
})
|
||||
.when('/realms/:realm/clients/:client/credentials/client-secret', {
|
||||
templateUrl : resourceUrl + '/partials/client-credentials-secret.html',
|
||||
resolve : {
|
||||
realm : function(RealmLoader) {
|
||||
return RealmLoader();
|
||||
},
|
||||
client : function(ClientLoader) {
|
||||
return ClientLoader();
|
||||
}
|
||||
},
|
||||
controller : 'ClientSecretCtrl'
|
||||
})
|
||||
.when('/realms/:realm/clients/:client/credentials/client-signed-jwt', {
|
||||
templateUrl : resourceUrl + '/partials/client-credentials-jwt.html',
|
||||
resolve : {
|
||||
realm : function(RealmLoader) {
|
||||
return RealmLoader();
|
||||
},
|
||||
client : function(ClientLoader) {
|
||||
return ClientLoader();
|
||||
}
|
||||
},
|
||||
controller : 'ClientSignedJWTCtrl'
|
||||
})
|
||||
.when('/realms/:realm/clients/:client/credentials/client-signed-jwt/:keyType/import/:attribute', {
|
||||
templateUrl : resourceUrl + '/partials/client-credentials-jwt-key-import.html',
|
||||
resolve : {
|
||||
realm : function(RealmLoader) {
|
||||
return RealmLoader();
|
||||
},
|
||||
client : function(ClientLoader) {
|
||||
return ClientLoader();
|
||||
},
|
||||
callingContext : function() {
|
||||
return "jwt-credentials";
|
||||
}
|
||||
},
|
||||
controller : 'ClientCertificateImportCtrl'
|
||||
})
|
||||
.when('/realms/:realm/clients/:client/credentials/client-signed-jwt/:keyType/export/:attribute', {
|
||||
templateUrl : resourceUrl + '/partials/client-credentials-jwt-key-export.html',
|
||||
resolve : {
|
||||
realm : function(RealmLoader) {
|
||||
return RealmLoader();
|
||||
},
|
||||
client : function(ClientLoader) {
|
||||
return ClientLoader();
|
||||
},
|
||||
callingContext : function() {
|
||||
return "jwt-credentials";
|
||||
}
|
||||
},
|
||||
controller : 'ClientCertificateExportCtrl'
|
||||
})
|
||||
.when('/realms/:realm/clients/:client/identity-provider', {
|
||||
templateUrl : resourceUrl + '/partials/client-identity-provider.html',
|
||||
resolve : {
|
||||
@@ -695,6 +752,9 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||
},
|
||||
client : function(ClientLoader) {
|
||||
return ClientLoader();
|
||||
},
|
||||
callingContext : function() {
|
||||
return "saml";
|
||||
}
|
||||
},
|
||||
controller : 'ClientCertificateImportCtrl'
|
||||
@@ -707,6 +767,9 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||
},
|
||||
client : function(ClientLoader) {
|
||||
return ClientLoader();
|
||||
},
|
||||
callingContext : function() {
|
||||
return "saml";
|
||||
}
|
||||
},
|
||||
controller : 'ClientCertificateExportCtrl'
|
||||
@@ -1134,6 +1197,9 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||
},
|
||||
authenticatorProviders : function(AuthenticatorProvidersLoader) {
|
||||
return AuthenticatorProvidersLoader();
|
||||
},
|
||||
clientAuthenticatorProviders : function(ClientAuthenticatorProvidersLoader) {
|
||||
return ClientAuthenticatorProvidersLoader();
|
||||
}
|
||||
},
|
||||
controller : 'CreateExecutionCtrl'
|
||||
|
||||
+71
-14
@@ -30,17 +30,23 @@ module.controller('ClientRoleListCtrl', function($scope, $location, realm, clien
|
||||
});
|
||||
});
|
||||
|
||||
module.controller('ClientCredentialsCtrl', function($scope, $location, realm, client, ClientCredentials, Notifications) {
|
||||
module.controller('ClientCredentialsCtrl', function($scope, $location, realm, client, clientAuthenticatorProviders, Notifications) {
|
||||
$scope.realm = realm;
|
||||
$scope.client = client;
|
||||
var secret = ClientCredentials.get({ realm : realm.realm, client : client.id },
|
||||
$scope.clientAuthenticatorProviders = clientAuthenticatorProviders;
|
||||
});
|
||||
|
||||
module.controller('ClientSecretCtrl', function($scope, $location, realm, client, ClientSecret, Notifications) {
|
||||
$scope.realm = realm;
|
||||
$scope.client = client;
|
||||
var secret = ClientSecret.get({ realm : realm.realm, client : client.id },
|
||||
function() {
|
||||
$scope.secret = secret.value;
|
||||
}
|
||||
);
|
||||
|
||||
$scope.changePassword = function() {
|
||||
var secret = ClientCredentials.update({ realm : realm.realm, client : client.id },
|
||||
var secret = ClientSecret.update({ realm : realm.realm, client : client.id },
|
||||
function() {
|
||||
Notifications.success('The secret has been changed.');
|
||||
$scope.secret = secret.value;
|
||||
@@ -57,6 +63,34 @@ module.controller('ClientCredentialsCtrl', function($scope, $location, realm, cl
|
||||
}, function() {
|
||||
$scope.path = $location.path().substring(1).split("/");
|
||||
});
|
||||
|
||||
$scope.cancel = function() {
|
||||
$location.url("/realms/" + realm.realm + "/clients/" + client.id + "/credentials");
|
||||
};
|
||||
});
|
||||
|
||||
module.controller('ClientSignedJWTCtrl', function($scope, $location, realm, client, ClientCertificate, Notifications) {
|
||||
|
||||
$scope.realm = realm;
|
||||
$scope.client = client;
|
||||
|
||||
var signingKeyInfo = ClientCertificate.get({ realm : realm.realm, client : client.id, attribute: 'jwt.credentials' },
|
||||
function() {
|
||||
$scope.signingKeyInfo = signingKeyInfo;
|
||||
}
|
||||
);
|
||||
|
||||
$scope.importCertificate = function() {
|
||||
$location.url("/realms/" + realm.realm + "/clients/" + client.id + "/credentials/client-signed-jwt/Signing/import/jwt.credentials");
|
||||
};
|
||||
|
||||
$scope.generateSigningKey = function() {
|
||||
$location.url("/realms/" + realm.realm + "/clients/" + client.id + "/credentials/client-signed-jwt/Signing/export/jwt.credentials");
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$location.url("/realms/" + realm.realm + "/clients/" + client.id + "/credentials");
|
||||
};
|
||||
});
|
||||
|
||||
module.controller('ClientIdentityProviderCtrl', function($scope, $location, $route, realm, client, Client, $location, Notifications) {
|
||||
@@ -212,16 +246,26 @@ module.controller('ClientSamlKeyCtrl', function($scope, $location, $http, $uploa
|
||||
});
|
||||
});
|
||||
|
||||
module.controller('ClientCertificateImportCtrl', function($scope, $location, $http, $upload, realm, client, $routeParams,
|
||||
module.controller('ClientCertificateImportCtrl', function($scope, $location, $http, $upload, realm, client, callingContext, $routeParams,
|
||||
ClientCertificate, ClientCertificateGenerate,
|
||||
ClientCertificateDownload, Notifications) {
|
||||
|
||||
console.log("callingContext: " + callingContext);
|
||||
|
||||
var keyType = $routeParams.keyType;
|
||||
var attribute = $routeParams.attribute;
|
||||
$scope.realm = realm;
|
||||
$scope.client = client;
|
||||
$scope.keyType = keyType;
|
||||
|
||||
if (callingContext == 'saml') {
|
||||
var uploadUrl = authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/certificates/' + attribute + '/upload';
|
||||
var redirectLocation = "/realms/" + realm.realm + "/clients/" + client.id + "/saml/keys";
|
||||
} else if (callingContext == 'jwt-credentials') {
|
||||
var uploadUrl = authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/certificates/' + attribute + '/upload-certificate';
|
||||
var redirectLocation = "/realms/" + realm.realm + "/clients/" + client.id + "/credentials/client-signed-jwt";
|
||||
}
|
||||
|
||||
$scope.files = [];
|
||||
|
||||
$scope.onFileSelect = function($files) {
|
||||
@@ -244,7 +288,7 @@ module.controller('ClientCertificateImportCtrl', function($scope, $location, $ht
|
||||
for (var i = 0; i < $scope.files.length; i++) {
|
||||
var $file = $scope.files[i];
|
||||
$scope.upload = $upload.upload({
|
||||
url: authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/certificates/' + attribute + '/upload',
|
||||
url: uploadUrl,
|
||||
// method: POST or PUT,
|
||||
// headers: {'headerKey': 'headerValue'}, withCredential: true,
|
||||
data: {keystoreFormat: $scope.uploadKeyFormat,
|
||||
@@ -259,12 +303,11 @@ module.controller('ClientCertificateImportCtrl', function($scope, $location, $ht
|
||||
//formDataAppender: function(formData, key, val){}
|
||||
}).success(function(data, status, headers) {
|
||||
Notifications.success("Keystore uploaded successfully.");
|
||||
$location.url("/realms/" + realm.realm + "/clients/" + client.id + "/saml/keys");
|
||||
})
|
||||
.error(function() {
|
||||
Notifications.error("The key store can not be uploaded. Please verify the file.");
|
||||
|
||||
});
|
||||
$location.url(redirectLocation);
|
||||
}).error(function(data) {
|
||||
var errorMsg = data['error_description'] ? data['error_description'] : 'The key store can not be uploaded. Please verify the file.';
|
||||
Notifications.error(errorMsg);
|
||||
});
|
||||
//.then(success, error, progress);
|
||||
}
|
||||
};
|
||||
@@ -276,7 +319,7 @@ module.controller('ClientCertificateImportCtrl', function($scope, $location, $ht
|
||||
});
|
||||
});
|
||||
|
||||
module.controller('ClientCertificateExportCtrl', function($scope, $location, $http, $upload, realm, client, $routeParams,
|
||||
module.controller('ClientCertificateExportCtrl', function($scope, $location, $http, $upload, realm, client, callingContext, $routeParams,
|
||||
ClientCertificate, ClientCertificateGenerate,
|
||||
ClientCertificateDownload, Notifications) {
|
||||
var keyType = $routeParams.keyType;
|
||||
@@ -284,9 +327,19 @@ module.controller('ClientCertificateExportCtrl', function($scope, $location, $ht
|
||||
$scope.realm = realm;
|
||||
$scope.client = client;
|
||||
$scope.keyType = keyType;
|
||||
|
||||
if (callingContext == 'saml') {
|
||||
var downloadUrl = authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/certificates/' + attribute + '/download';
|
||||
var realmCertificate = true;
|
||||
} else if (callingContext == 'jwt-credentials') {
|
||||
var downloadUrl = authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/certificates/' + attribute + '/generate-and-download'
|
||||
var realmCertificate = false;
|
||||
}
|
||||
|
||||
var jks = {
|
||||
keyAlias: client.clientId,
|
||||
realmAlias: realm.realm
|
||||
realmAlias: realm.realm,
|
||||
realmCertificate: realmCertificate
|
||||
};
|
||||
|
||||
$scope.keyFormats = [
|
||||
@@ -304,7 +357,7 @@ module.controller('ClientCertificateExportCtrl', function($scope, $location, $ht
|
||||
|
||||
$scope.download = function() {
|
||||
$http({
|
||||
url: authUrl + '/admin/realms/' + realm.realm + '/clients/' + client.id + '/certificates/' + attribute + '/download',
|
||||
url: downloadUrl,
|
||||
method: 'POST',
|
||||
responseType: 'arraybuffer',
|
||||
data: $scope.jks,
|
||||
@@ -335,6 +388,10 @@ module.controller('ClientCertificateExportCtrl', function($scope, $location, $ht
|
||||
}, function() {
|
||||
$scope.path = $location.path().substring(1).split("/");
|
||||
});
|
||||
|
||||
$scope.cancel = function() {
|
||||
$location.url("/realms/" + realm.realm + "/clients/" + client.id + "/credentials/client-signed-jwt");
|
||||
}
|
||||
});
|
||||
|
||||
module.controller('ClientSessionsCtrl', function($scope, realm, sessionCount, client,
|
||||
|
||||
+6
-2
@@ -1656,9 +1656,11 @@ module.controller('CreateExecutionFlowCtrl', function($scope, realm, topFlow, pa
|
||||
Notifications, $location) {
|
||||
$scope.realm = realm;
|
||||
$scope.formProviders = formProviders;
|
||||
|
||||
var defaultFlowType = parentFlow.providerId == 'client-flow' ? 'client-flow' : 'basic-flow';
|
||||
$scope.flow = {
|
||||
alias: "",
|
||||
type: "basic-flow",
|
||||
type: defaultFlowType,
|
||||
description: ""
|
||||
}
|
||||
$scope.provider = {};
|
||||
@@ -1678,7 +1680,7 @@ module.controller('CreateExecutionFlowCtrl', function($scope, realm, topFlow, pa
|
||||
};
|
||||
});
|
||||
|
||||
module.controller('CreateExecutionCtrl', function($scope, realm, topFlow, parentFlow, formActionProviders, authenticatorProviders,
|
||||
module.controller('CreateExecutionCtrl', function($scope, realm, topFlow, parentFlow, formActionProviders, authenticatorProviders, clientAuthenticatorProviders,
|
||||
CreateExecution,
|
||||
Notifications, $location) {
|
||||
$scope.realm = realm;
|
||||
@@ -1686,6 +1688,8 @@ module.controller('CreateExecutionCtrl', function($scope, realm, topFlow, parent
|
||||
console.log('parentFlow.providerId: ' + parentFlow.providerId);
|
||||
if (parentFlow.providerId == 'form-flow') {
|
||||
$scope.providers = formActionProviders;
|
||||
} else if (parentFlow.providerId == 'client-flow') {
|
||||
$scope.providers = clientAuthenticatorProviders;
|
||||
} else {
|
||||
$scope.providers = authenticatorProviders;
|
||||
}
|
||||
|
||||
@@ -392,6 +392,14 @@ module.factory('AuthenticatorProvidersLoader', function(Loader, AuthenticatorPro
|
||||
});
|
||||
});
|
||||
|
||||
module.factory('ClientAuthenticatorProvidersLoader', function(Loader, ClientAuthenticatorProviders, $route, $q) {
|
||||
return Loader.query(ClientAuthenticatorProviders, function() {
|
||||
return {
|
||||
realm : $route.current.params.realm
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
module.factory('AuthenticationFlowLoader', function(Loader, AuthenticationFlows, $route, $q) {
|
||||
return Loader.get(AuthenticationFlows, function() {
|
||||
return {
|
||||
|
||||
@@ -931,7 +931,7 @@ module.factory('ClientInstallationJBoss', function($resource) {
|
||||
}
|
||||
});
|
||||
|
||||
module.factory('ClientCredentials', function($resource) {
|
||||
module.factory('ClientSecret', function($resource) {
|
||||
return $resource(authUrl + '/admin/realms/:realm/clients/:client/client-secret', {
|
||||
realm : '@realm',
|
||||
client : '@client'
|
||||
@@ -1223,6 +1223,12 @@ module.factory('AuthenticatorProviders', function($resource) {
|
||||
});
|
||||
});
|
||||
|
||||
module.factory('ClientAuthenticatorProviders', function($resource) {
|
||||
return $resource(authUrl + '/admin/realms/:realm/authentication/client-authenticator-providers', {
|
||||
realm : '@realm'
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
module.factory('AuthenticationFlowsCopy', function($resource) {
|
||||
return $resource(authUrl + '/admin/realms/:realm/authentication/flows/:alias/copy', {
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/credentials/client-signed-jwt">Signed JWT config</a></li>
|
||||
<li class="active">Generate Client Private Key</li>
|
||||
</ol>
|
||||
|
||||
<h1>Generate Private Key {{client.clientId|capitalize}}</h1>
|
||||
|
||||
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
|
||||
<fieldset class="form-group col-sm-10">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="downloadKeyFormat">Archive Format</label>
|
||||
<div class="col-sm-6">
|
||||
<div>
|
||||
<select class="form-control" id="downloadKeyFormat"
|
||||
ng-model="jks.format"
|
||||
ng-options="f for f in keyFormats">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<kc-tooltip>Java keystore or PKCS12 archive format.</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="keyAlias">Key Alias</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" id="keyAlias" name="keyAlias" data-ng-model="jks.keyAlias" autofocus required>
|
||||
</div>
|
||||
<kc-tooltip>Archive alias for your private key and certificate.</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="keyPassword">Key Password</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="password" id="keyPassword" name="keyPassword" data-ng-model="jks.keyPassword" autofocus required>
|
||||
</div>
|
||||
<kc-tooltip>Password to access the private key in the archive</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="storePassword">Store Password</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="password" id="storePassword" name="storePassword" data-ng-model="jks.storePassword" autofocus required>
|
||||
</div>
|
||||
<kc-tooltip>Password to access the archive itself</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-10 col-md-offset-2" data-ng-show="access.manageRealm">
|
||||
<button class="btn btn-primary" type="submit" data-ng-click="download()">Generate and Download</button>
|
||||
<button class="btn btn-primary" type="submit" data-ng-click="cancel()">Back</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<kc-menu></kc-menu>
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}">{{client.clientId}}</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/credentials/client-signed-jwt">Signed JWT config</a></li>
|
||||
<li class="active">Client Certificate Import</li>
|
||||
</ol>
|
||||
|
||||
<h1>Import Client Certificate {{client.clientId|capitalize}}</h1>
|
||||
|
||||
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
|
||||
<fieldset>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="uploadKeyFormat">Archive Format</label>
|
||||
<div class="col-sm-6">
|
||||
<div>
|
||||
<select class="form-control" id="uploadKeyFormat"
|
||||
ng-model="uploadKeyFormat"
|
||||
ng-options="f for f in keyFormats">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<kc-tooltip>Java keystore or PKCS12 archive format.</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="uploadKeyAlias">Key Alias</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="text" id="uploadKeyAlias" name="uploadKeyAlias" data-ng-model="uploadKeyAlias" autofocus required>
|
||||
</div>
|
||||
<kc-tooltip>Archive alias for your certificate.</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="uploadStorePassword">Store Password</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control" type="password" id="uploadStorePassword" name="uploadStorePassword" data-ng-model="uploadStorePassword" autofocus required>
|
||||
</div>
|
||||
<kc-tooltip>Password to access the archive itself</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">Import File </label>
|
||||
<div class="col-md-6">
|
||||
<div class="controls kc-button-input-file" data-ng-show="!files || files.length == 0">
|
||||
<label for="import-file" class="btn btn-default">Select file <i class="pficon pficon-import"></i></label>
|
||||
<input id="import-file" type="file" class="hidden" ng-file-select="onFileSelect($files)">
|
||||
</div>
|
||||
<span class="kc-uploaded-file" data-ng-show="files.length > 0">
|
||||
{{files[0].name}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-10 col-md-offset-2" data-ng-show="files.length > 0">
|
||||
<button type="submit" data-ng-click="uploadFile()" class="btn btn-primary">Import</button>
|
||||
<button type="submit" data-ng-click="clearFileSelect()" class="btn btn-default">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<kc-menu></kc-menu>
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
|
||||
<li>{{client.clientId}}</li>
|
||||
</ol>
|
||||
|
||||
<kc-tabs-client></kc-tabs-client>
|
||||
|
||||
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageClients">
|
||||
<fieldset class="form-group col-sm-10">
|
||||
<legend uncollapsed><span class="text">Client Certificate</span> <kc-tooltip>Client Certificate for validate JWT issued by client and signed by Client private key.</kc-tooltip></legend>
|
||||
<div class="form-group" data-ng-hide="!signingKeyInfo.certificate">
|
||||
<label class="col-md-2 control-label" for="signingCert">Certificate</label>
|
||||
|
||||
<div class="col-sm-10">
|
||||
<textarea type="text" id="signingCert" name="signingCert" class="form-control" rows="5"
|
||||
kc-select-action="click" readonly>{{signingKeyInfo.certificate}}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" data-ng-show="!signingKeyInfo.certificate">
|
||||
<label class="col-md-2 control-label" for="signingCert">Client Certificate not yet generated or imported!</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-10 col-md-offset-2" data-ng-show="access.manageClients">
|
||||
<button class="btn btn-default" type="submit" data-ng-click="generateSigningKey()">Generate new keys</button>
|
||||
<button class="btn btn-default" type="submit" data-ng-click="importCertificate()">Import certificate</button>
|
||||
<button class="btn btn-default" type="buttin" data-ng-click="cancel()">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<kc-menu></kc-menu>
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="#/realms/{{realm.realm}}/clients">Clients</a></li>
|
||||
<li>{{client.clientId}}</li>
|
||||
</ol>
|
||||
|
||||
<kc-tabs-client></kc-tabs-client>
|
||||
|
||||
<form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!access.manageClients">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="secret">Secret</label>
|
||||
<div class="col-sm-6">
|
||||
<input readonly kc-select-action="click" class="form-control" type="text" id="secret" name="secret" data-ng-model="secret">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-10 col-md-offset-2" data-ng-show="access.manageClients">
|
||||
<button type="submit" data-ng-click="changePassword()" class="btn btn-primary">Regenerate Secret</button>
|
||||
<button type="button" class="btn btn-default" ng-click="cancel()">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<kc-menu></kc-menu>
|
||||
+18
-14
@@ -7,20 +7,24 @@
|
||||
|
||||
<kc-tabs-client></kc-tabs-client>
|
||||
|
||||
<form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!access.manageClients">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="secret">Secret</label>
|
||||
<div class="col-sm-6">
|
||||
<input readonly kc-select-action="click" class="form-control" type="text" id="secret" name="secret" data-ng-model="secret">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-10 col-md-offset-2" data-ng-show="access.manageClients">
|
||||
<button type="submit" data-ng-click="changePassword()" class="btn btn-primary">Regenerate Secret</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr data-ng-hide="executions.length == 0">
|
||||
<th>Client Auth Type</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="authenticator in clientAuthenticatorProviders" data-ng-show="clientAuthenticatorProviders.length > 0">
|
||||
<td ng-repeat="lev in execution.preLevels"></td>
|
||||
<td>{{authenticator.displayName|capitalize}}</td>
|
||||
<td><a href="#/realms/{{realm.realm}}/clients/{{client.id}}/credentials/{{authenticator.id}}" data-ng-show="authenticator.configurablePerClient">Configure</a></td>
|
||||
</tr>
|
||||
<tr data-ng-show="clientAuthenticatorProviders.length == 0">
|
||||
<td>No client authenticators available</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<kc-menu></kc-menu>
|
||||
-2
@@ -5,8 +5,6 @@
|
||||
<li>{{client.clientId}}</li>
|
||||
</ol>
|
||||
|
||||
<h1>{{client.clientId|capitalize}}</h1>
|
||||
|
||||
<kc-tabs-client></kc-tabs-client>
|
||||
|
||||
<form class="form-horizontal" name="keyForm" novalidate kc-read-only="!access.manageRealm">
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
<textarea class="form-control" rows="5" cols="50" id="description" name="description" data-ng-model="flow.description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group" data-ng-hide="flow.type == 'client-flow'">
|
||||
<label class="col-md-2 control-label" for="flowType">Flow Type</label>
|
||||
<div class="col-sm-6">
|
||||
<div>
|
||||
|
||||
+13
@@ -18,6 +18,19 @@
|
||||
<textarea class="form-control" rows="5" cols="50" id="description" name="description" data-ng-model="flow.description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label" for="flowType">Top Level Flow Type</label>
|
||||
<div class="col-sm-6">
|
||||
<div>
|
||||
<select class="form-control" id="flowType"
|
||||
ng-model="flow.providerId">
|
||||
<option value="basic-flow">generic</option>
|
||||
<option value="client-flow">client</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<kc-tooltip>What kind of top level flow is it? Type 'client' is used for authentication of clients (applications) when generic is for everything else</kc-tooltip>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-10 col-md-offset-2">
|
||||
<button kc-save>Save</button>
|
||||
|
||||
Reference in new issue
Block a user