keycloak-aplcache
Changes
admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html 34(+6 -28)
admin-ui/src/main/resources/META-INF/resources/admin/partials/application-installation.html 18(+15 -3)
admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-credentials.html 38(+7 -31)
integration/adapter-core/src/main/java/org/keycloak/adapters/config/OAuthClientConfigLoader.java 2(+1 -1)
integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java 2(+0 -2)
Details
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
index 3fac2e4..9e5bc0b 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js
@@ -329,9 +329,6 @@ module.config([ '$routeProvider', function($routeProvider) {
},
application : function(ApplicationLoader) {
return ApplicationLoader();
- },
- installation : function(ApplicationInstallationLoader) {
- return ApplicationInstallationLoader();
}
},
controller : 'ApplicationInstallationCtrl'
@@ -399,9 +396,6 @@ module.config([ '$routeProvider', function($routeProvider) {
realm : function(RealmLoader) {
return RealmLoader();
},
- application : function(OAuthClientLoader) {
- return OAuthClientLoader();
- },
oauth : function(OAuthClientLoader) {
return OAuthClientLoader();
}
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js
index d4054c7..b6be8d0 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/applications.js
@@ -13,80 +13,25 @@ module.controller('ApplicationRoleListCtrl', function($scope, $location, realm,
module.controller('ApplicationCredentialsCtrl', function($scope, $location, realm, application, ApplicationCredentials, Notifications) {
$scope.realm = realm;
$scope.application = application;
-
- var required = realm.requiredApplicationCredentials;
-
- for (var i = 0; i < required.length; i++) {
- if (required[i] == 'password') {
- $scope.passwordRequired = true;
- } else if (required[i] == 'totp') {
- $scope.totpRequired = true;
- } else if (required[i] == 'cert') {
- $scope.certRequired = true;
- }
- }
-
- function randomString(len) {
- var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
- var randomString = '';
- for (var i = 0; i < len; i++) {
- var randomPoz = Math.floor(Math.random() * charSet.length);
- randomString += charSet.substring(randomPoz,randomPoz+1);
+ var secret = ApplicationCredentials.get({ realm : realm.realm, application : application.name },
+ function() {
+ $scope.secret = secret.value;
}
- return randomString;
- }
-
- $scope.generateTotp = function() {
- $scope.totp = randomString(5) + '-' + randomString(5) + '-' + randomString(5);
- }
+ );
$scope.changePassword = function() {
- if ($scope.password != $scope.confirmPassword) {
- Notifications.error("Password and confirmation does not match.");
- $scope.password = "";
- $scope.confirmPassword = "";
- return;
- }
- var creds = [
- {
- type : "password",
- value : $scope.password
- }
- ];
-
- ApplicationCredentials.update({ realm : realm.realm, application : application.name }, creds,
+ var secret = ApplicationCredentials.update({ realm : realm.realm, application : application.name },
function() {
- Notifications.success('The password has been changed.');
- $scope.password = null;
- $scope.confirmPassword = null;
+ Notifications.success('The secret has been changed.');
+ $scope.secret = secret.value;
},
function() {
- Notifications.error("The password was not changed due to a problem.");
- $scope.password = null;
- $scope.confirmPassword = null;
+ Notifications.error("The secret was not changed due to a problem.");
+ $scope.secret = "error";
}
);
};
- $scope.changeTotp = function() {
- var creds = [
- {
- type : "totp",
- value : $scope.totp
- }
- ];
-
- ApplicationCredentials.update({ realm : realm.realm, application : application.name }, creds,
- function() {
- Notifications.success('The totp was changed.');
- $scope.totp = null;
- },
- function() {
- Notifications.error("The totp was not changed due to a problem.");
- $scope.totp = null;
- }
- );
- };
$scope.$watch(function() {
return $location.path();
}, function() {
@@ -163,12 +108,37 @@ module.controller('ApplicationListCtrl', function($scope, realm, applications, A
});
});
-module.controller('ApplicationInstallationCtrl', function($scope, realm, installation, application, ApplicationInstallation, $routeParams) {
+module.controller('ApplicationInstallationCtrl', function($scope, realm, application, ApplicationInstallation,ApplicationInstallationJBoss, $http, $routeParams) {
console.log('ApplicationInstallationCtrl');
$scope.realm = realm;
$scope.application = application;
- $scope.installation = installation;
- $scope.download = ApplicationInstallation.url({ realm: $routeParams.realm, application: $routeParams.application });
+ $scope.installation = null;
+ $scope.download = null;
+ $scope.configFormat = null;
+
+ $scope.configFormats = [
+ "keycloak.json",
+ "Wildfly/JBoss Subsystem XML"
+ ];
+
+ $scope.changeFormat = function() {
+ if ($scope.configFormat == "keycloak.json") {
+ var url = ApplicationInstallation.url({ realm: $routeParams.realm, application: $routeParams.application });
+ var installation = $http.get(url).success(function(data) {
+ var tmp = angular.fromJson(data);
+ $scope.installation = angular.toJson(tmp, true);
+ })
+ $scope.download = url;
+ } else if ($scope.configFormat == "Wildfly/JBoss Subsystem XML") {
+ var url = ApplicationInstallationJBoss.url({ realm: $routeParams.realm, application: $routeParams.application });
+ var installation = $http.get(url).success(function(data) {
+ $scope.installation = data;
+ })
+ $scope.download = url;
+ }
+
+ };
+
});
module.controller('ApplicationDetailCtrl', function($scope, realm, application, Application, $location, Dialog, Notifications) {
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/oauth-clients.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/oauth-clients.js
index 6a642a3..4998583 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/oauth-clients.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/controllers/oauth-clients.js
@@ -2,84 +2,31 @@ module.controller('OAuthClientCredentialsCtrl', function($scope, $location, real
$scope.realm = realm;
$scope.oauth = oauth;
- var required = realm.requiredOAuthClientCredentials;
-
- for (var i = 0; i < required.length; i++) {
- if (required[i] == 'password') {
- $scope.passwordRequired = true;
- } else if (required[i] == 'totp') {
- $scope.totpRequired = true;
- } else if (required[i] == 'cert') {
- $scope.certRequired = true;
+ var secret = OAuthClientCredentials.get({ realm : realm.realm, oauth : oauth.id },
+ function() {
+ $scope.secret = secret.value;
}
- }
-
- function randomString(len) {
- var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
- var randomString = '';
- for (var i = 0; i < len; i++) {
- var randomPoz = Math.floor(Math.random() * charSet.length);
- randomString += charSet.substring(randomPoz,randomPoz+1);
- }
- return randomString;
- }
-
- $scope.generateTotp = function() {
- $scope.totp = randomString(5) + '-' + randomString(5) + '-' + randomString(5);
- }
+ );
$scope.changePassword = function() {
- if ($scope.password != $scope.confirmPassword) {
- Notifications.error("Password and confirmation does not match.");
- $scope.password = "";
- $scope.confirmPassword = "";
- return;
- }
- var creds = [
- {
- type : "password",
- value : $scope.password
- }
- ];
-
- OAuthClientCredentials.update({ realm : realm.realm, oauth : oauth.id }, creds,
+ var secret = OAuthClientCredentials.update({ realm : realm.realm, oauth : oauth.id },
function() {
- Notifications.success('The password has been changed.');
- $scope.password = null;
- $scope.confirmPassword = null;
+ Notifications.success('The secret has been changed.');
+ $scope.secret = secret.value;
},
function() {
- Notifications.error("The password was not changed due to a problem.");
- $scope.password = null;
- $scope.confirmPassword = null;
+ Notifications.error("The secret was not changed due to a problem.");
+ $scope.secret = "error";
}
);
};
- $scope.changeTotp = function() {
- var creds = [
- {
- type : "totp",
- value : $scope.totp
- }
- ];
-
- OAuthClientCredentials.update({ realm : realm.realm, oauth : oauth.id }, creds,
- function() {
- Notifications.success('The totp was changed.');
- $scope.totp = null;
- },
- function() {
- Notifications.error("The totp was not changed due to a problem.");
- $scope.totp = null;
- }
- );
- };
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
+
});
module.controller('OAuthClientListCtrl', function($scope, realm, oauthClients, OAuthClient, $location) {
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
index 4eef684..cd0376f 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/services.js
@@ -464,29 +464,31 @@ module.factory('Application', function($resource) {
});
module.factory('ApplicationInstallation', function($resource) {
- var url = '/auth/rest/admin/realms/:realm/applications/:application/installation';
- var resource = $resource('/auth/rest/admin/realms/:realm/applications/:application/installation', {
- realm : '@realm',
- application : '@application'
- }, {
- update : {
- method : 'PUT'
+ var url = '/auth/rest/admin/realms/:realm/applications/:application/installation/json';
+ return {
+ url : function(parameters)
+ {
+ return url.replace(':realm', parameters.realm).replace(':application', parameters.application);
}
- });
- resource.url = function(parameters) {
+ }
+});
+module.factory('ApplicationInstallationJBoss', function($resource) {
+ var url = '/auth/rest/admin/realms/:realm/applications/:application/installation/jboss';
+ return {
+ url : function(parameters)
+ {
return url.replace(':realm', parameters.realm).replace(':application', parameters.application);
}
- return resource;
+ }
});
module.factory('ApplicationCredentials', function($resource) {
- return $resource('/auth/rest/admin/realms/:realm/applications/:application/credentials', {
+ return $resource('/auth/rest/admin/realms/:realm/applications/:application/client-secret', {
realm : '@realm',
application : '@application'
}, {
update : {
- method : 'PUT',
- isArray : true
+ method : 'POST'
}
});
});
@@ -515,15 +517,15 @@ module.factory('OAuthClient', function($resource) {
});
module.factory('OAuthClientCredentials', function($resource) {
- return $resource('/auth/rest/admin/realms/:realm/oauth-clients/:oauth/credentials', {
+ return $resource('/auth/rest/admin/realms/:realm/oauth-clients/:oauth/client-secret', {
realm : '@realm',
oauth : '@oauth'
}, {
update : {
- method : 'PUT',
- isArray : true
+ method : 'POST'
}
});
+
});
module.factory('OAuthClientRealmScopeMapping', function($resource) {
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html
index 6655b8a..8716490 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-credentials.html
@@ -17,42 +17,20 @@
</ol>
<h2 data-ng-hide="create"><span>{{application.name}}</span> Credentials</h2>
<form class="form-horizontal" name="credentialForm" novalidate>
- <fieldset data-ng-show="passwordRequired">
- <legend><span class="text">Change Password</span></legend>
+ <fieldset >
+ <legend><span class="text">Client Secret</span></legend>
<div class="form-group">
- <label class="col-sm-2 control-label" for="password">New Password</label>
+ <label class="col-sm-2 control-label" for="secret">Secret</label>
<div class="col-sm-4">
- <input class="form-control" type="password" id="password" name="password" data-ng-model="password" autofocus
- required>
- </div>
- </div>
- <div class="form-group">
- <label class="col-sm-2 control-label" for="password">New Password Confirmation</label>
- <div class="col-sm-4">
- <input class="form-control" type="password" id="confirmPassword" name="confirmPassword" data-ng-model="confirmPassword"
+ <input ng-disabled="true" class="form-control" type="text" id="secret" name="secret" data-ng-model="secret" autofocus
required>
</div>
</div>
</fieldset>
- <div class="pull-right form-actions" ng-show="password != null">
- <button type="submit" data-ng-click="changePassword()" class="btn btn-primary btn-lg">Change Password
+ <div class="pull-right form-actions">
+ <button type="submit" data-ng-click="changePassword()" class="btn btn-primary btn-lg">Regenerate Secret
</button>
</div>
- <fieldset data-ng-show="totpRequired">
- <legend uncollapsed><span class="text">Change TOTP Key</span></legend>
- <div class="form-group">
- <label class="col-sm-2 control-label" for="totp">New Key</label>
- <div class="col-sm-4">
- <input class="form-control" type="text" id="totp" name="totp" data-ng-model="totp" autofocus
- required>
- <button class="btn btn-primary" type="submit" data-ng-click="generateTotp()">Generate
- </button>
- </div>
- </div>
- </fieldset>
- <div class="pull-right form-actions" ng-show="totp != null">
- <button type="submit" data-ng-click="changeTotp()" class="btn btn-primary btn-lg">Save</button>
- </div>
</form>
</div>
</div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-installation.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-installation.html
index 60863b2..eeaa134 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-installation.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-installation.html
@@ -19,15 +19,27 @@
<h2>Application Installation</h2>
<form class="form-horizontal" name="realmForm" novalidate>
<fieldset>
- <div class="form-group">
+ <div class="form-group input-select">
+ <label class="col-sm-2 control-label" for="configFormats">Format Option</label>
+ <div class="col-sm-4">
+ <div class="input-group">
+ <div class="select-kc">
+ <select id="configFormats" name="configFormats" ng-change="changeFormat()" ng-model="configFormat" ng-options="a for a in configFormats">
+ <option value="" selected> Select a Format </option>
+ </select>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="form-group" ng-show="installation">
<div class="col-sm-12">
- <textarea class="form-control" rows="20" kc-select-action="click">{{installation | json}}</textarea>
+ <textarea class="form-control" rows="20" kc-select-action="click">{{installation}}</textarea>
</div>
</div>
</fieldset>
</form>
- <div class="pull-right form-actions">
+ <div class="pull-right form-actions" ng-show="installation">
<a class="btn btn-primary btn-lg" href="{{download}}" download="keycloak.json" type="submit">Download</a>
</div>
</div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-credentials.html
index 166eaa1..03ad7f7 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-credentials.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-credentials.html
@@ -16,43 +16,19 @@
</ol>
<h2 data-ng-hide="create"><span>{{oauth.name}}</span> Credentials</h2>
<form class="form-horizontal" name="credentialForm" novalidate>
- <fieldset data-ng-show="passwordRequired">
- <legend><span class="text">Change Password</span></legend>
+ <fieldset >
+ <legend><span class="text">Client Secret</span></legend>
<div class="form-group">
- <label class="col-sm-2 control-label" for="password">New Password</label>
+ <label class="col-sm-2 control-label" for="secret">Secret</label>
<div class="col-sm-4">
- <input class="form-control" type="password" id="password" name="password" data-ng-model="password" autofocus
- required>
- </div>
- </div>
- <div class="form-group">
- <label class="col-sm-2 control-label two-lines" for="password">New Password Confirmation</label>
- <div class="col-sm-4">
- <input class="form-control" type="password" id="confirmPassword" name="confirmPassword" data-ng-model="confirmPassword"
+ <input ng-disabled="true" class="form-control" type="text" id="secret" name="secret" data-ng-model="secret" autofocus
required>
</div>
</div>
</fieldset>
-
- <div class="pull-right form-actions" ng-show="password != null">
- <button class="btn btn-primary btn-lg" type="submit" data-ng-click="changePassword()" ng-show="password != null">Change Password</button>
- </div>
-
- <fieldset data-ng-show="totpRequired">
- <legend uncollapsed><span class="text">Change TOTP Key</span></legend>
- <div class="form-group">
- <label class="col-sm-2 control-label" for="totp">New Key</label>
- <div class="col-sm-4">
- <input class="form-control" type="text" id="totp" name="totp" data-ng-model="totp" autofocus
- required>
- <button class="btn btn-primary" type="submit" data-ng-click="generateTotp()">Generate
- </button>
- </div>
- </div>
- </fieldset>
-
- <div class="pull-right form-actions" ng-show="totp != null">
- <button class="btn btn-primary btn-lg" type="submit" data-ng-click="changeTotp()" ng-show="totp != null">Save</button>
+ <div class="pull-right form-actions">
+ <button type="submit" data-ng-click="changePassword()" class="btn btn-primary btn-lg">Regenerate Secret
+ </button>
</div>
</form>
</div>
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
index da4188f..aad2f6d 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-credentials.html
@@ -19,20 +19,6 @@
<input id="user" type="text" ui-select2="userCredentialOptions" ng-model="realm.requiredCredentials" placeholder="Type a role and enter">
</div>
</div>
- <div class="form-group">
- <label class="col-sm-2 control-label" for="application" class="control-label two-lines">Required Application Credentials</label>
-
- <div class="col-sm-4">
- <input id="application" type="text" ui-select2="userCredentialOptions" ng-model="realm.requiredApplicationCredentials" placeholder="Type a role and enter">
- </div>
- </div>
- <div class="form-group">
- <label class="col-sm-2 control-label" for="oauth" class="control-label two-lines">Required OAuth Credentials</label>
-
- <div class="col-sm-4">
- <input id="oauth" type="text" ui-select2="userCredentialOptions" ng-model="realm.requiredOAuthClientCredentials" placeholder="Type a role and enter">
- </div>
- </div>
</fieldset>
<fieldset class="border-top">
<legend uncollapsed><span class="text">Realm Password Policy</span></legend>
diff --git a/core/src/main/java/org/keycloak/AbstractOAuthClient.java b/core/src/main/java/org/keycloak/AbstractOAuthClient.java
index aa65ad9..ccc5393 100755
--- a/core/src/main/java/org/keycloak/AbstractOAuthClient.java
+++ b/core/src/main/java/org/keycloak/AbstractOAuthClient.java
@@ -3,6 +3,7 @@ package org.keycloak;
import org.keycloak.util.KeycloakUriBuilder;
import java.security.KeyStore;
+import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
@@ -13,7 +14,7 @@ import java.util.concurrent.atomic.AtomicLong;
public class AbstractOAuthClient {
public static final String OAUTH_TOKEN_REQUEST_STATE = "OAuth_Token_Request_State";
protected String clientId;
- protected String password;
+ protected Map<String, String> credentials;
protected KeyStore truststore;
protected String authUrl;
protected String codeUrl;
@@ -35,12 +36,12 @@ public class AbstractOAuthClient {
this.clientId = clientId;
}
- public String getPassword() {
- return password;
+ public Map<String, String> getCredentials() {
+ return credentials;
}
- public void setPassword(String password) {
- this.password = password;
+ public void setCredentials(Map<String, String> credentials) {
+ this.credentials = credentials;
}
public KeyStore getTruststore() {
diff --git a/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
index 4e043ed..b0c37ac 100755
--- a/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/CredentialRepresentation.java
@@ -5,6 +5,7 @@ package org.keycloak.representations.idm;
* @version $Revision: 1 $
*/
public class CredentialRepresentation {
+ public static final String SECRET = "secret";
public static final String PASSWORD = "password";
public static final String TOTP = "totp";
public static final String CLIENT_CERT = "cert";
diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
index e31b41c..e11dc57 100755
--- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java
@@ -28,8 +28,6 @@ public class RealmRepresentation {
protected RolesRepresentation roles;
protected List<String> defaultRoles;
protected Set<String> requiredCredentials;
- protected Set<String> requiredApplicationCredentials;
- protected Set<String> requiredOAuthClientCredentials;
protected String passwordPolicy;
protected List<UserRepresentation> users;
protected List<UserRoleMappingRepresentation> roleMappings;
@@ -168,22 +166,6 @@ public class RealmRepresentation {
this.requiredCredentials = requiredCredentials;
}
- public Set<String> getRequiredApplicationCredentials() {
- return requiredApplicationCredentials;
- }
-
- public void setRequiredApplicationCredentials(Set<String> requiredApplicationCredentials) {
- this.requiredApplicationCredentials = requiredApplicationCredentials;
- }
-
- public Set<String> getRequiredOAuthClientCredentials() {
- return requiredOAuthClientCredentials;
- }
-
- public void setRequiredOAuthClientCredentials(Set<String> requiredOAuthClientCredentials) {
- this.requiredOAuthClientCredentials = requiredOAuthClientCredentials;
- }
-
public String getPasswordPolicy() {
return passwordPolicy;
}
diff --git a/examples/demo-template/customer-app/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/customer-app/src/main/webapp/WEB-INF/keycloak.json
index e8bf328..50ec3d3 100755
--- a/examples/demo-template/customer-app/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/demo-template/customer-app/src/main/webapp/WEB-INF/keycloak.json
@@ -6,6 +6,6 @@
"ssl-not-required": true,
"expose-token": true,
"credentials": {
- "password": "password"
+ "secret": "password"
}
}
diff --git a/examples/demo-template/product-app/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/product-app/src/main/webapp/WEB-INF/keycloak.json
index 7df8edb..ab28c0f 100755
--- a/examples/demo-template/product-app/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/demo-template/product-app/src/main/webapp/WEB-INF/keycloak.json
@@ -5,6 +5,6 @@
"auth-server-url" : "http://localhost:8080/auth",
"ssl-not-required" : true,
"credentials" : {
- "password" : "password"
+ "secret": "password"
}
}
diff --git a/examples/demo-template/subsystem-config.xml b/examples/demo-template/subsystem-config.xml
index bf569cd..977eb8b 100755
--- a/examples/demo-template/subsystem-config.xml
+++ b/examples/demo-template/subsystem-config.xml
@@ -8,12 +8,12 @@
<secure-deployment name="customer-portal.war">
<realm>demo</realm>
<resource>customer-portal</resource>
- <credential name="password">password</credential>
+ <credential name="secret">password</credential>
</secure-deployment>
<secure-deployment name="product-portal.war">
<realm>demo</realm>
<resource>product-portal</resource>
- <credential name="password">password</credential>
+ <credential name="secret">password</credential>
</secure-deployment>
<secure-deployment name="database.war">
<realm>demo</realm>
diff --git a/examples/demo-template/testrealm.json b/examples/demo-template/testrealm.json
index 86cf0f6..1183de8 100755
--- a/examples/demo-template/testrealm.json
+++ b/examples/demo-template/testrealm.json
@@ -11,8 +11,6 @@
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [ "password" ],
- "requiredApplicationCredentials": [ "password" ],
- "requiredOAuthClientCredentials": [ "password" ],
"users" : [
{
"username" : "bburke@redhat.com",
@@ -66,7 +64,7 @@
"adminUrl": "http://localhost:8080/customer-portal",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
@@ -77,7 +75,7 @@
"adminUrl": "http://localhost:8080/product-portal",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
@@ -89,7 +87,7 @@
"enabled": true,
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
diff --git a/examples/demo-template/third-party/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/third-party/src/main/webapp/WEB-INF/keycloak.json
index 80c6a3b..7e9ddc4 100755
--- a/examples/demo-template/third-party/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/demo-template/third-party/src/main/webapp/WEB-INF/keycloak.json
@@ -4,7 +4,7 @@
"auth-server-url" : "http://localhost:8080/auth",
"ssl-not-required" : true,
"credentials" : {
- "password" : "password"
+ "secret": "password"
},
"scope": {
"realm": [ "user" ]
diff --git a/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/keycloak.json b/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/keycloak.json
index 80c6a3b..7e9ddc4 100755
--- a/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/keycloak.json
+++ b/examples/demo-template/third-party-cdi/src/main/webapp/WEB-INF/keycloak.json
@@ -4,7 +4,7 @@
"auth-server-url" : "http://localhost:8080/auth",
"ssl-not-required" : true,
"credentials" : {
- "password" : "password"
+ "secret": "password"
},
"scope": {
"realm": [ "user" ]
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/config/OAuthClientConfigLoader.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/config/OAuthClientConfigLoader.java
index db9d2d5..3e53fee 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/config/OAuthClientConfigLoader.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/config/OAuthClientConfigLoader.java
@@ -28,7 +28,7 @@ public abstract class OAuthClientConfigLoader extends RealmConfigurationLoader {
public void configureOAuthClient(AbstractOAuthClient oauthClient) {
oauthClient.setClientId(adapterConfig.getResource());
- oauthClient.setPassword(adapterConfig.getCredentials().get("password"));
+ oauthClient.setCredentials(adapterConfig.getCredentials());
if (adapterConfig.getAuthServerUrl() == null) {
throw new RuntimeException("You must specify auth-url");
}
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/TokenGrantRequest.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/TokenGrantRequest.java
index 9340ce1..da49e88 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/TokenGrantRequest.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/TokenGrantRequest.java
@@ -57,11 +57,12 @@ public class TokenGrantRequest {
public static AccessTokenResponse invoke(HttpClient client, String code, String codeUrl, String redirectUri, String client_id, Map<String, String> credentials) throws IOException, HttpFailure {
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
redirectUri = stripOauthParametersFromRedirect(redirectUri);
- String password = credentials.get("password");
+ for (Map.Entry<String, String> entry : credentials.entrySet()) {
+ formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
+ }
formparams.add(new BasicNameValuePair("grant_type", "authorization_code"));
formparams.add(new BasicNameValuePair("code", code));
formparams.add(new BasicNameValuePair("client_id", client_id));
- formparams.add(new BasicNameValuePair(CredentialRepresentation.PASSWORD, password));
formparams.add(new BasicNameValuePair("redirect_uri", redirectUri));
HttpResponse response = null;
UrlEncodedFormEntity form = new UrlEncodedFormEntity(formparams, "UTF-8");
diff --git a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
index 1858caa..89ee9bc 100755
--- a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
+++ b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsOAuthClient.java
@@ -5,6 +5,7 @@ import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.util.BasicAuthHelper;
import org.keycloak.AbstractOAuthClient;
import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.representations.idm.CredentialRepresentation;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.InternalServerErrorException;
@@ -19,6 +20,7 @@ import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.net.URL;
+import java.util.Map;
/**
* Helper code to obtain oauth access tokens via browser redirects
@@ -58,14 +60,15 @@ public class JaxrsOAuthClient extends AbstractOAuthClient {
public String resolveBearerToken(String redirectUri, String code) {
redirectUri = stripOauthParametersFromRedirect(redirectUri);
- String authHeader = BasicAuthHelper.createHeader(clientId, password);
Form codeForm = new Form()
.param("grant_type", "authorization_code")
.param("code", code)
.param("client_id", clientId)
- .param("password", password)
.param("redirect_uri", redirectUri);
- Response res = client.target(codeUrl).request().header(HttpHeaders.AUTHORIZATION, authHeader).post(Entity.form(codeForm));
+ for (Map.Entry<String, String> entry : credentials.entrySet()) {
+ codeForm.param(entry.getKey(), entry.getValue());
+ }
+ Response res = client.target(codeUrl).request().post(Entity.form(codeForm));
try {
if (res.getStatus() == 400) {
throw new BadRequestException();
diff --git a/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java b/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
index c8259c4..4290651 100755
--- a/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
+++ b/integration/servlet-oauth-client/src/main/java/org/keycloak/servlet/ServletOAuthClient.java
@@ -48,8 +48,6 @@ public class ServletOAuthClient extends AbstractOAuthClient {
}
public String resolveBearerToken(String redirectUri, String code) throws IOException, TokenGrantRequest.HttpFailure {
- Map<String, String> credentials = new HashMap<String, String>();
- credentials.put("password", password);
return TokenGrantRequest.invoke(client, code, codeUrl, redirectUri, clientId, credentials).getToken();
}
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index 8ec3e0a..2e247d7 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -170,4 +170,13 @@ public interface RealmModel extends RoleContainerModel, RoleMapperModel, ScopeMa
void setAccountTheme(String name);
+ boolean validateSecret(UserModel user, String secret);
+
+ /**
+ * Secrets can be viewed. They are used by confidential Applications and OAuth clients
+ *
+ * @param user
+ * @return
+ */
+ UserCredentialModel getSecret(UserModel user);
}
diff --git a/model/api/src/main/java/org/keycloak/models/RequiredCredentialModel.java b/model/api/src/main/java/org/keycloak/models/RequiredCredentialModel.java
index 737c1b4..9d77a7a 100755
--- a/model/api/src/main/java/org/keycloak/models/RequiredCredentialModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RequiredCredentialModel.java
@@ -53,6 +53,7 @@ public class RequiredCredentialModel {
public static final RequiredCredentialModel PASSWORD;
public static final RequiredCredentialModel TOTP;
public static final RequiredCredentialModel CLIENT_CERT;
+ public static final RequiredCredentialModel SECRET;
static {
Map<String, RequiredCredentialModel> map = new HashMap<String, RequiredCredentialModel>();
@@ -62,6 +63,12 @@ public class RequiredCredentialModel {
PASSWORD.setSecret(true);
PASSWORD.setFormLabel("password");
map.put(PASSWORD.getType(), PASSWORD);
+ SECRET = new RequiredCredentialModel();
+ SECRET.setType(UserCredentialModel.SECRET);
+ SECRET.setInput(false);
+ SECRET.setSecret(true);
+ SECRET.setFormLabel("secret");
+ map.put(SECRET.getType(), SECRET);
TOTP = new RequiredCredentialModel();
TOTP.setType(UserCredentialModel.TOTP);
TOTP.setInput(true);
diff --git a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
index 410ae87..510f852 100755
--- a/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
+++ b/model/api/src/main/java/org/keycloak/models/UserCredentialModel.java
@@ -1,11 +1,16 @@
package org.keycloak.models;
+import java.util.UUID;
+
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UserCredentialModel {
public static final String PASSWORD = "password";
+
+ // Secret is same as password but it is not hashed
+ public static final String SECRET = "secret";
public static final String TOTP = "totp";
public static final String CLIENT_CERT = "cert";
@@ -23,6 +28,20 @@ public class UserCredentialModel {
return model;
}
+ public static UserCredentialModel secret(String password) {
+ UserCredentialModel model = new UserCredentialModel();
+ model.setType(SECRET);
+ model.setValue(password);
+ return model;
+ }
+
+ public static UserCredentialModel generateSecret() {
+ UserCredentialModel model = new UserCredentialModel();
+ model.setType(SECRET);
+ model.setValue(UUID.randomUUID().toString());
+ return model;
+ }
+
public String getType() {
return type;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 467953c..8b7712d 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -997,6 +997,17 @@ public class RealmAdapter implements RealmModel {
}
@Override
+ public UserCredentialModel getSecret(UserModel user) {
+ for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
+ if (cred.getType().equals(UserCredentialModel.SECRET)) {
+ return UserCredentialModel.secret(cred.getValue());
+ }
+ }
+ return null;
+
+ }
+
+ @Override
public boolean validatePassword(UserModel user, String password) {
for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
if (cred.getType().equals(UserCredentialModel.PASSWORD)) {
@@ -1007,6 +1018,18 @@ public class RealmAdapter implements RealmModel {
}
@Override
+ public boolean validateSecret(UserModel user, String secret) {
+ for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
+ if (cred.getType().equals(UserCredentialModel.SECRET)) {
+ return secret.equals(cred.getValue());
+ }
+ }
+ return false;
+ }
+
+
+
+ @Override
public boolean validateTOTP(UserModel user, String password, String token) {
if (!validatePassword(user, password)) return false;
for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 6083eeb..2d23090 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -770,6 +770,29 @@ public class RealmAdapter extends AbstractAdapter implements RealmModel {
}
@Override
+ public boolean validateSecret(UserModel user, String secret) {
+ for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
+ if (cred.getType().equals(UserCredentialModel.SECRET)) {
+ return secret.equals(cred.getValue());
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public UserCredentialModel getSecret(UserModel user) {
+ for (CredentialEntity cred : ((UserAdapter)user).getUser().getCredentials()) {
+ if (cred.getType().equals(UserCredentialModel.SECRET)) {
+ return UserCredentialModel.secret(cred.getValue());
+ }
+ }
+ return null;
+
+ }
+
+
+
+ @Override
public void updateCredential(UserModel user, UserCredentialModel cred) {
CredentialEntity credentialEntity = null;
UserEntity userEntity = ((UserAdapter) user).getUser();
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java b/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
index 6a4a908..b44b32f 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ImportTest.java
@@ -151,8 +151,8 @@ public class ImportTest extends AbstractModelTest {
Assert.assertFalse(realm.isUpdateProfileOnInitialSocialLogin());
Assert.assertEquals(600, realm.getAccessCodeLifespanUserAction());
verifyRequiredCredentials(realm.getRequiredCredentials(), "password");
- verifyRequiredCredentials(realm.getRequiredApplicationCredentials(), "totp");
- verifyRequiredCredentials(realm.getRequiredOAuthClientCredentials(), "cert");
+ verifyRequiredCredentials(realm.getRequiredApplicationCredentials(), "secret");
+ verifyRequiredCredentials(realm.getRequiredOAuthClientCredentials(), "secret");
}
private void verifyRequiredCredentials(List<RequiredCredentialModel> requiredCreds, String expectedType) {
diff --git a/model/tests/src/test/resources/testcomposites.json b/model/tests/src/test/resources/testcomposites.json
old mode 100644
new mode 100755
index 73e4300..2ac02ce
--- a/model/tests/src/test/resources/testcomposites.json
+++ b/model/tests/src/test/resources/testcomposites.json
@@ -9,8 +9,6 @@
"registrationAllowed": true,
"resetPasswordAllowed": true,
"requiredCredentials": [ "password" ],
- "requiredApplicationCredentials": [ "password" ],
- "requiredOAuthClientCredentials": [ "password" ],
"smtpServer": {
"from": "auto@keycloak.org",
"host": "localhost",
@@ -68,7 +66,7 @@
"name" : "third-party",
"enabled": true,
"credentials" : [
- { "type" : "password",
+ { "type" : "secret",
"value" : "password" }
]
}
@@ -109,7 +107,7 @@
"adminUrl": "http://localhost:8081/app/logout",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
@@ -121,7 +119,7 @@
"adminUrl": "http://localhost:8081/app/logout",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
@@ -133,7 +131,7 @@
"adminUrl": "http://localhost:8081/app/logout",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
@@ -145,7 +143,7 @@
"adminUrl": "http://localhost:8081/app/logout",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
diff --git a/model/tests/src/test/resources/testrealm.json b/model/tests/src/test/resources/testrealm.json
index 16ccf46..a78c234 100755
--- a/model/tests/src/test/resources/testrealm.json
+++ b/model/tests/src/test/resources/testrealm.json
@@ -5,8 +5,6 @@
"accessCodeLifespan": 30,
"accessCodeLifespanUserAction": 600,
"requiredCredentials": [ "password" ],
- "requiredApplicationCredentials": [ "password" ],
- "requiredOAuthClientCredentials": [ "password" ],
"defaultRoles": [ "foo", "bar" ],
"verifyEmail" : "true",
"users": [
@@ -83,7 +81,7 @@
"name" : "oauthclient",
"enabled": true,
"credentials" : [
- { "type" : "password",
+ { "type" : "secret",
"value" : "clientpassword" }
]
}
diff --git a/model/tests/src/test/resources/testrealm-demo.json b/model/tests/src/test/resources/testrealm-demo.json
index be00dce..7cf1072 100755
--- a/model/tests/src/test/resources/testrealm-demo.json
+++ b/model/tests/src/test/resources/testrealm-demo.json
@@ -9,8 +9,6 @@
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [ "password" ],
- "requiredApplicationCredentials": [ "totp" ],
- "requiredOAuthClientCredentials": [ "cert" ],
"users" : [
{
"username" : "bburke@redhat.com",
@@ -29,7 +27,7 @@
"name" : "third-party",
"enabled": true,
"credentials" : [
- { "type" : "Password",
+ { "type" : "secret",
"value" : "password" }
]
}
@@ -66,9 +64,8 @@
"adminUrl": "http://localhost:8080/customer-portal/j_admin_request",
"credentials": [
{
- "type": "totp",
- "value": "12345",
- "device": "67890"
+ "type": "secret",
+ "value": "12345"
}
]
},
@@ -78,9 +75,8 @@
"adminUrl": "http://localhost:8080/product-portal/j_admin_request",
"credentials": [
{
- "type": "totp",
- "value": "12345",
- "device": "67890"
+ "type": "secret",
+ "value": "12345"
}
]
}
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
index c4260a4..f4ea7df 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java
@@ -58,16 +58,10 @@ public class ApplianceBootstrap {
realm.setLoginTheme("keycloak");
realm.setAccountTheme("keycloak");
- ApplicationModel adminConsole = realm.addApplication(Constants.ADMIN_CONSOLE_APPLICATION);
+ ApplicationModel adminConsole = new ApplicationManager(manager).createApplication(realm, Constants.ADMIN_CONSOLE_APPLICATION);
adminConsole.setBaseUrl("/auth/admin/index.html");
adminConsole.setEnabled(true);
- UserCredentialModel adminConsolePassword = new UserCredentialModel();
- adminConsolePassword.setType(UserCredentialModel.PASSWORD);
- adminConsolePassword.setValue(UUID.randomUUID().toString()); // just a random password as we'll never access it
- realm.updateCredential(adminConsole.getApplicationUser(), adminConsolePassword);
- RoleModel applicationRole = realm.getRole(Constants.APPLICATION_ROLE);
- realm.grantRole(adminConsole.getApplicationUser(), applicationRole);
RoleModel adminRole = adminConsole.addRole(Constants.ADMIN_CONSOLE_ADMIN_ROLE);
UserModel adminUser = realm.addUser("admin");
diff --git a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
index 9ca5193..bfa7ebf 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
@@ -1,5 +1,7 @@
package org.keycloak.services.managers;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.annotate.JsonPropertyOrder;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
@@ -7,7 +9,9 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
+import org.keycloak.representations.SkeletonKeyScope;
import org.keycloak.representations.adapters.config.BaseAdapterConfig;
+import org.keycloak.representations.adapters.config.BaseRealmConfig;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
@@ -22,6 +26,7 @@ import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
+import java.util.UUID;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -36,6 +41,10 @@ public class ApplicationManager {
this.realmManager = realmManager;
}
+ public ApplicationManager() {
+ }
+
+
/**
* Does not create scope or role mappings!
*
@@ -54,14 +63,18 @@ public class ApplicationManager {
applicationModel.updateApplication();
UserModel resourceUser = applicationModel.getApplicationUser();
- if (resourceRep.getCredentials() != null) {
+ if (resourceRep.getCredentials() != null && resourceRep.getCredentials().size() > 0) {
for (CredentialRepresentation cred : resourceRep.getCredentials()) {
UserCredentialModel credential = new UserCredentialModel();
credential.setType(cred.getType());
credential.setValue(cred.getValue());
realm.updateCredential(resourceUser, credential);
}
+ } else {
+ generateSecret(realm, applicationModel);
}
+
+
if (resourceRep.getRedirectUris() != null) {
for (String redirectUri : resourceRep.getRedirectUris()) {
resourceUser.addRedirectUri(redirectUri);
@@ -122,9 +135,17 @@ public class ApplicationManager {
RoleModel loginRole = realm.getRole(Constants.APPLICATION_ROLE);
ApplicationModel app = realm.addApplication(name);
realm.grantRole(app.getApplicationUser(), loginRole);
+ generateSecret(realm, app);
+
return app;
}
+ public UserCredentialModel generateSecret(RealmModel realm, ApplicationModel app) {
+ UserCredentialModel secret = UserCredentialModel.generateSecret();
+ realm.updateCredential(app.getApplicationUser(), secret);
+ return secret;
+ }
+
public void updateApplication(ApplicationRepresentation rep, ApplicationModel resource) {
resource.setName(rep.getName());
resource.setEnabled(rep.isEnabled());
@@ -175,8 +196,45 @@ public class ApplicationManager {
}
- public BaseAdapterConfig toInstallationRepresentation(RealmModel realmModel, ApplicationModel applicationModel, URI baseUri) {
- BaseAdapterConfig rep = new BaseAdapterConfig();
+ @JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-not-required",
+ "resource", "credentials",
+ "use-resource-role-mappings"})
+ public static class InstallationAdapterConfig extends BaseRealmConfig {
+ @JsonProperty("resource")
+ protected String resource;
+ @JsonProperty("use-resource-role-mappings")
+ protected boolean useResourceRoleMappings;
+ @JsonProperty("credentials")
+ protected Map<String, String> credentials = new HashMap<String, String>();
+
+ public boolean isUseResourceRoleMappings() {
+ return useResourceRoleMappings;
+ }
+
+ public void setUseResourceRoleMappings(boolean useResourceRoleMappings) {
+ this.useResourceRoleMappings = useResourceRoleMappings;
+ }
+
+ public String getResource() {
+ return resource;
+ }
+
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+ public Map<String, String> getCredentials() {
+ return credentials;
+ }
+
+ public void setCredentials(Map<String, String> credentials) {
+ this.credentials = credentials;
+ }
+
+ }
+
+
+ public InstallationAdapterConfig toInstallationRepresentation(RealmModel realmModel, ApplicationModel applicationModel, URI baseUri) {
+ InstallationAdapterConfig rep = new InstallationAdapterConfig();
rep.setRealm(realmModel.getName());
rep.setRealmKey(realmModel.getPublicKeyPem());
rep.setSslNotRequired(realmModel.isSslNotRequired());
@@ -187,12 +245,25 @@ public class ApplicationManager {
rep.setResource(applicationModel.getName());
Map<String, String> creds = new HashMap<String, String>();
- creds.put(CredentialRepresentation.PASSWORD, "INSERT APPLICATION PASSWORD");
- if (applicationModel.getApplicationUser().isTotp()) {
- creds.put(CredentialRepresentation.TOTP, "INSERT APPLICATION TOTP");
- }
+ String cred = realmModel.getSecret(applicationModel.getApplicationUser()).getValue();
+ creds.put(CredentialRepresentation.SECRET, cred);
rep.setCredentials(creds);
return rep;
}
+
+ public String toJBossSubsystemConfig(RealmModel realmModel, ApplicationModel applicationModel, URI baseUri) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("<secure-deployment name=\"WAR MODULE NAME.war\">\n");
+ buffer.append(" <realm>").append(realmModel.getName()).append("</realm>\n");
+ buffer.append(" <realm-public-key>").append(realmModel.getPublicKeyPem()).append("</realm-public-key>\n");
+ buffer.append(" <auth-server-url>").append(baseUri.toString()).append("</auth-server-url>\n");
+ buffer.append(" <ssl-not-required>").append(realmModel.isSslNotRequired()).append("</ssl-not-required>\n");
+ buffer.append(" <resource>").append(applicationModel.getName()).append("</resource>\n");
+ String cred = realmModel.getSecret(applicationModel.getApplicationUser()).getValue();
+ buffer.append(" <credential name=\"secret\">").append(cred).append("</credential>\n");
+ buffer.append("</secure-deployment>\n");
+ return buffer.toString();
+ }
+
}
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index bc937d7..0a02633 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -303,6 +303,21 @@ public class AuthenticationManager {
} else {
return AuthenticationStatus.SUCCESS;
}
+ } else if (types.contains(CredentialRepresentation.SECRET)) {
+ String secret = formData.getFirst(CredentialRepresentation.SECRET);
+ if (secret == null) {
+ logger.warn("Secret not provided");
+ return AuthenticationStatus.MISSING_PASSWORD;
+ }
+ if (!realm.validateSecret(user, secret)) {
+ logger.debug("invalid secret for user: " + user.getLoginName());
+ return AuthenticationStatus.INVALID_CREDENTIALS;
+ }
+ if (!user.getRequiredActions().isEmpty()) {
+ return AuthenticationStatus.ACTIONS_REQUIRED;
+ } else {
+ return AuthenticationStatus.SUCCESS;
+ }
} else {
logger.warn("Do not know how to authenticate user");
return AuthenticationStatus.FAILED;
diff --git a/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java b/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
index a706360..a8e3609 100755
--- a/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
+++ b/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
@@ -5,7 +5,9 @@ import org.keycloak.models.Constants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
@@ -95,20 +97,13 @@ public class ModelToRepresentation {
rep.getRequiredCredentials().add(cred.getType());
}
}
- List<RequiredCredentialModel> requiredResourceCredentialModels = realm.getRequiredApplicationCredentials();
- if (requiredResourceCredentialModels.size() > 0) {
- rep.setRequiredApplicationCredentials(new HashSet<String>());
- for (RequiredCredentialModel cred : requiredResourceCredentialModels) {
- rep.getRequiredApplicationCredentials().add(cred.getType());
- }
- }
- List<RequiredCredentialModel> requiredOAuthCredentialModels = realm.getRequiredOAuthClientCredentials();
- if (requiredOAuthCredentialModels.size() > 0) {
- rep.setRequiredOAuthClientCredentials(new HashSet<String>());
- for (RequiredCredentialModel cred : requiredOAuthCredentialModels) {
- rep.getRequiredOAuthClientCredentials().add(cred.getType());
- }
- }
+ return rep;
+ }
+
+ public static CredentialRepresentation toRepresentation(UserCredentialModel cred) {
+ CredentialRepresentation rep = new CredentialRepresentation();
+ rep.setType(CredentialRepresentation.SECRET);
+ rep.setValue(cred.getValue());
return rep;
}
}
diff --git a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
index c02a74c..00ca44c 100755
--- a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
@@ -1,5 +1,7 @@
package org.keycloak.services.managers;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.annotate.JsonPropertyOrder;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
import org.keycloak.models.OAuthClientModel;
@@ -8,6 +10,7 @@ import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.adapters.config.BaseAdapterConfig;
+import org.keycloak.representations.adapters.config.BaseRealmConfig;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.services.resources.flows.Urls;
@@ -83,21 +86,43 @@ public class OAuthClientManager {
return rep;
}
- public BaseAdapterConfig toInstallationRepresentation(RealmModel realmModel, OAuthClientModel model, URI baseUri) {
- BaseAdapterConfig rep = new BaseAdapterConfig();
+ @JsonPropertyOrder({"realm", "realm-public-key", "auth-server-url", "ssl-not-required",
+ "resource", "credentials"})
+ public static class InstallationAdapterConfig extends BaseRealmConfig {
+ @JsonProperty("resource")
+ protected String resource;
+ @JsonProperty("credentials")
+ protected Map<String, String> credentials = new HashMap<String, String>();
+
+ public String getResource() {
+ return resource;
+ }
+
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+ public Map<String, String> getCredentials() {
+ return credentials;
+ }
+
+ public void setCredentials(Map<String, String> credentials) {
+ this.credentials = credentials;
+ }
+
+ }
+
+
+ public InstallationAdapterConfig toInstallationRepresentation(RealmModel realmModel, OAuthClientModel model, URI baseUri) {
+ InstallationAdapterConfig rep = new InstallationAdapterConfig();
rep.setRealm(realmModel.getName());
rep.setRealmKey(realmModel.getPublicKeyPem());
rep.setSslNotRequired(realmModel.isSslNotRequired());
rep.setAuthServerUrl(baseUri.toString());
- rep.setUseResourceRoleMappings(false);
rep.setResource(model.getOAuthAgent().getLoginName());
Map<String, String> creds = new HashMap<String, String>();
- creds.put(CredentialRepresentation.PASSWORD, "INSERT CLIENT PASSWORD");
- if (model.getOAuthAgent().isTotp()) {
- creds.put(CredentialRepresentation.TOTP, "INSERT CLIENT TOTP");
- }
+ creds.put(CredentialRepresentation.SECRET, realmModel.getSecret(model.getOAuthAgent()).getValue());
rep.setCredentials(creds);
return rep;
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index b9c0e64..5cc26ce 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -64,6 +64,7 @@ public class RealmManager {
return identitySession.getRealmByName(name);
}
+
public RealmModel createRealm(String name) {
return createRealm(name, name);
}
@@ -76,6 +77,8 @@ public class RealmManager {
realm.addRole(Constants.IDENTITY_REQUESTER_ROLE);
setupAccountManagement(realm);
+ realm.addRequiredOAuthClientCredential(UserCredentialModel.SECRET);
+ realm.addRequiredResourceCredential(UserCredentialModel.SECRET);
return realm;
}
@@ -108,15 +111,9 @@ public class RealmManager {
if (rep.getAccessCodeLifespanUserAction() != null)
realm.setAccessCodeLifespanUserAction(rep.getAccessCodeLifespanUserAction());
if (rep.getTokenLifespan() != null) realm.setTokenLifespan(rep.getTokenLifespan());
- if (rep.getRequiredOAuthClientCredentials() != null) {
- realm.updateRequiredOAuthClientCredentials(rep.getRequiredOAuthClientCredentials());
- }
if (rep.getRequiredCredentials() != null) {
realm.updateRequiredCredentials(rep.getRequiredCredentials());
}
- if (rep.getRequiredApplicationCredentials() != null) {
- realm.updateRequiredApplicationCredentials(rep.getRequiredApplicationCredentials());
- }
realm.setLoginTheme(rep.getLoginTheme());
realm.setAccountTheme(rep.getAccountTheme());
@@ -142,20 +139,12 @@ public class RealmManager {
private void setupAccountManagement(RealmModel realm) {
ApplicationModel application = realm.getApplicationNameMap().get(Constants.ACCOUNT_APPLICATION);
if (application == null) {
- application = realm.addApplication(Constants.ACCOUNT_APPLICATION);
+ application = new ApplicationManager(this).createApplication(realm, Constants.ACCOUNT_APPLICATION);
application.setEnabled(true);
application.addDefaultRole(Constants.ACCOUNT_PROFILE_ROLE);
application.addDefaultRole(Constants.ACCOUNT_MANAGE_ROLE);
- UserCredentialModel password = new UserCredentialModel();
- password.setType(UserCredentialModel.PASSWORD);
- password.setValue(UUID.randomUUID().toString()); // just a random password as we'll never access it
-
- realm.updateCredential(application.getApplicationUser(), password);
-
- RoleModel applicationRole = realm.getRole(Constants.APPLICATION_ROLE);
- realm.grantRole(application.getApplicationUser(), applicationRole);
}
}
@@ -209,22 +198,6 @@ public class RealmManager {
addRequiredCredential(newRealm, CredentialRepresentation.PASSWORD);
}
- if (rep.getRequiredApplicationCredentials() != null) {
- for (String requiredCred : rep.getRequiredApplicationCredentials()) {
- addResourceRequiredCredential(newRealm, requiredCred);
- }
- } else {
- addResourceRequiredCredential(newRealm, CredentialRepresentation.PASSWORD);
- }
-
- if (rep.getRequiredOAuthClientCredentials() != null) {
- for (String requiredCred : rep.getRequiredOAuthClientCredentials()) {
- addOAuthClientRequiredCredential(newRealm, requiredCred);
- }
- } else {
- addOAuthClientRequiredCredential(newRealm, CredentialRepresentation.PASSWORD);
- }
-
newRealm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
if (rep.getUsers() != null) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
index cfc4c62..3fa6d1b 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
@@ -10,6 +10,7 @@ import org.keycloak.representations.adapters.config.BaseAdapterConfig;
import org.keycloak.representations.idm.ApplicationRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.ApplicationManager;
+import org.keycloak.services.managers.ModelToRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.KeycloakApplication;
import org.keycloak.util.JsonSerialization;
@@ -17,6 +18,8 @@ import org.keycloak.util.JsonSerialization;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@@ -25,7 +28,6 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
-import java.util.List;
import java.util.Set;
/**
@@ -73,35 +75,53 @@ public class ApplicationResource extends RoleContainerResource {
@GET
@NoCache
- @Path("installation")
+ @Path("installation/json")
@Produces(MediaType.APPLICATION_JSON)
public String getInstallation() throws IOException {
ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
- BaseAdapterConfig rep = applicationManager.toInstallationRepresentation(realm, application, getKeycloakApplication().getBaseUri(uriInfo));
+ Object rep = applicationManager.toInstallationRepresentation(realm, application, getKeycloakApplication().getBaseUri(uriInfo));
// TODO Temporary solution to pretty-print
return JsonSerialization.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rep);
}
+ @GET
+ @NoCache
+ @Path("installation/jboss")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String getJBossInstallation() throws IOException {
+ ApplicationManager applicationManager = new ApplicationManager(new RealmManager(session));
+ return applicationManager.toJBossSubsystemConfig(realm, application, getKeycloakApplication().getBaseUri(uriInfo));
+ }
+
@DELETE
@NoCache
public void deleteApplication() {
realm.removeApplication(application.getId());
}
- @Path("credentials")
- @PUT
+ @Path("client-secret")
+ @POST
+ @Produces("application/json")
@Consumes("application/json")
- public void updateCredentials(List<CredentialRepresentation> credentials) {
- logger.debug("updateCredentials");
- if (credentials == null) return;
+ public CredentialRepresentation regenerateSecret() {
+ logger.debug("regenerateSecret");
+ UserCredentialModel cred = new ApplicationManager().generateSecret(realm, application);
+ CredentialRepresentation rep = ModelToRepresentation.toRepresentation(cred);
+ return rep;
+ }
- for (CredentialRepresentation rep : credentials) {
- UserCredentialModel cred = RealmManager.fromRepresentation(rep);
- realm.updateCredential(application.getApplicationUser(), cred);
- }
+ @Path("client-secret")
+ @GET
+ @Produces("application/json")
+ public CredentialRepresentation getClientSecret() {
+ logger.debug("getClientSecret");
+ UserCredentialModel model = realm.getSecret(application.getApplicationUser());
+ if (model == null) throw new NotFoundException("Application does not have a secret");
+ return ModelToRepresentation.toRepresentation(model);
}
+
@Path("scope-mappings")
public ScopeMappedResource getScopeMappedResource() {
return new ScopeMappedResource(realm, application.getApplicationUser(), session);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
index 46cce26..9bdc837 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
@@ -10,6 +10,7 @@ import org.keycloak.representations.adapters.config.BaseAdapterConfig;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.OAuthClientRepresentation;
import org.keycloak.services.managers.ApplicationManager;
+import org.keycloak.services.managers.ModelToRepresentation;
import org.keycloak.services.managers.OAuthClientManager;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.KeycloakApplication;
@@ -18,6 +19,8 @@ import org.keycloak.util.JsonSerialization;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@@ -74,7 +77,7 @@ public class OAuthClientResource {
@Produces(MediaType.APPLICATION_JSON)
public String getInstallation() throws IOException {
OAuthClientManager manager = new OAuthClientManager(realm);
- BaseAdapterConfig rep = manager.toInstallationRepresentation(realm, oauthClient, getApplication().getBaseUri(uriInfo));
+ Object rep = manager.toInstallationRepresentation(realm, oauthClient, getApplication().getBaseUri(uriInfo));
// TODO Temporary solution to pretty-print
return JsonSerialization.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rep);
@@ -86,17 +89,26 @@ public class OAuthClientResource {
realm.removeOAuthClient(oauthClient.getId());
}
- @Path("credentials")
- @PUT
+ @Path("client-secret")
+ @POST
+ @Produces("application/json")
@Consumes("application/json")
- public void updateCredentials(List<CredentialRepresentation> credentials) {
- logger.debug("updateCredentials");
- if (credentials == null) return;
-
- for (CredentialRepresentation rep : credentials) {
- UserCredentialModel cred = RealmManager.fromRepresentation(rep);
- realm.updateCredential(oauthClient.getOAuthAgent(), cred);
- }
+ public CredentialRepresentation regenerateSecret() {
+ logger.debug("regenerateSecret");
+ UserCredentialModel cred = UserCredentialModel.generateSecret();
+ realm.updateCredential(oauthClient.getOAuthAgent(), cred);
+ CredentialRepresentation rep = ModelToRepresentation.toRepresentation(cred);
+ return rep;
+ }
+
+ @Path("client-secret")
+ @GET
+ @Produces("application/json")
+ public CredentialRepresentation getClientSecret() {
+ logger.debug("getClientSecret");
+ UserCredentialModel model = realm.getSecret(oauthClient.getOAuthAgent());
+ if (model == null) throw new NotFoundException("Application does not have a secret");
+ return ModelToRepresentation.toRepresentation(model);
}
@Path("scope-mappings")
diff --git a/services/src/test/java/org/keycloak/services/email/EmailSenderTest.java b/services/src/test/java/org/keycloak/services/email/EmailSenderTest.java
index fa76623..d08b5cf 100755
--- a/services/src/test/java/org/keycloak/services/email/EmailSenderTest.java
+++ b/services/src/test/java/org/keycloak/services/email/EmailSenderTest.java
@@ -6,6 +6,7 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.keycloak.util.JsonSerialization;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
@@ -14,12 +15,27 @@ import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.SocketException;
import java.util.HashMap;
+import java.util.UUID;
public class EmailSenderTest {
private GreenMail greenMail;
private EmailSender emailSender;
+ @Test
+ public void testUUID() throws Exception{
+ System.out.println(UUID.randomUUID());
+
+ HashMap<String,String> config = new HashMap<String, String>();
+ config.put("from", "auto@keycloak.org");
+ config.put("host", "localhost");
+ config.put("port", "3025");
+
+ System.out.println(JsonSerialization.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(config));
+
+
+ }
+
@Before
public void before() {
ServerSetup setup = new ServerSetup(3025, "localhost", "smtp");
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
index 8c0d19f..852f840 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/composites/CompositeRoleTest.java
@@ -62,8 +62,6 @@ public class CompositeRoleTest {
realm.setAccessCodeLifespan(1000);
realm.setSslNotRequired(true);
realm.setEnabled(true);
- realm.addRequiredResourceCredential(UserCredentialModel.PASSWORD);
- realm.addRequiredOAuthClientCredential(UserCredentialModel.PASSWORD);
realm.addRequiredCredential(UserCredentialModel.PASSWORD);
final RoleModel realmRole1 = realm.addRole("REALM_ROLE_1");
final RoleModel realmRole2 = realm.addRole("REALM_ROLE_2");
@@ -86,21 +84,21 @@ public class CompositeRoleTest {
realmComposite1Application.addScope(realmComposite1);
realmComposite1Application.setBaseUrl("http://localhost:8081/app");
realmComposite1Application.setManagementUrl("http://localhost:8081/app/logout");
- realm.updateCredential(realmComposite1Application.getApplicationUser(), UserCredentialModel.password("password"));
+ realm.updateCredential(realmComposite1Application.getApplicationUser(), UserCredentialModel.secret("password"));
final ApplicationModel realmRole1Application = new ApplicationManager(manager).createApplication(realm, "REALM_ROLE_1_APPLICATION");
realmRole1Application.setEnabled(true);
realmRole1Application.addScope(realmRole1);
realmRole1Application.setBaseUrl("http://localhost:8081/app");
realmRole1Application.setManagementUrl("http://localhost:8081/app/logout");
- realm.updateCredential(realmRole1Application.getApplicationUser(), UserCredentialModel.password("password"));
+ realm.updateCredential(realmRole1Application.getApplicationUser(), UserCredentialModel.secret("password"));
final ApplicationModel appRoleApplication = new ApplicationManager(manager).createApplication(realm, "APP_ROLE_APPLICATION");
appRoleApplication.setEnabled(true);
appRoleApplication.setBaseUrl("http://localhost:8081/app");
appRoleApplication.setManagementUrl("http://localhost:8081/app/logout");
- realm.updateCredential(appRoleApplication.getApplicationUser(), UserCredentialModel.password("password"));
+ realm.updateCredential(appRoleApplication.getApplicationUser(), UserCredentialModel.secret("password"));
final RoleModel appRole1 = appRoleApplication.addRole("APP_ROLE_1");
final RoleModel appRole2 = appRoleApplication.addRole("APP_ROLE_2");
@@ -121,7 +119,7 @@ public class CompositeRoleTest {
appCompositeApplication.setEnabled(true);
appCompositeApplication.setBaseUrl("http://localhost:8081/app");
appCompositeApplication.setManagementUrl("http://localhost:8081/app/logout");
- realm.updateCredential(appCompositeApplication.getApplicationUser(), UserCredentialModel.password("password"));
+ realm.updateCredential(appCompositeApplication.getApplicationUser(), UserCredentialModel.secret("password"));
final RoleModel appCompositeRole = appCompositeApplication.addRole("APP_COMPOSITE_ROLE");
appCompositeApplication.addScope(appRole2);
appCompositeRole.addCompositeRole(realmRole1);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
index 7dbf997..a68ffad 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
@@ -125,7 +125,7 @@ public class OAuthClient {
parameters.add(new BasicNameValuePair("client_id", clientId));
}
if (password != null) {
- parameters.add(new BasicNameValuePair("password", password));
+ parameters.add(new BasicNameValuePair("secret", password));
}
UrlEncodedFormEntity formEntity = null;
diff --git a/testsuite/integration/src/test/resources/testcomposite.json b/testsuite/integration/src/test/resources/testcomposite.json
index 1ac78c2..19b662e 100755
--- a/testsuite/integration/src/test/resources/testcomposite.json
+++ b/testsuite/integration/src/test/resources/testcomposite.json
@@ -9,8 +9,6 @@
"registrationAllowed": true,
"resetPasswordAllowed": true,
"requiredCredentials": [ "password" ],
- "requiredApplicationCredentials": [ "password" ],
- "requiredOAuthClientCredentials": [ "password" ],
"smtpServer": {
"from": "auto@keycloak.org",
"host": "localhost",
@@ -68,7 +66,7 @@
"name" : "third-party",
"enabled": true,
"credentials" : [
- { "type" : "password",
+ { "type" : "secret",
"value" : "password" }
]
}
@@ -109,7 +107,7 @@
"adminUrl": "http://localhost:8081/app/logout",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
@@ -121,7 +119,7 @@
"adminUrl": "http://localhost:8081/app/logout",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
@@ -133,7 +131,7 @@
"adminUrl": "http://localhost:8081/app/logout",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
@@ -145,7 +143,7 @@
"adminUrl": "http://localhost:8081/app/logout",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]
diff --git a/testsuite/integration/src/test/resources/testrealm.json b/testsuite/integration/src/test/resources/testrealm.json
index 855959e..e040c2c 100755
--- a/testsuite/integration/src/test/resources/testrealm.json
+++ b/testsuite/integration/src/test/resources/testrealm.json
@@ -11,8 +11,6 @@
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [ "password" ],
- "requiredApplicationCredentials": [ "password" ],
- "requiredOAuthClientCredentials": [ "password" ],
"defaultRoles": [ "user" ],
"smtpServer": {
"from": "auto@keycloak.org",
@@ -35,7 +33,7 @@
"name" : "third-party",
"enabled": true,
"credentials" : [
- { "type" : "password",
+ { "type" : "secret",
"value" : "password" }
]
}
@@ -64,7 +62,7 @@
"adminUrl": "http://localhost:8081/app/logout",
"credentials": [
{
- "type": "password",
+ "type": "secret",
"value": "password"
}
]