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 62142edd6e..411277602a 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
@@ -276,6 +276,21 @@ module.config([ '$routeProvider', function($routeProvider) {
},
controller : 'ApplicationRoleDetailCtrl'
})
+ .when('/realms/:realm/applications/:application/claims', {
+ templateUrl : 'partials/application-claims.html',
+ resolve : {
+ realm : function(RealmLoader) {
+ return RealmLoader();
+ },
+ application : function(ApplicationLoader) {
+ return ApplicationLoader();
+ },
+ claims : function(ApplicationClaimsLoader) {
+ return ApplicationClaimsLoader();
+ }
+ },
+ controller : 'ApplicationClaimsCtrl'
+ })
.when('/realms/:realm/applications/:application/credentials', {
templateUrl : 'partials/application-credentials.html',
resolve : {
@@ -390,6 +405,21 @@ module.config([ '$routeProvider', function($routeProvider) {
// OAUTH Client
+ .when('/realms/:realm/oauth-clients/:oauth/claims', {
+ templateUrl : 'partials/oauth-client-claims.html',
+ resolve : {
+ realm : function(RealmLoader) {
+ return RealmLoader();
+ },
+ oauth : function(OAuthClientLoader) {
+ return OAuthClientLoader();
+ },
+ claims : function(OAuthClientClaimsLoader) {
+ return OAuthClientClaimsLoader();
+ }
+ },
+ controller : 'OAuthClientClaimsCtrl'
+ })
.when('/realms/:realm/oauth-clients/:oauth/credentials', {
templateUrl : 'partials/oauth-client-credentials.html',
resolve : {
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 b6be8d0f4f..8bcacd1f62 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
@@ -44,6 +44,41 @@ module.controller('ApplicationSessionsCtrl', function($scope, $location, realm,
$scope.application = application;
});
+module.controller('ApplicationClaimsCtrl', function($scope, realm, application, claims,
+ ApplicationClaims,
+ $http, $location, Dialog, Notifications) {
+ $scope.realm = realm;
+ $scope.application = application;
+ $scope.claims = angular.copy(claims);
+
+ $scope.changed = false;
+
+ $scope.$watch('claims', function () {
+ if (!angular.equals($scope.claims, claims)) {
+ $scope.changed = true;
+ }
+ }, true);
+
+
+ $scope.save = function () {
+ ApplicationClaims.update({
+ realm: realm.realm,
+ application: application.name
+ }, $scope.claims, function () {
+ $scope.changed = false;
+ claims = angular.copy($scope.claims);
+
+ Notifications.success("Your claim changes have been saved.");
+ });
+ };
+
+ $scope.reset = function () {
+ $location.url("/realms/" + realm.realm + "/applications/" + application.name + "/claims");
+ };
+
+});
+
+
module.controller('ApplicationRoleDetailCtrl', function($scope, realm, application, role, roles, applications,
Role, ApplicationRole, RoleById, RoleRealmComposites, RoleApplicationComposites,
$http, $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 4998583cae..542d5e18c2 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
@@ -1,3 +1,37 @@
+module.controller('OAuthClientClaimsCtrl', function($scope, realm, oauth, claims,
+ OAuthClientClaims,
+ $location, Dialog, Notifications) {
+ $scope.realm = realm;
+ $scope.oauth = oauth;
+ $scope.claims = angular.copy(claims);
+
+ $scope.changed = false;
+
+ $scope.$watch('claims', function () {
+ if (!angular.equals($scope.claims, claims)) {
+ $scope.changed = true;
+ }
+ }, true);
+
+
+ $scope.save = function () {
+ OAuthClientClaims.update({
+ realm: realm.realm,
+ oauth: oauth.id
+ }, $scope.claims, function () {
+ $scope.changed = false;
+ claims = angular.copy($scope.claims);
+
+ Notifications.success("Your claim changes have been saved.");
+ });
+ };
+
+ $scope.reset = function () {
+ $location.url("/realms/" + realm.realm + "/oauth-clients/" + oauth.id + "/claims");
+ };
+
+});
+
module.controller('OAuthClientCredentialsCtrl', function($scope, $location, realm, oauth, OAuthClientCredentials, Notifications) {
$scope.realm = realm;
$scope.oauth = oauth;
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/loaders.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/loaders.js
index faf05cd2b9..d5b391772d 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/js/loaders.js
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/loaders.js
@@ -91,6 +91,15 @@ module.factory('ApplicationRoleLoader', function(Loader, ApplicationRole, $route
});
});
+module.factory('ApplicationClaimsLoader', function(Loader, ApplicationClaims, $route, $q) {
+ return Loader.get(ApplicationClaims, function() {
+ return {
+ realm : $route.current.params.realm,
+ application : $route.current.params.application
+ }
+ });
+});
+
module.factory('ApplicationInstallationLoader', function(Loader, ApplicationInstallation, $route, $q) {
return Loader.get(ApplicationInstallation, function() {
return {
@@ -149,6 +158,16 @@ module.factory('OAuthClientLoader', function(Loader, OAuthClient, $route, $q) {
});
});
+module.factory('OAuthClientClaimsLoader', function(Loader, OAuthClientClaims, $route, $q) {
+ return Loader.get(OAuthClientClaims, function() {
+ return {
+ realm : $route.current.params.realm,
+ oauth : $route.current.params.oauth
+ }
+ });
+});
+
+
module.factory('OAuthClientListLoader', function(Loader, OAuthClient, $route, $q) {
return Loader.query(OAuthClient, function() {
return {
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 cd0376f89e..cff788d125 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
@@ -450,6 +450,16 @@ module.factory('ApplicationRole', function($resource) {
}
});
});
+module.factory('ApplicationClaims', function($resource) {
+ return $resource('/auth/rest/admin/realms/:realm/applications/:application/claims', {
+ realm : '@realm',
+ application : "@application"
+ }, {
+ update : {
+ method : 'PUT'
+ }
+ });
+});
module.factory('Application', function($resource) {
@@ -516,6 +526,18 @@ module.factory('OAuthClient', function($resource) {
});
});
+module.factory('OAuthClientClaims', function($resource) {
+ return $resource('/auth/rest/admin/realms/:realm/oauth-clients/:oauth/claims', {
+ realm : '@realm',
+ oauth : "@oauth"
+ }, {
+ update : {
+ method : 'PUT'
+ }
+ });
+});
+
+
module.factory('OAuthClientCredentials', function($resource) {
return $resource('/auth/rest/admin/realms/:realm/oauth-clients/:oauth/client-secret', {
realm : '@realm',
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-claims.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-claims.html
new file mode 100755
index 0000000000..d20118563f
--- /dev/null
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-claims.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+ - {{realm.realm}}
+ - Applications
+ - {{application.name}}
+ - Claims
+
+
{{application.name}} Allowed Claims
+
+
+
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 a839ccf36a..eda151816c 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
@@ -5,6 +5,7 @@
Credentials
Installation
Roles
+ Claims
Scope
Sessions
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
index f123d1c3b5..70491bb186 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-detail.html
@@ -5,6 +5,7 @@
Credentials
Installation
Roles
+ Claims
Scope
Sessions
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 eeaa134bd4..d6ffd1edae 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
@@ -6,6 +6,7 @@
Credentials
Installation
Roles
+ Claims
Scope
Sessions
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html
index e103b1296f..3a93fc66e8 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-detail.html
@@ -5,6 +5,7 @@
Credentials
Installation
Roles
+ Claims
Scope
Sessions
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html
index 087d11d925..40e8d4d859 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-role-list.html
@@ -6,6 +6,7 @@
Credentials
Installation
Roles
+ Claims
Scope
Sessions
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
index 865f9d697a..98fa8ea6cc 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-scope-mappings.html
@@ -6,6 +6,7 @@
Credentials
Installation
Roles
+ Claims
Scope
Sessions
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-sessions.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-sessions.html
index 5f110beb7f..432ae2aea1 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-sessions.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/application-sessions.html
@@ -6,6 +6,7 @@
Credentials
Installation
Roles
+ Claims
Scope
Sessions
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/claims.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/claims.html
new file mode 100755
index 0000000000..2701792167
--- /dev/null
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/claims.html
@@ -0,0 +1,62 @@
+
\ No newline at end of file
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-claims.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-claims.html
new file mode 100755
index 0000000000..05bca000dc
--- /dev/null
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-claims.html
@@ -0,0 +1,20 @@
+
+
+
+
+
{{oauth.name}} Allowed Claims
+
+
+
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 f931492e72..08ceee81ef 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
@@ -3,6 +3,7 @@
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-detail.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-detail.html
index 01e18350d5..693041ffb5 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-detail.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-detail.html
@@ -3,6 +3,7 @@
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-installation.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-installation.html
index 19afcde9da..14a4c503a2 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-installation.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-installation.html
@@ -3,6 +3,7 @@
diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-scope-mappings.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-scope-mappings.html
index 424fab27b2..72c4799b32 100755
--- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-scope-mappings.html
+++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/oauth-client-scope-mappings.html
@@ -4,6 +4,7 @@
diff --git a/core/src/main/java/org/keycloak/KeycloakAuthenticatedSession.java b/core/src/main/java/org/keycloak/KeycloakAuthenticatedSession.java
index 658e19adff..6593f2dbcf 100755
--- a/core/src/main/java/org/keycloak/KeycloakAuthenticatedSession.java
+++ b/core/src/main/java/org/keycloak/KeycloakAuthenticatedSession.java
@@ -2,6 +2,7 @@ package org.keycloak;
import org.keycloak.adapters.ResourceMetadata;
import org.keycloak.representations.AccessToken;
+import org.keycloak.representations.IDToken;
import java.io.Serializable;
@@ -12,14 +13,18 @@ import java.io.Serializable;
public class KeycloakAuthenticatedSession implements Serializable {
protected String tokenString;
protected AccessToken token;
+ protected IDToken idToken;
+ protected String idTokenString;
protected transient ResourceMetadata metadata;
public KeycloakAuthenticatedSession() {
}
- public KeycloakAuthenticatedSession(String tokenString, AccessToken token, ResourceMetadata metadata) {
+ public KeycloakAuthenticatedSession(String tokenString, AccessToken token, String idTokenString, IDToken idToken, ResourceMetadata metadata) {
this.tokenString = tokenString;
this.token = token;
+ this.idToken = idToken;
+ this.idTokenString = idTokenString;
this.metadata = metadata;
}
@@ -38,4 +43,12 @@ public class KeycloakAuthenticatedSession implements Serializable {
public void setMetadata(ResourceMetadata metadata) {
this.metadata = metadata;
}
+
+ public IDToken getIdToken() {
+ return idToken;
+ }
+
+ public String getIdTokenString() {
+ return idTokenString;
+ }
}
diff --git a/core/src/main/java/org/keycloak/representations/AccessToken.java b/core/src/main/java/org/keycloak/representations/AccessToken.java
index c99a509a3a..7f55dd9dff 100755
--- a/core/src/main/java/org/keycloak/representations/AccessToken.java
+++ b/core/src/main/java/org/keycloak/representations/AccessToken.java
@@ -12,7 +12,7 @@ import java.util.Set;
* @author Bill Burke
* @version $Revision: 1 $
*/
-public class AccessToken extends JsonWebToken {
+public class AccessToken extends IDToken {
public static class Access {
@JsonProperty("roles")
protected Set roles;
diff --git a/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java b/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java
index 985dae4aa4..2ed50812ca 100755
--- a/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java
+++ b/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java
@@ -21,6 +21,9 @@ public class AccessTokenResponse {
@JsonProperty("token_type")
protected String tokenType;
+ @JsonProperty("id_token")
+ protected String idToken;
+
public String getToken() {
return token;
}
@@ -52,4 +55,12 @@ public class AccessTokenResponse {
public void setTokenType(String tokenType) {
this.tokenType = tokenType;
}
+
+ public String getIdToken() {
+ return idToken;
+ }
+
+ public void setIdToken(String idToken) {
+ this.idToken = idToken;
+ }
}
diff --git a/core/src/main/java/org/keycloak/representations/IDToken.java b/core/src/main/java/org/keycloak/representations/IDToken.java
new file mode 100755
index 0000000000..08514a9fa3
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/IDToken.java
@@ -0,0 +1,306 @@
+package org.keycloak.representations;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class IDToken extends JsonWebToken {
+ @JsonProperty("nonce")
+ protected String nonce;
+
+ @JsonProperty("name")
+ protected String name;
+
+ @JsonProperty("given_name")
+ protected String givenName;
+
+ @JsonProperty("family_name")
+ protected String familyName;
+
+ @JsonProperty("middle_name")
+ protected String middleName;
+
+ @JsonProperty("nickname")
+ protected String nickName;
+
+ @JsonProperty("preferred_username")
+ protected String preferredUsername;
+
+ @JsonProperty("profile")
+ protected String profile;
+
+ @JsonProperty("picture")
+ protected String picture;
+
+ @JsonProperty("website")
+ protected String website;
+
+ @JsonProperty("email")
+ protected String email;
+
+ @JsonProperty("email_verified")
+ protected Boolean emailVerified;
+
+ @JsonProperty("gender")
+ protected String gender;
+
+ @JsonProperty("birthdate")
+ protected String birthdate;
+
+ @JsonProperty("zoneinfo")
+ protected String zoneinfo;
+
+ @JsonProperty("locale")
+ protected String locale;
+
+ @JsonProperty("phone_number")
+ protected String phoneNumber;
+
+ @JsonProperty("phone_number_verified")
+ protected Boolean phoneNumberVerified;
+
+ @JsonProperty("address")
+ protected String address;
+
+ @JsonProperty("updated_at")
+ protected Long updatedAt;
+
+ @JsonProperty("formatted")
+ protected String formattedAddress;
+
+ @JsonProperty("street_address")
+ protected String streetAddress;
+
+ @JsonProperty("locality")
+ protected String locality;
+
+ @JsonProperty("region")
+ protected String region;
+
+ @JsonProperty("postal_code")
+ protected String postalCode;
+
+ @JsonProperty("country")
+ protected String country;
+
+ @JsonProperty("claims_locales")
+ protected String claimsLocales;
+
+ public String getNonce() {
+ return nonce;
+ }
+
+ public void setNonce(String nonce) {
+ this.nonce = nonce;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getGivenName() {
+ return givenName;
+ }
+
+ public void setGivenName(String givenName) {
+ this.givenName = givenName;
+ }
+
+ public String getFamilyName() {
+ return familyName;
+ }
+
+ public void setFamilyName(String familyName) {
+ this.familyName = familyName;
+ }
+
+ public String getMiddleName() {
+ return middleName;
+ }
+
+ public void setMiddleName(String middleName) {
+ this.middleName = middleName;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ public String getPreferredUsername() {
+ return preferredUsername;
+ }
+
+ public void setPreferredUsername(String preferredUsername) {
+ this.preferredUsername = preferredUsername;
+ }
+
+ public String getProfile() {
+ return profile;
+ }
+
+ public void setProfile(String profile) {
+ this.profile = profile;
+ }
+
+ public String getPicture() {
+ return picture;
+ }
+
+ public void setPicture(String picture) {
+ this.picture = picture;
+ }
+
+ public String getWebsite() {
+ return website;
+ }
+
+ public void setWebsite(String website) {
+ this.website = website;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public Boolean getEmailVerified() {
+ return emailVerified;
+ }
+
+ public void setEmailVerified(Boolean emailVerified) {
+ this.emailVerified = emailVerified;
+ }
+
+ public String getGender() {
+ return gender;
+ }
+
+ public void setGender(String gender) {
+ this.gender = gender;
+ }
+
+ public String getBirthdate() {
+ return birthdate;
+ }
+
+ public void setBirthdate(String birthdate) {
+ this.birthdate = birthdate;
+ }
+
+ public String getZoneinfo() {
+ return zoneinfo;
+ }
+
+ public void setZoneinfo(String zoneinfo) {
+ this.zoneinfo = zoneinfo;
+ }
+
+ public String getLocale() {
+ return locale;
+ }
+
+ public void setLocale(String locale) {
+ this.locale = locale;
+ }
+
+ public String getPhoneNumber() {
+ return phoneNumber;
+ }
+
+ public void setPhoneNumber(String phoneNumber) {
+ this.phoneNumber = phoneNumber;
+ }
+
+ public Boolean getPhoneNumberVerified() {
+ return phoneNumberVerified;
+ }
+
+ public void setPhoneNumberVerified(Boolean phoneNumberVerified) {
+ this.phoneNumberVerified = phoneNumberVerified;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public Long getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(Long updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+
+ public String getFormattedAddress() {
+ return formattedAddress;
+ }
+
+ public void setFormattedAddress(String formattedAddress) {
+ this.formattedAddress = formattedAddress;
+ }
+
+ public String getStreetAddress() {
+ return streetAddress;
+ }
+
+ public void setStreetAddress(String streetAddress) {
+ this.streetAddress = streetAddress;
+ }
+
+ public String getLocality() {
+ return locality;
+ }
+
+ public void setLocality(String locality) {
+ this.locality = locality;
+ }
+
+ public String getRegion() {
+ return region;
+ }
+
+ public void setRegion(String region) {
+ this.region = region;
+ }
+
+ public String getPostalCode() {
+ return postalCode;
+ }
+
+ public void setPostalCode(String postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public String getClaimsLocales() {
+ return claimsLocales;
+ }
+
+ public void setClaimsLocales(String claimsLocales) {
+ this.claimsLocales = claimsLocales;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
index 5cb4a1d240..601bce52e8 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
@@ -18,6 +18,7 @@ public class ApplicationRepresentation {
protected String[] defaultRoles;
protected List redirectUris;
protected List webOrigins;
+ protected ClaimRepresentation claims;
public String getId() {
return id;
@@ -107,4 +108,12 @@ public class ApplicationRepresentation {
public void setDefaultRoles(String[] defaultRoles) {
this.defaultRoles = defaultRoles;
}
+
+ public ClaimRepresentation getClaims() {
+ return claims;
+ }
+
+ public void setClaims(ClaimRepresentation claims) {
+ this.claims = claims;
+ }
}
diff --git a/core/src/main/java/org/keycloak/representations/idm/ClaimRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ClaimRepresentation.java
new file mode 100755
index 0000000000..1783d89239
--- /dev/null
+++ b/core/src/main/java/org/keycloak/representations/idm/ClaimRepresentation.java
@@ -0,0 +1,98 @@
+package org.keycloak.representations.idm;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class ClaimRepresentation {
+ protected boolean name;
+ protected boolean username;
+ protected boolean profile;
+ protected boolean picture;
+ protected boolean website;
+ protected boolean email;
+ protected boolean gender;
+ protected boolean locale;
+ protected boolean address;
+ protected boolean phone;
+
+ public boolean getName() {
+ return name;
+ }
+
+ public void setName(boolean name) {
+ this.name = name;
+ }
+
+ public boolean getUsername() {
+ return username;
+ }
+
+ public void setUsername(boolean username) {
+ this.username = username;
+ }
+
+ public boolean getProfile() {
+ return profile;
+ }
+
+ public void setProfile(boolean profile) {
+ this.profile = profile;
+ }
+
+ public boolean getPicture() {
+ return picture;
+ }
+
+ public void setPicture(boolean picture) {
+ this.picture = picture;
+ }
+
+ public boolean getWebsite() {
+ return website;
+ }
+
+ public void setWebsite(boolean website) {
+ this.website = website;
+ }
+
+ public boolean getEmail() {
+ return email;
+ }
+
+ public void setEmail(boolean email) {
+ this.email = email;
+ }
+
+ public boolean getGender() {
+ return gender;
+ }
+
+ public void setGender(boolean gender) {
+ this.gender = gender;
+ }
+
+ public boolean getLocale() {
+ return locale;
+ }
+
+ public void setLocale(boolean locale) {
+ this.locale = locale;
+ }
+
+ public boolean getAddress() {
+ return address;
+ }
+
+ public void setAddress(boolean address) {
+ this.address = address;
+ }
+
+ public boolean getPhone() {
+ return phone;
+ }
+
+ public void setPhone(boolean phone) {
+ this.phone = phone;
+ }
+}
diff --git a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
index be44c4344a..cfd33dd9b1 100755
--- a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
@@ -14,6 +14,7 @@ public class OAuthClientRepresentation {
protected List webOrigins;
protected boolean enabled;
protected List credentials;
+ protected ClaimRepresentation claims;
public String getId() {
return id;
@@ -70,4 +71,12 @@ public class OAuthClientRepresentation {
public void setCredentials(List credentials) {
this.credentials = credentials;
}
+
+ public ClaimRepresentation getClaims() {
+ return claims;
+ }
+
+ public void setClaims(ClaimRepresentation claims) {
+ this.claims = claims;
+ }
}
diff --git a/docbook/reference/en/en-US/modules/Overview.xml b/docbook/reference/en/en-US/modules/Overview.xml
index bdd3b2b9e9..3910cea1aa 100755
--- a/docbook/reference/en/en-US/modules/Overview.xml
+++ b/docbook/reference/en/en-US/modules/Overview.xml
@@ -31,6 +31,10 @@
Password and TOTP support (via Google Authenticator). Client cert auth coming soon.
+
+ Pluggable theme and style support for user facing screens.
+
+
OAuth Bearer token auth for REST Services
@@ -60,7 +64,7 @@
Deployable as a WAR, appliance, or on Openshift.
- Supports JBoss AS7, EAP 6.x, and Wildfly applications. Plans to support Node.js, RAILS, GRAILS, and other non-Java application
+ Supports JBoss AS7, EAP 6.x, and Wildfly applications. Plans to support Node.js, RAILS, GRAILS, and other non-Java deployments
diff --git a/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java b/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java
index 196579da59..16b6a9623a 100755
--- a/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java
+++ b/examples/demo-template/customer-app/src/main/java/org/keycloak/example/CustomerDatabaseClient.java
@@ -6,6 +6,7 @@ import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.keycloak.KeycloakAuthenticatedSession;
import org.keycloak.adapters.HttpClientBuilder;
+import org.keycloak.representations.IDToken;
import org.keycloak.util.JsonSerialization;
import javax.servlet.http.HttpServletRequest;
@@ -35,6 +36,12 @@ public class CustomerDatabaseClient {
}
}
+ public static IDToken getIDToken(HttpServletRequest req) {
+ KeycloakAuthenticatedSession session = (KeycloakAuthenticatedSession) req.getAttribute(KeycloakAuthenticatedSession.class.getName());
+ return session.getIdToken();
+
+ }
+
public static List getCustomers(HttpServletRequest req) throws Failure {
KeycloakAuthenticatedSession session = (KeycloakAuthenticatedSession) req.getAttribute(KeycloakAuthenticatedSession.class.getName());
diff --git a/examples/demo-template/customer-app/src/main/webapp/customers/view.jsp b/examples/demo-template/customer-app/src/main/webapp/customers/view.jsp
index 0e9ab0ed84..f966321212 100755
--- a/examples/demo-template/customer-app/src/main/webapp/customers/view.jsp
+++ b/examples/demo-template/customer-app/src/main/webapp/customers/view.jsp
@@ -2,6 +2,7 @@
pageEncoding="ISO-8859-1" %>
<%@ page import="org.keycloak.example.CustomerDatabaseClient" %>
<%@ page import="org.keycloak.util.KeycloakUriBuilder" %>
+<%@ page import="org.keycloak.representations.IDToken" %>
Customer View Page
@@ -11,11 +12,18 @@
String logoutUri = KeycloakUriBuilder.fromUri("http://localhost:8080/auth/rest/realms/demo/tokens/logout")
.queryParam("redirect_uri", "http://localhost:8080/customer-portal").build().toString();
String acctUri = "http://localhost:8080/auth/rest/realms/demo/account";
+ IDToken idToken = CustomerDatabaseClient.getIDToken(request);
%>
Goto: products | logout | manage acct
-User <%=request.getUserPrincipal().getName()%>
+Servlet User Principal <%=request.getUserPrincipal().getName()%>
made this request.
+Caller IDToken values (You can specify what is returned in IDToken in the customer-portal claims page in the admin console:
+Username: <%=idToken.getPreferredUsername()%>
+Email: <%=idToken.getEmail()%>
+Full Name: <%=idToken.getName()%>
+First: <%=idToken.getGivenName()%>
+Last: <%=idToken.getFamilyName()%>
Customer Listing
<%
java.util.List list = null;
diff --git a/forms/login-api/src/main/java/org/keycloak/login/LoginForms.java b/forms/login-api/src/main/java/org/keycloak/login/LoginForms.java
old mode 100644
new mode 100755
index 3cce80c972..9f91751c00
--- a/forms/login-api/src/main/java/org/keycloak/login/LoginForms.java
+++ b/forms/login-api/src/main/java/org/keycloak/login/LoginForms.java
@@ -1,47 +1,47 @@
-package org.keycloak.login;
-
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import java.util.List;
-
-/**
- * @author Stian Thorgersen
- */
-public interface LoginForms {
-
- public Response createResponse(UserModel.RequiredAction action);
-
- public Response createLogin();
-
- public Response createPasswordReset();
-
- public Response createLoginTotp();
-
- public Response createRegistration();
-
- public Response createErrorPage();
-
- public Response createOAuthGrant();
-
- public LoginForms setAccessCode(String accessCodeId, String accessCode);
-
- public LoginForms setAccessRequest(List realmRolesRequested, MultivaluedMap resourceRolesRequested);
-
- public LoginForms setError(String message);
-
- public LoginForms setSuccess(String message);
-
- public LoginForms setWarning(String message);
-
- public LoginForms setUser(UserModel user);
-
- public LoginForms setClient(UserModel client);
-
- public LoginForms setFormData(MultivaluedMap formData);
-
- public LoginForms setStatus(Response.Status status);
-
-}
+package org.keycloak.login;
+
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import java.util.List;
+
+/**
+ * @author Stian Thorgersen
+ */
+public interface LoginForms {
+
+ public Response createResponse(UserModel.RequiredAction action);
+
+ public Response createLogin();
+
+ public Response createPasswordReset();
+
+ public Response createLoginTotp();
+
+ public Response createRegistration();
+
+ public Response createErrorPage();
+
+ public Response createOAuthGrant();
+
+ public LoginForms setAccessCode(String accessCodeId, String accessCode);
+
+ public LoginForms setAccessRequest(List realmRolesRequested, MultivaluedMap resourceRolesRequested);
+
+ public LoginForms setError(String message);
+
+ public LoginForms setSuccess(String message);
+
+ public LoginForms setWarning(String message);
+
+ public LoginForms setUser(UserModel user);
+
+ public LoginForms setClient(UserModel client);
+
+ public LoginForms setFormData(MultivaluedMap formData);
+
+ public LoginForms setStatus(Response.Status status);
+
+}
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginForms.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginForms.java
old mode 100644
new mode 100755
index 30b15faf2e..95f005b9f2
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginForms.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginForms.java
@@ -1,273 +1,273 @@
-package org.keycloak.login.freemarker;
-
-import org.jboss.logging.Logger;
-import org.jboss.resteasy.spi.HttpRequest;
-import org.keycloak.freemarker.FreeMarkerException;
-import org.keycloak.freemarker.FreeMarkerUtil;
-import org.keycloak.freemarker.Theme;
-import org.keycloak.freemarker.ThemeLoader;
-import org.keycloak.login.LoginForms;
-import org.keycloak.login.LoginFormsPages;
-import org.keycloak.login.freemarker.model.LoginBean;
-import org.keycloak.login.freemarker.model.MessageBean;
-import org.keycloak.login.freemarker.model.OAuthGrantBean;
-import org.keycloak.login.freemarker.model.ProfileBean;
-import org.keycloak.login.freemarker.model.RealmBean;
-import org.keycloak.login.freemarker.model.RegisterBean;
-import org.keycloak.login.freemarker.model.SocialBean;
-import org.keycloak.login.freemarker.model.TotpBean;
-import org.keycloak.login.freemarker.model.UrlBean;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.services.email.EmailException;
-import org.keycloak.services.email.EmailSender;
-import org.keycloak.services.messages.Messages;
-
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
-import java.io.IOException;
-import java.net.URI;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * @author Stian Thorgersen
- */
-public class FreeMarkerLoginForms implements LoginForms {
-
- private static final Logger logger = Logger.getLogger(FreeMarkerLoginForms.class);
-
- private String message;
- private String accessCodeId;
- private String accessCode;
- private Response.Status status = Response.Status.OK;
- private List realmRolesRequested;
- private MultivaluedMap resourceRolesRequested;
-
- public static enum MessageType {SUCCESS, WARNING, ERROR}
-
- private MessageType messageType = MessageType.ERROR;
-
- private MultivaluedMap formData;
-
- private RealmModel realm;
-
- // TODO Remove
- private HttpRequest request;
-
- private UserModel user;
-
- private UserModel client;
-
- private UriInfo uriInfo;
-
- FreeMarkerLoginForms(RealmModel realm, org.jboss.resteasy.spi.HttpRequest request, UriInfo uriInfo) {
- this.realm = realm;
- this.request = request;
- this.uriInfo = uriInfo;
- }
-
- public Response createResponse(UserModel.RequiredAction action) {
- String actionMessage;
- LoginFormsPages page;
-
- switch (action) {
- case CONFIGURE_TOTP:
- actionMessage = Messages.ACTION_WARN_TOTP;
- page = LoginFormsPages.LOGIN_CONFIG_TOTP;
- break;
- case UPDATE_PROFILE:
- actionMessage = Messages.ACTION_WARN_PROFILE;
- page = LoginFormsPages.LOGIN_UPDATE_PROFILE;
- break;
- case UPDATE_PASSWORD:
- actionMessage = Messages.ACTION_WARN_PASSWD;
- page = LoginFormsPages.LOGIN_UPDATE_PASSWORD;
- break;
- case VERIFY_EMAIL:
- try {
- new EmailSender(realm.getSmtpConfig()).sendEmailVerification(user, realm, accessCodeId, uriInfo);
- } catch (EmailException e) {
- return setError("emailSendError").createErrorPage();
- }
-
- actionMessage = Messages.ACTION_WARN_EMAIL;
- page = LoginFormsPages.LOGIN_VERIFY_EMAIL;
- break;
- default:
- return Response.serverError().build();
- }
-
- if (message == null) {
- setWarning(actionMessage);
- }
-
- return createResponse(page);
- }
-
- private Response createResponse(LoginFormsPages page) {
- MultivaluedMap queryParameterMap = uriInfo.getQueryParameters();
-
- String requestURI = uriInfo.getBaseUri().getPath();
- UriBuilder uriBuilder = UriBuilder.fromUri(requestURI);
-
- for (String k : queryParameterMap.keySet()) {
- uriBuilder.replaceQueryParam(k, queryParameterMap.get(k).toArray());
- }
-
- if (accessCode != null) {
- uriBuilder.replaceQueryParam("code", accessCode);
- }
-
- Map attributes = new HashMap();
-
- Theme theme;
- try {
- theme = ThemeLoader.createTheme(realm.getLoginTheme(), Theme.Type.LOGIN);
- } catch (FreeMarkerException e) {
- logger.error("Failed to create theme", e);
- return Response.serverError().build();
- }
-
- try {
- attributes.put("properties", theme.getProperties());
- } catch (IOException e) {
- logger.warn("Failed to load properties", e);
- }
-
- Properties messages;
- try {
- messages = theme.getMessages();
- attributes.put("rb", messages);
- } catch (IOException e) {
- logger.warn("Failed to load messages", e);
- messages = new Properties();
- }
-
- if (message != null) {
- attributes.put("message", new MessageBean(messages.containsKey(message) ? messages.getProperty(message) : message, messageType));
- }
-
- URI baseUri = uriBuilder.build();
-
- if (realm != null) {
- attributes.put("realm", new RealmBean(realm));
- attributes.put("social", new SocialBean(realm, baseUri));
- attributes.put("url", new UrlBean(realm, theme, baseUri));
- }
-
- attributes.put("login", new LoginBean(formData));
-
- switch (page) {
- case LOGIN_CONFIG_TOTP:
- attributes.put("totp", new TotpBean(user, baseUri));
- break;
- case LOGIN_UPDATE_PROFILE:
- attributes.put("user", new ProfileBean(user));
- break;
- case REGISTER:
- attributes.put("register", new RegisterBean(formData));
- break;
- case OAUTH_GRANT:
- attributes.put("oauth", new OAuthGrantBean(accessCode, client, realmRolesRequested, resourceRolesRequested));
- break;
- }
-
- try {
- String result = FreeMarkerUtil.processTemplate(attributes, Templates.getTemplate(page), theme);
- return Response.status(status).type(MediaType.TEXT_HTML).entity(result).build();
- } catch (FreeMarkerException e) {
- logger.error("Failed to process template", e);
- return Response.serverError().build();
- }
- }
-
- public Response createLogin() {
- return createResponse(LoginFormsPages.LOGIN);
- }
-
- public Response createPasswordReset() {
- return createResponse(LoginFormsPages.LOGIN_RESET_PASSWORD);
- }
-
- public Response createUsernameReminder() {
- return createResponse(LoginFormsPages.LOGIN_USERNAME_REMINDER);
- }
-
- public Response createLoginTotp() {
- return createResponse(LoginFormsPages.LOGIN_TOTP);
- }
-
- public Response createRegistration() {
- return createResponse(LoginFormsPages.REGISTER);
- }
-
- public Response createErrorPage() {
- setStatus(Response.Status.INTERNAL_SERVER_ERROR);
- return createResponse(LoginFormsPages.ERROR);
- }
-
- public Response createOAuthGrant() {
- return createResponse(LoginFormsPages.OAUTH_GRANT);
- }
-
- public FreeMarkerLoginForms setError(String message) {
- this.message = message;
- this.messageType = MessageType.ERROR;
- return this;
- }
-
- public FreeMarkerLoginForms setSuccess(String message) {
- this.message = message;
- this.messageType = MessageType.SUCCESS;
- return this;
- }
-
- public FreeMarkerLoginForms setWarning(String message) {
- this.message = message;
- this.messageType = MessageType.WARNING;
- return this;
- }
-
- public FreeMarkerLoginForms setUser(UserModel user) {
- this.user = user;
- return this;
- }
-
- public FreeMarkerLoginForms setClient(UserModel client) {
- this.client = client;
- return this;
- }
-
- public FreeMarkerLoginForms setFormData(MultivaluedMap formData) {
- this.formData = formData;
- return this;
- }
-
- @Override
- public LoginForms setAccessCode(String accessCodeId, String accessCode) {
- this.accessCodeId = accessCodeId;
- this.accessCode = accessCode;
- return this;
- }
-
- @Override
- public LoginForms setAccessRequest(List realmRolesRequested, MultivaluedMap resourceRolesRequested) {
- this.realmRolesRequested = realmRolesRequested;
- this.resourceRolesRequested = resourceRolesRequested;
- return this;
- }
-
- @Override
- public LoginForms setStatus(Response.Status status) {
- this.status = status;
- return this;
- }
-
-}
+package org.keycloak.login.freemarker;
+
+import org.jboss.logging.Logger;
+import org.jboss.resteasy.spi.HttpRequest;
+import org.keycloak.freemarker.FreeMarkerException;
+import org.keycloak.freemarker.FreeMarkerUtil;
+import org.keycloak.freemarker.Theme;
+import org.keycloak.freemarker.ThemeLoader;
+import org.keycloak.login.LoginForms;
+import org.keycloak.login.LoginFormsPages;
+import org.keycloak.login.freemarker.model.LoginBean;
+import org.keycloak.login.freemarker.model.MessageBean;
+import org.keycloak.login.freemarker.model.OAuthGrantBean;
+import org.keycloak.login.freemarker.model.ProfileBean;
+import org.keycloak.login.freemarker.model.RealmBean;
+import org.keycloak.login.freemarker.model.RegisterBean;
+import org.keycloak.login.freemarker.model.SocialBean;
+import org.keycloak.login.freemarker.model.TotpBean;
+import org.keycloak.login.freemarker.model.UrlBean;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.services.email.EmailException;
+import org.keycloak.services.email.EmailSender;
+import org.keycloak.services.messages.Messages;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author Stian Thorgersen
+ */
+public class FreeMarkerLoginForms implements LoginForms {
+
+ private static final Logger logger = Logger.getLogger(FreeMarkerLoginForms.class);
+
+ private String message;
+ private String accessCodeId;
+ private String accessCode;
+ private Response.Status status = Response.Status.OK;
+ private List realmRolesRequested;
+ private MultivaluedMap resourceRolesRequested;
+
+ public static enum MessageType {SUCCESS, WARNING, ERROR}
+
+ private MessageType messageType = MessageType.ERROR;
+
+ private MultivaluedMap formData;
+
+ private RealmModel realm;
+
+ // TODO Remove
+ private HttpRequest request;
+
+ private UserModel user;
+
+ private UserModel client;
+
+ private UriInfo uriInfo;
+
+ FreeMarkerLoginForms(RealmModel realm, org.jboss.resteasy.spi.HttpRequest request, UriInfo uriInfo) {
+ this.realm = realm;
+ this.request = request;
+ this.uriInfo = uriInfo;
+ }
+
+ public Response createResponse(UserModel.RequiredAction action) {
+ String actionMessage;
+ LoginFormsPages page;
+
+ switch (action) {
+ case CONFIGURE_TOTP:
+ actionMessage = Messages.ACTION_WARN_TOTP;
+ page = LoginFormsPages.LOGIN_CONFIG_TOTP;
+ break;
+ case UPDATE_PROFILE:
+ actionMessage = Messages.ACTION_WARN_PROFILE;
+ page = LoginFormsPages.LOGIN_UPDATE_PROFILE;
+ break;
+ case UPDATE_PASSWORD:
+ actionMessage = Messages.ACTION_WARN_PASSWD;
+ page = LoginFormsPages.LOGIN_UPDATE_PASSWORD;
+ break;
+ case VERIFY_EMAIL:
+ try {
+ new EmailSender(realm.getSmtpConfig()).sendEmailVerification(user, realm, accessCodeId, uriInfo);
+ } catch (EmailException e) {
+ return setError("emailSendError").createErrorPage();
+ }
+
+ actionMessage = Messages.ACTION_WARN_EMAIL;
+ page = LoginFormsPages.LOGIN_VERIFY_EMAIL;
+ break;
+ default:
+ return Response.serverError().build();
+ }
+
+ if (message == null) {
+ setWarning(actionMessage);
+ }
+
+ return createResponse(page);
+ }
+
+ private Response createResponse(LoginFormsPages page) {
+ MultivaluedMap queryParameterMap = uriInfo.getQueryParameters();
+
+ String requestURI = uriInfo.getBaseUri().getPath();
+ UriBuilder uriBuilder = UriBuilder.fromUri(requestURI);
+
+ for (String k : queryParameterMap.keySet()) {
+ uriBuilder.replaceQueryParam(k, queryParameterMap.get(k).toArray());
+ }
+
+ if (accessCode != null) {
+ uriBuilder.replaceQueryParam("code", accessCode);
+ }
+
+ Map attributes = new HashMap();
+
+ Theme theme;
+ try {
+ theme = ThemeLoader.createTheme(realm.getLoginTheme(), Theme.Type.LOGIN);
+ } catch (FreeMarkerException e) {
+ logger.error("Failed to create theme", e);
+ return Response.serverError().build();
+ }
+
+ try {
+ attributes.put("properties", theme.getProperties());
+ } catch (IOException e) {
+ logger.warn("Failed to load properties", e);
+ }
+
+ Properties messages;
+ try {
+ messages = theme.getMessages();
+ attributes.put("rb", messages);
+ } catch (IOException e) {
+ logger.warn("Failed to load messages", e);
+ messages = new Properties();
+ }
+
+ if (message != null) {
+ attributes.put("message", new MessageBean(messages.containsKey(message) ? messages.getProperty(message) : message, messageType));
+ }
+
+ URI baseUri = uriBuilder.build();
+
+ if (realm != null) {
+ attributes.put("realm", new RealmBean(realm));
+ attributes.put("social", new SocialBean(realm, baseUri));
+ attributes.put("url", new UrlBean(realm, theme, baseUri));
+ }
+
+ attributes.put("login", new LoginBean(formData));
+
+ switch (page) {
+ case LOGIN_CONFIG_TOTP:
+ attributes.put("totp", new TotpBean(user, baseUri));
+ break;
+ case LOGIN_UPDATE_PROFILE:
+ attributes.put("user", new ProfileBean(user));
+ break;
+ case REGISTER:
+ attributes.put("register", new RegisterBean(formData));
+ break;
+ case OAUTH_GRANT:
+ attributes.put("oauth", new OAuthGrantBean(accessCode, client, realmRolesRequested, resourceRolesRequested));
+ break;
+ }
+
+ try {
+ String result = FreeMarkerUtil.processTemplate(attributes, Templates.getTemplate(page), theme);
+ return Response.status(status).type(MediaType.TEXT_HTML).entity(result).build();
+ } catch (FreeMarkerException e) {
+ logger.error("Failed to process template", e);
+ return Response.serverError().build();
+ }
+ }
+
+ public Response createLogin() {
+ return createResponse(LoginFormsPages.LOGIN);
+ }
+
+ public Response createPasswordReset() {
+ return createResponse(LoginFormsPages.LOGIN_RESET_PASSWORD);
+ }
+
+ public Response createUsernameReminder() {
+ return createResponse(LoginFormsPages.LOGIN_USERNAME_REMINDER);
+ }
+
+ public Response createLoginTotp() {
+ return createResponse(LoginFormsPages.LOGIN_TOTP);
+ }
+
+ public Response createRegistration() {
+ return createResponse(LoginFormsPages.REGISTER);
+ }
+
+ public Response createErrorPage() {
+ setStatus(Response.Status.INTERNAL_SERVER_ERROR);
+ return createResponse(LoginFormsPages.ERROR);
+ }
+
+ public Response createOAuthGrant() {
+ return createResponse(LoginFormsPages.OAUTH_GRANT);
+ }
+
+ public FreeMarkerLoginForms setError(String message) {
+ this.message = message;
+ this.messageType = MessageType.ERROR;
+ return this;
+ }
+
+ public FreeMarkerLoginForms setSuccess(String message) {
+ this.message = message;
+ this.messageType = MessageType.SUCCESS;
+ return this;
+ }
+
+ public FreeMarkerLoginForms setWarning(String message) {
+ this.message = message;
+ this.messageType = MessageType.WARNING;
+ return this;
+ }
+
+ public FreeMarkerLoginForms setUser(UserModel user) {
+ this.user = user;
+ return this;
+ }
+
+ public FreeMarkerLoginForms setClient(UserModel client) {
+ this.client = client;
+ return this;
+ }
+
+ public FreeMarkerLoginForms setFormData(MultivaluedMap formData) {
+ this.formData = formData;
+ return this;
+ }
+
+ @Override
+ public LoginForms setAccessCode(String accessCodeId, String accessCode) {
+ this.accessCodeId = accessCodeId;
+ this.accessCode = accessCode;
+ return this;
+ }
+
+ @Override
+ public LoginForms setAccessRequest(List realmRolesRequested, MultivaluedMap resourceRolesRequested) {
+ this.realmRolesRequested = realmRolesRequested;
+ this.resourceRolesRequested = resourceRolesRequested;
+ return this;
+ }
+
+ @Override
+ public LoginForms setStatus(Response.Status status) {
+ this.status = status;
+ return this;
+ }
+
+}
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
index 4c04f12a48..d18dde5ccf 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/OAuthGrantBean.java
@@ -1,66 +1,66 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2012, Red Hat, Inc., and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.keycloak.login.freemarker.model;
-
-import org.keycloak.models.RoleModel;
-import org.keycloak.models.UserModel;
-
-import javax.ws.rs.core.MultivaluedMap;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Viliam Rockai
- */
-public class OAuthGrantBean {
-
- private List realmRolesRequested;
- private MultivaluedMap resourceRolesRequested;
- private String code;
- private UserModel client;
- private String oAuthCode;
- private String action;
-
- public OAuthGrantBean(String code, UserModel client, List realmRolesRequested, MultivaluedMap resourceRolesRequested) {
- this.code = code;
- this.client = client;
- this.realmRolesRequested = realmRolesRequested;
- this.resourceRolesRequested = resourceRolesRequested;
- }
-
- public String getCode() {
- return code;
- }
-
- public MultivaluedMap getResourceRolesRequested() {
- return resourceRolesRequested;
- }
-
- public List getRealmRolesRequested() {
- return realmRolesRequested;
- }
-
- public String getClient() {
- return client.getLoginName();
- }
-
-}
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2012, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.keycloak.login.freemarker.model;
+
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.UserModel;
+
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Viliam Rockai
+ */
+public class OAuthGrantBean {
+
+ private List realmRolesRequested;
+ private MultivaluedMap resourceRolesRequested;
+ private String code;
+ private UserModel client;
+ private String oAuthCode;
+ private String action;
+
+ public OAuthGrantBean(String code, UserModel client, List realmRolesRequested, MultivaluedMap resourceRolesRequested) {
+ this.code = code;
+ this.client = client;
+ this.realmRolesRequested = realmRolesRequested;
+ this.resourceRolesRequested = resourceRolesRequested;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public MultivaluedMap getResourceRolesRequested() {
+ return resourceRolesRequested;
+ }
+
+ public List getRealmRolesRequested() {
+ return realmRolesRequested;
+ }
+
+ public String getClient() {
+ return client.getLoginName();
+ }
+
+}
diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSession.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSession.java
index 8716e0ef5c..7e14a79d1b 100755
--- a/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSession.java
+++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSession.java
@@ -7,6 +7,7 @@ import org.keycloak.adapters.config.RealmConfiguration;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
import org.jboss.logging.Logger;
+import org.keycloak.representations.IDToken;
import java.io.IOException;
@@ -24,8 +25,8 @@ public class RefreshableKeycloakSession extends KeycloakAuthenticatedSession {
public RefreshableKeycloakSession() {
}
- public RefreshableKeycloakSession(String tokenString, AccessToken token, ResourceMetadata metadata, RealmConfiguration realmConfiguration, String refreshToken) {
- super(tokenString, token, metadata);
+ public RefreshableKeycloakSession(String tokenString, AccessToken token, String idTokenString, IDToken idToken, ResourceMetadata metadata, RealmConfiguration realmConfiguration, String refreshToken) {
+ super(tokenString, token, idTokenString, idToken, metadata);
this.realmConfiguration = realmConfiguration;
this.refreshToken = refreshToken;
}
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java
index 86933f06de..93be4f4951 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaBearerTokenAuthenticator.java
@@ -106,7 +106,7 @@ public class CatalinaBearerTokenAuthenticator {
principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), skeletonKeyPrincipal, roles);
request.setUserPrincipal(principal);
request.setAuthType("OAUTH_BEARER");
- KeycloakAuthenticatedSession skSession = new KeycloakAuthenticatedSession(tokenString, token, resourceMetadata);
+ KeycloakAuthenticatedSession skSession = new KeycloakAuthenticatedSession(tokenString, token, null, null, resourceMetadata);
request.setAttribute(KeycloakAuthenticatedSession.class.getName(), skSession);
return true;
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java
index 430b3bd506..b6e8af9028 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/KeycloakAuthenticatorValve.java
@@ -262,7 +262,7 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
Session session = request.getSessionInternal(true);
session.setPrincipal(principal);
session.setAuthType("OAUTH");
- KeycloakAuthenticatedSession skSession = new RefreshableKeycloakSession(oauth.getTokenString(), oauth.getToken(), resourceMetadata, realmConfiguration, oauth.getRefreshToken());
+ KeycloakAuthenticatedSession skSession = new RefreshableKeycloakSession(oauth.getTokenString(), oauth.getToken(), oauth.getIdTokenString(), oauth.getIdToken(), resourceMetadata, realmConfiguration, oauth.getRefreshToken());
session.setNote(KeycloakAuthenticatedSession.class.getName(), skSession);
String username = token.getSubject();
diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java
index 35cb609396..1cec19f407 100755
--- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java
+++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/ServletOAuthLogin.java
@@ -5,8 +5,10 @@ import org.keycloak.RSATokenVerifier;
import org.keycloak.VerificationException;
import org.keycloak.adapters.TokenGrantRequest;
import org.keycloak.adapters.config.RealmConfiguration;
+import org.keycloak.jose.jws.JWSInput;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.representations.IDToken;
import org.keycloak.util.KeycloakUriBuilder;
import javax.servlet.http.Cookie;
@@ -28,6 +30,8 @@ public class ServletOAuthLogin {
protected RealmConfiguration realmInfo;
protected int redirectPort;
protected String tokenString;
+ protected String idTokenString;
+ protected IDToken idToken;
protected AccessToken token;
protected String refreshToken;
@@ -50,6 +54,14 @@ public class ServletOAuthLogin {
return refreshToken;
}
+ public String getIdTokenString() {
+ return idTokenString;
+ }
+
+ public IDToken getIdToken() {
+ return idToken;
+ }
+
public RealmConfiguration getRealmInfo() {
return realmInfo;
}
@@ -246,8 +258,17 @@ public class ServletOAuthLogin {
}
tokenString = tokenResponse.getToken();
+ idTokenString = tokenResponse.getIdToken();
try {
token = RSATokenVerifier.verifyToken(tokenString, realmInfo.getMetadata().getRealmKey(), realmInfo.getMetadata().getRealm());
+ if (idTokenString != null) {
+ JWSInput input = new JWSInput(idTokenString);
+ try {
+ idToken = input.readJsonContent(IDToken.class);
+ } catch (IOException e) {
+ throw new VerificationException();
+ }
+ }
log.debug("Token Verification succeeded!");
} catch (VerificationException e) {
log.error("failed verification of token");
diff --git a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java
index 6e226365cc..88d29c404f 100755
--- a/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java
+++ b/integration/jaxrs-oauth-client/src/main/java/org/keycloak/jaxrs/JaxrsBearerTokenFilter.java
@@ -67,7 +67,7 @@ public class JaxrsBearerTokenFilter implements ContainerRequestFilter {
try {
AccessToken token = RSATokenVerifier.verifyToken(tokenString, resourceMetadata.getRealmKey(), resourceMetadata.getRealm());
- KeycloakAuthenticatedSession skSession = new KeycloakAuthenticatedSession(tokenString, token, resourceMetadata);
+ KeycloakAuthenticatedSession skSession = new KeycloakAuthenticatedSession(tokenString, token, null, null, resourceMetadata);
ResteasyProviderFactory.pushContext(KeycloakAuthenticatedSession.class, skSession);
String callerPrincipal = securityContext.getUserPrincipal() != null ? securityContext.getUserPrincipal().getName() : null;
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakAuthenticationMechanism.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakAuthenticationMechanism.java
index 5b9ef86d34..ffa950561a 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakAuthenticationMechanism.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakAuthenticationMechanism.java
@@ -94,7 +94,7 @@ public class KeycloakAuthenticationMechanism implements AuthenticationMechanism
protected void completeAuthentication(HttpServerExchange exchange, SecurityContext securityContext, OAuthAuthenticator oauth) {
final KeycloakPrincipal principal = new KeycloakPrincipal(oauth.getToken().getSubject(), null);
- RefreshableKeycloakSession session = new RefreshableKeycloakSession(oauth.getTokenString(), oauth.getToken(), resourceMetadata, realmConfig, oauth.getRefreshToken());
+ RefreshableKeycloakSession session = new RefreshableKeycloakSession(oauth.getTokenString(), oauth.getToken(), oauth.getIdTokenString(), oauth.getIdToken(), resourceMetadata, realmConfig, oauth.getRefreshToken());
KeycloakUndertowAccount account = new KeycloakUndertowAccount(principal, session, adapterConfig, resourceMetadata);
securityContext.authenticationComplete(account, "KEYCLOAK", true);
login(exchange, account);
@@ -107,7 +107,7 @@ public class KeycloakAuthenticationMechanism implements AuthenticationMechanism
protected void completeAuthentication(SecurityContext securityContext, BearerTokenAuthenticator bearer) {
final KeycloakPrincipal principal = new KeycloakPrincipal(bearer.getToken().getSubject(), bearer.getSurrogate());
- RefreshableKeycloakSession session = new RefreshableKeycloakSession(bearer.getTokenString(), bearer.getToken(), resourceMetadata, realmConfig, null);
+ RefreshableKeycloakSession session = new RefreshableKeycloakSession(bearer.getTokenString(), bearer.getToken(), null, null, resourceMetadata, realmConfig, null);
KeycloakUndertowAccount account = new KeycloakUndertowAccount(principal, session, adapterConfig, resourceMetadata);
securityContext.authenticationComplete(account, "KEYCLOAK", false);
}
diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/OAuthAuthenticator.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/OAuthAuthenticator.java
index d21e5d3ed6..29bb28a00d 100755
--- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/OAuthAuthenticator.java
+++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/OAuthAuthenticator.java
@@ -12,8 +12,10 @@ import org.keycloak.RSATokenVerifier;
import org.keycloak.adapters.config.RealmConfiguration;
import org.keycloak.VerificationException;
import org.keycloak.adapters.TokenGrantRequest;
+import org.keycloak.jose.jws.JWSInput;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.representations.IDToken;
import org.keycloak.util.KeycloakUriBuilder;
import java.io.IOException;
@@ -31,6 +33,8 @@ public class OAuthAuthenticator {
protected RealmConfiguration realmInfo;
protected int sslRedirectPort;
protected String tokenString;
+ protected String idTokenString;
+ protected IDToken idToken;
protected AccessToken token;
protected HttpServerExchange exchange;
protected KeycloakChallenge challenge;
@@ -58,6 +62,22 @@ public class OAuthAuthenticator {
return refreshToken;
}
+ public String getIdTokenString() {
+ return idTokenString;
+ }
+
+ public void setIdTokenString(String idTokenString) {
+ this.idTokenString = idTokenString;
+ }
+
+ public IDToken getIdToken() {
+ return idToken;
+ }
+
+ public void setIdToken(IDToken idToken) {
+ this.idToken = idToken;
+ }
+
protected String getRequestUrl() {
KeycloakUriBuilder uriBuilder = KeycloakUriBuilder.fromUri(exchange.getRequestURI())
.replaceQuery(exchange.getQueryString());
@@ -255,8 +275,17 @@ public class OAuthAuthenticator {
tokenString = tokenResponse.getToken();
refreshToken = tokenResponse.getRefreshToken();
+ idTokenString = tokenResponse.getIdToken();
try {
token = RSATokenVerifier.verifyToken(tokenString, realmInfo.getMetadata().getRealmKey(), realmInfo.getMetadata().getRealm());
+ if (idTokenString != null) {
+ JWSInput input = new JWSInput(idTokenString);
+ try {
+ idToken = input.readJsonContent(IDToken.class);
+ } catch (IOException e) {
+ throw new VerificationException();
+ }
+ }
log.debug("Token Verification succeeded!");
} catch (VerificationException e) {
log.error("failed verification of token");
diff --git a/model/api/src/main/java/org/keycloak/models/ApplicationModel.java b/model/api/src/main/java/org/keycloak/models/ApplicationModel.java
index 46576448c9..6247cdca34 100755
--- a/model/api/src/main/java/org/keycloak/models/ApplicationModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ApplicationModel.java
@@ -7,13 +7,9 @@ import java.util.Set;
* @author Bill Burke
* @version $Revision: 1 $
*/
-public interface ApplicationModel extends RoleContainerModel {
+public interface ApplicationModel extends RoleContainerModel, ClientModel {
void updateApplication();
- UserModel getApplicationUser();
-
- String getId();
-
String getName();
void setName(String name);
@@ -45,4 +41,5 @@ public interface ApplicationModel extends RoleContainerModel {
Set getApplicationScopeMappings(UserModel user);
void addScope(RoleModel role);
+
}
diff --git a/model/api/src/main/java/org/keycloak/models/ClaimMask.java b/model/api/src/main/java/org/keycloak/models/ClaimMask.java
new file mode 100755
index 0000000000..7d4334c9ac
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/ClaimMask.java
@@ -0,0 +1,50 @@
+package org.keycloak.models;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class ClaimMask {
+ public static final long NAME = 0x01l;
+ public static final long USERNAME = 0x02l;
+ public static final long PROFILE = 0x04l;
+ public static final long PICTURE = 0x08l;
+ public static final long WEBSITE = 0x10l;
+ public static final long EMAIL = 0x20l;
+ public static final long GENDER = 0x40l;
+ public static final long LOCALE = 0x80l;
+ public static final long ADDRESS = 0x100l;
+ public static final long PHONE = 0x200l;
+
+ public static boolean hasName(long mask) {
+ return (mask & NAME) > 0;
+ }
+ public static boolean hasUsername(long mask) {
+ return (mask & USERNAME) > 0;
+ }
+ public static boolean hasProfile(long mask) {
+ return (mask & PROFILE) > 0;
+ }
+ public static boolean hasPicture(long mask) {
+ return (mask & PICTURE) > 0;
+ }
+ public static boolean hasWebsite(long mask) {
+ return (mask & WEBSITE) > 0;
+ }
+ public static boolean hasEmail(long mask) {
+ return (mask & EMAIL) > 0;
+ }
+ public static boolean hasGender(long mask) {
+ return (mask & GENDER) > 0;
+ }
+ public static boolean hasLocale(long mask) {
+ return (mask & LOCALE) > 0;
+ }
+ public static boolean hasAddress(long mask) {
+ return (mask & ADDRESS) > 0;
+ }
+ public static boolean hasPhone(long mask) {
+ return (mask & PHONE) > 0;
+ }
+
+}
diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java
new file mode 100755
index 0000000000..ab38dd3c53
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -0,0 +1,15 @@
+package org.keycloak.models;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public interface ClientModel {
+ long getAllowedClaimsMask();
+
+ void setAllowedClaimsMask(long mask);
+
+ UserModel getAgent();
+
+ String getId();
+}
diff --git a/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java b/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java
index 622500c588..e5e828416c 100755
--- a/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/OAuthClientModel.java
@@ -4,8 +4,6 @@ package org.keycloak.models;
* @author Bill Burke
* @version $Revision: 1 $
*/
-public interface OAuthClientModel {
- String getId();
+public interface OAuthClientModel extends ClientModel {
- UserModel getOAuthAgent();
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
index 9c25a3813f..3b43464656 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ApplicationAdapter.java
@@ -6,17 +6,13 @@ import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.jpa.entities.*;
-import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
-import org.keycloak.representations.idm.RoleRepresentation;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
/**
@@ -41,7 +37,7 @@ public class ApplicationAdapter implements ApplicationModel {
}
@Override
- public UserModel getApplicationUser() {
+ public UserModel getAgent() {
return new UserAdapter(application.getApplicationUser());
}
@@ -70,6 +66,16 @@ public class ApplicationAdapter implements ApplicationModel {
application.setEnabled(enabled);
}
+ @Override
+ public long getAllowedClaimsMask() {
+ return application.getAllowedClaimsMask();
+ }
+
+ @Override
+ public void setAllowedClaimsMask(long mask) {
+ application.setAllowedClaimsMask(mask);
+ }
+
@Override
public boolean isSurrogateAuthRequired() {
return application.isSurrogateAuthRequired();
@@ -266,7 +272,7 @@ public class ApplicationAdapter implements ApplicationModel {
@Override
public void addScope(RoleModel role) {
- realm.addScopeMapping(getApplicationUser(), role);
+ realm.addScopeMapping(getAgent(), role);
}
public boolean equals(Object o) {
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
index fd2afcc487..6bb62ccacb 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/OAuthClientAdapter.java
@@ -25,8 +25,19 @@ public class OAuthClientAdapter implements OAuthClientModel {
}
@Override
- public UserModel getOAuthAgent() {
+ public UserModel getAgent() {
return new UserAdapter(entity.getAgent());
}
+ @Override
+ public long getAllowedClaimsMask() {
+ return entity.getAllowedClaimsMask();
+ }
+
+ @Override
+ public void setAllowedClaimsMask(long mask) {
+ entity.setAllowedClaimsMask(mask);
+ }
+
+
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
index 19a59817db..b85f720f7b 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ApplicationEntity.java
@@ -30,6 +30,7 @@ public class ApplicationEntity {
private boolean surrogateAuthRequired;
private String baseUrl;
private String managementUrl;
+ private long allowedClaimsMask;
@OneToOne(fetch = FetchType.EAGER)
private UserEntity applicationUser;
@@ -119,4 +120,12 @@ public class ApplicationEntity {
public void setRealm(RealmEntity realm) {
this.realm = realm;
}
+
+ public long getAllowedClaimsMask() {
+ return allowedClaimsMask;
+ }
+
+ public void setAllowedClaimsMask(long allowedClaimsMask) {
+ this.allowedClaimsMask = allowedClaimsMask;
+ }
}
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
index d266ed7502..9a114a1795 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/OAuthClientEntity.java
@@ -28,6 +28,7 @@ public class OAuthClientEntity {
private String id;
private String name;
+ private long allowedClaimsMask;
@OneToOne(fetch = FetchType.EAGER)
private UserEntity agent;
@@ -62,4 +63,13 @@ public class OAuthClientEntity {
public void setRealm(RealmEntity realm) {
this.realm = realm;
}
+
+ public long getAllowedClaimsMask() {
+ return allowedClaimsMask;
+ }
+
+ public void setAllowedClaimsMask(long allowedClaimsMask) {
+ this.allowedClaimsMask = allowedClaimsMask;
+ }
+
}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
index 80835f2b7e..a0da211452 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ApplicationAdapter.java
@@ -41,7 +41,7 @@ public class ApplicationAdapter extends AbstractAdapter implements ApplicationMo
}
@Override
- public UserAdapter getApplicationUser() {
+ public UserAdapter getAgent() {
// This is not thread-safe. Assumption is that ApplicationAdapter instance is per-client object
if (resourceUser == null) {
UserEntity userEntity = getMongoStore().loadEntity(UserEntity.class, application.getResourceUserId(), invocationContext);
@@ -109,6 +109,17 @@ public class ApplicationAdapter extends AbstractAdapter implements ApplicationMo
return application.getBaseUrl();
}
+ @Override
+ public long getAllowedClaimsMask() {
+ return application.getAllowedClaimsMask();
+ }
+
+ @Override
+ public void setAllowedClaimsMask(long mask) {
+ application.setAllowedClaimsMask(mask);
+ }
+
+
@Override
public RoleAdapter getRole(String name) {
DBObject query = new QueryBuilder()
@@ -185,7 +196,7 @@ public class ApplicationAdapter extends AbstractAdapter implements ApplicationMo
@Override
public void addScope(RoleModel role) {
- UserAdapter appUser = getApplicationUser();
+ UserAdapter appUser = getAgent();
getMongoStore().pushItemToList(appUser.getUser(), "scopeIds", role.getId(), true, invocationContext);
}
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
index 2eacc45165..ea48f9154b 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/OAuthClientAdapter.java
@@ -31,7 +31,17 @@ public class OAuthClientAdapter extends AbstractAdapter implements OAuthClientMo
}
@Override
- public UserModel getOAuthAgent() {
+ public long getAllowedClaimsMask() {
+ return delegate.getAllowedClaimsMask();
+ }
+
+ @Override
+ public void setAllowedClaimsMask(long mask) {
+ delegate.setAllowedClaimsMask(mask);
+ }
+
+ @Override
+ public UserModel getAgent() {
// This is not thread-safe. Assumption is that OAuthClientAdapter instance is per-client object
if (oauthAgent == null) {
UserEntity user = getMongoStore().loadEntity(UserEntity.class, delegate.getOauthAgentId(), invocationContext);
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
old mode 100644
new mode 100755
index 39a62346a1..2a03171993
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
@@ -25,6 +25,7 @@ public class ApplicationEntity extends AbstractMongoIdentifiableEntity implement
private String resourceUserId;
private String realmId;
+ private long allowedClaimsMask;
// We are using names of defaultRoles (not ids)
private List defaultRoles = new ArrayList();
@@ -83,6 +84,15 @@ public class ApplicationEntity extends AbstractMongoIdentifiableEntity implement
this.resourceUserId = resourceUserId;
}
+ @MongoField
+ public long getAllowedClaimsMask() {
+ return allowedClaimsMask;
+ }
+
+ public void setAllowedClaimsMask(long allowedClaimsMask) {
+ this.allowedClaimsMask = allowedClaimsMask;
+ }
+
@MongoField
public String getRealmId() {
return realmId;
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
old mode 100644
new mode 100755
index f2875b1be0..78c3687f7f
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
@@ -16,6 +16,7 @@ public class OAuthClientEntity extends AbstractMongoIdentifiableEntity implement
private String oauthAgentId;
private String realmId;
+ private long allowedClaimsMask;
@MongoField
public String getName() {
@@ -44,6 +45,15 @@ public class OAuthClientEntity extends AbstractMongoIdentifiableEntity implement
this.realmId = realmId;
}
+ @MongoField
+ public long getAllowedClaimsMask() {
+ return allowedClaimsMask;
+ }
+
+ public void setAllowedClaimsMask(long allowedClaimsMask) {
+ this.allowedClaimsMask = allowedClaimsMask;
+ }
+
@Override
public void afterRemove(MongoStoreInvocationContext context) {
// Remove user of this oauthClient
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
index 8aa12f9b19..eb119d547c 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AdapterTest.java
@@ -1,7 +1,6 @@
package org.keycloak.model.test;
import org.junit.Assert;
-import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
@@ -15,7 +14,6 @@ import org.keycloak.models.SocialLinkModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.ApplianceBootstrap;
import org.keycloak.services.managers.OAuthClientManager;
import org.keycloak.services.managers.RealmManager;
@@ -141,7 +139,7 @@ public class AdapterTest extends AbstractModelTest {
OAuthClientModel oauth = new OAuthClientManager(realmModel).create("oauth-client");
oauth = realmModel.getOAuthClient("oauth-client");
- Assert.assertTrue(realmModel.hasRole(oauth.getOAuthAgent(), realmModel.getRole(Constants.IDENTITY_REQUESTER_ROLE)));
+ Assert.assertTrue(realmModel.hasRole(oauth.getAgent(), realmModel.getRole(Constants.IDENTITY_REQUESTER_ROLE)));
}
@@ -186,10 +184,10 @@ public class AdapterTest extends AbstractModelTest {
RoleModel appRole = app.addRole("test");
realmModel.grantRole(user, appRole);
- realmModel.addScopeMapping(client.getOAuthAgent(), appRole);
+ realmModel.addScopeMapping(client.getAgent(), appRole);
RoleModel realmRole = realmModel.addRole("test");
- realmModel.addScopeMapping(app.getApplicationUser(), realmRole);
+ realmModel.addScopeMapping(app.getAgent(), realmRole);
Assert.assertTrue(realmModel.removeApplication(app.getId()));
Assert.assertFalse(realmModel.removeApplication(app.getId()));
@@ -214,10 +212,10 @@ public class AdapterTest extends AbstractModelTest {
RoleModel appRole = app.addRole("test");
realmModel.grantRole(user, appRole);
- realmModel.addScopeMapping(client.getOAuthAgent(), appRole);
+ realmModel.addScopeMapping(client.getAgent(), appRole);
RoleModel realmRole = realmModel.addRole("test");
- realmModel.addScopeMapping(app.getApplicationUser(), realmRole);
+ realmModel.addScopeMapping(app.getAgent(), realmRole);
Assert.assertTrue(identitySession.removeRealm(realmModel.getId()));
Assert.assertFalse(identitySession.removeRealm(realmModel.getId()));
@@ -237,10 +235,10 @@ public class AdapterTest extends AbstractModelTest {
RoleModel appRole = app.addRole("test");
realmModel.grantRole(user, appRole);
- realmModel.addScopeMapping(client.getOAuthAgent(), appRole);
+ realmModel.addScopeMapping(client.getAgent(), appRole);
RoleModel realmRole = realmModel.addRole("test");
- realmModel.addScopeMapping(app.getApplicationUser(), realmRole);
+ realmModel.addScopeMapping(app.getAgent(), realmRole);
Assert.assertTrue(realmModel.removeRoleById(realmRole.getId()));
Assert.assertFalse(realmModel.removeRoleById(realmRole.getId()));
diff --git a/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
index 3cac5782e9..942aab901e 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/ApplicationModelTest.java
@@ -37,11 +37,11 @@ public class ApplicationModelTest extends AbstractModelTest {
application.addDefaultRole("role-1");
application.addDefaultRole("role-2");
- application.getApplicationUser().addRedirectUri("redirect-1");
- application.getApplicationUser().addRedirectUri("redirect-2");
+ application.getAgent().addRedirectUri("redirect-1");
+ application.getAgent().addRedirectUri("redirect-2");
- application.getApplicationUser().addWebOrigin("origin-1");
- application.getApplicationUser().addWebOrigin("origin-2");
+ application.getAgent().addWebOrigin("origin-1");
+ application.getAgent().addWebOrigin("origin-2");
application.updateApplication();
}
@@ -69,8 +69,8 @@ public class ApplicationModelTest extends AbstractModelTest {
Assert.assertEquals(expected.getManagementUrl(), actual.getManagementUrl());
Assert.assertEquals(expected.getDefaultRoles(), actual.getDefaultRoles());
- UserModel auser = actual.getApplicationUser();
- UserModel euser = expected.getApplicationUser();
+ UserModel auser = actual.getAgent();
+ UserModel euser = expected.getAgent();
Assert.assertTrue(euser.getRedirectUris().containsAll(auser.getRedirectUris()));
Assert.assertTrue(euser.getWebOrigins().containsAll(auser.getWebOrigins()));
diff --git a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
old mode 100644
new mode 100755
index ec14411199..c0ec969328
--- a/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
@@ -60,7 +60,7 @@ public class CompositeRolesModelTest extends AbstractModelTest {
ApplicationModel application = realm.getApplicationByName(applicationName);
Set roleMappings = realm.getRoleMappings(user);
- Set scopeMappings = realm.getScopeMappings(application.getApplicationUser());
+ Set scopeMappings = realm.getScopeMappings(application.getAgent());
Set appRoles = application.getRoles();
if (appRoles != null) scopeMappings.addAll(appRoles);
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 55642a2f63..3bbd8e49f9 100755
--- a/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ApplicationManager.java
@@ -4,6 +4,7 @@ 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.ClaimMask;
import org.keycloak.models.Constants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
@@ -57,7 +58,7 @@ public class ApplicationManager {
applicationModel.setBaseUrl(resourceRep.getBaseUrl());
applicationModel.updateApplication();
- UserModel resourceUser = applicationModel.getApplicationUser();
+ UserModel resourceUser = applicationModel.getAgent();
if (resourceRep.getCredentials() != null && resourceRep.getCredentials().size() > 0) {
for (CredentialRepresentation cred : resourceRep.getCredentials()) {
UserCredentialModel credential = new UserCredentialModel();
@@ -89,6 +90,12 @@ public class ApplicationManager {
applicationModel.updateDefaultRoles(resourceRep.getDefaultRoles());
}
+ if (resourceRep.getClaims() != null) {
+ ClaimManager.setClaims(applicationModel, resourceRep.getClaims());
+ } else {
+ applicationModel.setAllowedClaimsMask(ClaimMask.USERNAME);
+ }
+
return applicationModel;
}
@@ -129,7 +136,7 @@ public class ApplicationManager {
public ApplicationModel createApplication(RealmModel realm, String name) {
RoleModel loginRole = realm.getRole(Constants.APPLICATION_ROLE);
ApplicationModel app = realm.addApplication(name);
- realm.grantRole(app.getApplicationUser(), loginRole);
+ realm.grantRole(app.getAgent(), loginRole);
generateSecret(realm, app);
return app;
@@ -137,7 +144,7 @@ public class ApplicationManager {
public UserCredentialModel generateSecret(RealmModel realm, ApplicationModel app) {
UserCredentialModel secret = UserCredentialModel.generateSecret();
- realm.updateCredential(app.getApplicationUser(), secret);
+ realm.updateCredential(app.getAgent(), secret);
return secret;
}
@@ -155,12 +162,16 @@ public class ApplicationManager {
List redirectUris = rep.getRedirectUris();
if (redirectUris != null) {
- resource.getApplicationUser().setRedirectUris(new HashSet(redirectUris));
+ resource.getAgent().setRedirectUris(new HashSet(redirectUris));
}
List webOrigins = rep.getWebOrigins();
if (webOrigins != null) {
- resource.getApplicationUser().setWebOrigins(new HashSet(webOrigins));
+ resource.getAgent().setWebOrigins(new HashSet(webOrigins));
+ }
+
+ if (rep.getClaims() != null) {
+ ClaimManager.setClaims(resource, rep.getClaims());
}
}
@@ -173,12 +184,12 @@ public class ApplicationManager {
rep.setSurrogateAuthRequired(applicationModel.isSurrogateAuthRequired());
rep.setBaseUrl(applicationModel.getBaseUrl());
- Set redirectUris = applicationModel.getApplicationUser().getRedirectUris();
+ Set redirectUris = applicationModel.getAgent().getRedirectUris();
if (redirectUris != null) {
rep.setRedirectUris(new LinkedList(redirectUris));
}
- Set webOrigins = applicationModel.getApplicationUser().getWebOrigins();
+ Set webOrigins = applicationModel.getAgent().getWebOrigins();
if (webOrigins != null) {
rep.setWebOrigins(new LinkedList(webOrigins));
}
@@ -240,7 +251,7 @@ public class ApplicationManager {
rep.setResource(applicationModel.getName());
Map creds = new HashMap();
- String cred = realmModel.getSecret(applicationModel.getApplicationUser()).getValue();
+ String cred = realmModel.getSecret(applicationModel.getAgent()).getValue();
creds.put(CredentialRepresentation.SECRET, cred);
rep.setCredentials(creds);
@@ -255,7 +266,7 @@ public class ApplicationManager {
buffer.append(" ").append(baseUri.toString()).append("\n");
buffer.append(" ").append(realmModel.isSslNotRequired()).append("\n");
buffer.append(" ").append(applicationModel.getName()).append("\n");
- String cred = realmModel.getSecret(applicationModel.getApplicationUser()).getValue();
+ String cred = realmModel.getSecret(applicationModel.getAgent()).getValue();
buffer.append(" ").append(cred).append("\n");
buffer.append("\n");
return buffer.toString();
diff --git a/services/src/main/java/org/keycloak/services/managers/ClaimManager.java b/services/src/main/java/org/keycloak/services/managers/ClaimManager.java
new file mode 100755
index 0000000000..af1ab62d41
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/managers/ClaimManager.java
@@ -0,0 +1,66 @@
+package org.keycloak.services.managers;
+
+import org.keycloak.models.ClaimMask;
+import org.keycloak.models.ClientModel;
+import org.keycloak.representations.idm.ClaimRepresentation;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class ClaimManager {
+ public static void setClaims(ClientModel model, ClaimRepresentation rep) {
+ long mask = model.getAllowedClaimsMask();
+ if (rep.getAddress()) {
+ mask |= ClaimMask.ADDRESS;
+ } else {
+ mask &= ~ClaimMask.ADDRESS;
+ }
+ if (rep.getEmail()) {
+ mask |= ClaimMask.EMAIL;
+ } else {
+ mask &= ~ClaimMask.EMAIL;
+ }
+ if (rep.getGender()) {
+ mask |= ClaimMask.GENDER;
+ } else {
+ mask &= ~ClaimMask.GENDER;
+ }
+ if (rep.getLocale()) {
+ mask |= ClaimMask.LOCALE;
+ } else {
+ mask &= ~ClaimMask.LOCALE;
+ }
+ if (rep.getName()) {
+ mask |= ClaimMask.NAME;
+ } else {
+ mask &= ~ClaimMask.NAME;
+ }
+ if (rep.getPhone()) {
+ mask |= ClaimMask.PHONE;
+ } else {
+ mask &= ~ClaimMask.PHONE;
+ }
+ if (rep.getPicture()) {
+ mask |= ClaimMask.PICTURE;
+ } else {
+ mask &= ~ClaimMask.PICTURE;
+ }
+ if (rep.getProfile()) {
+ mask |= ClaimMask.PROFILE;
+ } else {
+ mask &= ~ClaimMask.PROFILE;
+ }
+ if (rep.getUsername()) {
+ mask |= ClaimMask.USERNAME;
+ } else {
+ mask &= ~ClaimMask.USERNAME;
+ }
+ if (rep.getWebsite()) {
+ mask |= ClaimMask.WEBSITE;
+ } else {
+ mask &= ~ClaimMask.WEBSITE;
+ }
+ model.setAllowedClaimsMask(mask);
+ }
+}
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 303cd94172..a83cf9e7bd 100755
--- a/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
+++ b/services/src/main/java/org/keycloak/services/managers/ModelToRepresentation.java
@@ -1,12 +1,15 @@
package org.keycloak.services.managers;
import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClaimMask;
+import org.keycloak.models.ClientModel;
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.ClaimRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
@@ -110,4 +113,19 @@ public class ModelToRepresentation {
rep.setValue(cred.getValue());
return rep;
}
+
+ public static ClaimRepresentation toRepresentation(ClientModel model) {
+ ClaimRepresentation rep = new ClaimRepresentation();
+ rep.setAddress(ClaimMask.hasAddress(model.getAllowedClaimsMask()));
+ rep.setEmail(ClaimMask.hasEmail(model.getAllowedClaimsMask()));
+ rep.setGender(ClaimMask.hasGender(model.getAllowedClaimsMask()));
+ rep.setLocale(ClaimMask.hasLocale(model.getAllowedClaimsMask()));
+ rep.setName(ClaimMask.hasName(model.getAllowedClaimsMask()));
+ rep.setPhone(ClaimMask.hasPhone(model.getAllowedClaimsMask()));
+ rep.setPicture(ClaimMask.hasPicture(model.getAllowedClaimsMask()));
+ rep.setProfile(ClaimMask.hasProfile(model.getAllowedClaimsMask()));
+ rep.setWebsite(ClaimMask.hasWebsite(model.getAllowedClaimsMask()));
+ rep.setUsername(ClaimMask.hasUsername(model.getAllowedClaimsMask()));
+ 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 5426755552..500bbadec1 100755
--- a/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/OAuthClientManager.java
@@ -2,18 +2,16 @@ 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.ClaimMask;
import org.keycloak.models.Constants;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
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;
import java.net.URI;
import java.util.HashMap;
@@ -36,7 +34,7 @@ public class OAuthClientManager {
public UserCredentialModel generateSecret(RealmModel realm, OAuthClientModel app) {
UserCredentialModel secret = UserCredentialModel.generateSecret();
- realm.updateCredential(app.getOAuthAgent(), secret);
+ realm.updateCredential(app.getAgent(), secret);
return secret;
}
@@ -44,7 +42,7 @@ public class OAuthClientManager {
public OAuthClientModel create(String name) {
OAuthClientModel model = realm.addOAuthClient(name);
RoleModel role = realm.getRole(Constants.IDENTITY_REQUESTER_ROLE);
- realm.grantRole(model.getOAuthAgent(), role);
+ realm.grantRole(model.getAgent(), role);
generateSecret(realm, model);
return model;
}
@@ -52,7 +50,7 @@ public class OAuthClientManager {
public OAuthClientModel create(OAuthClientRepresentation rep) {
OAuthClientModel model = create(rep.getName());
update(rep, model);
- UserModel resourceUser = model.getOAuthAgent();
+ UserModel resourceUser = model.getAgent();
if (rep.getCredentials() != null) {
for (CredentialRepresentation cred : rep.getCredentials()) {
UserCredentialModel credential = new UserCredentialModel();
@@ -61,33 +59,43 @@ public class OAuthClientManager {
realm.updateCredential(resourceUser, credential);
}
}
+ if (rep.getClaims() != null) {
+ ClaimManager.setClaims(model, rep.getClaims());
+ } else {
+ model.setAllowedClaimsMask(ClaimMask.USERNAME);
+ }
+
return model;
}
public void update(OAuthClientRepresentation rep, OAuthClientModel model) {
- model.getOAuthAgent().setEnabled(rep.isEnabled());
+ model.getAgent().setEnabled(rep.isEnabled());
List redirectUris = rep.getRedirectUris();
if (redirectUris != null) {
- model.getOAuthAgent().setRedirectUris(new HashSet(redirectUris));
+ model.getAgent().setRedirectUris(new HashSet(redirectUris));
}
List webOrigins = rep.getWebOrigins();
if (webOrigins != null) {
- model.getOAuthAgent().setWebOrigins(new HashSet(webOrigins));
+ model.getAgent().setWebOrigins(new HashSet(webOrigins));
+ }
+
+ if (rep.getClaims() != null) {
+ ClaimManager.setClaims(model, rep.getClaims());
}
}
public static OAuthClientRepresentation toRepresentation(OAuthClientModel model) {
OAuthClientRepresentation rep = new OAuthClientRepresentation();
rep.setId(model.getId());
- rep.setName(model.getOAuthAgent().getLoginName());
- rep.setEnabled(model.getOAuthAgent().isEnabled());
- Set redirectUris = model.getOAuthAgent().getRedirectUris();
+ rep.setName(model.getAgent().getLoginName());
+ rep.setEnabled(model.getAgent().isEnabled());
+ Set redirectUris = model.getAgent().getRedirectUris();
if (redirectUris != null) {
rep.setRedirectUris(new LinkedList(redirectUris));
}
- Set webOrigins = model.getOAuthAgent().getWebOrigins();
+ Set webOrigins = model.getAgent().getWebOrigins();
if (webOrigins != null) {
rep.setWebOrigins(new LinkedList(webOrigins));
}
@@ -127,10 +135,10 @@ public class OAuthClientManager {
rep.setSslNotRequired(realmModel.isSslNotRequired());
rep.setAuthServerUrl(baseUri.toString());
- rep.setResource(model.getOAuthAgent().getLoginName());
+ rep.setResource(model.getAgent().getLoginName());
Map creds = new HashMap();
- creds.put(CredentialRepresentation.SECRET, realmModel.getSecret(model.getOAuthAgent()).getValue());
+ creds.put(CredentialRepresentation.SECRET, realmModel.getSecret(model.getAgent()).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 ca71051399..0ee5c389aa 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -255,7 +255,7 @@ public class RealmManager {
if (rep.getApplications() != null) {
Map appMap = createApplications(rep, newRealm);
for (ApplicationModel app : appMap.values()) {
- userMap.put(app.getApplicationUser().getLoginName(), app.getApplicationUser());
+ userMap.put(app.getAgent().getLoginName(), app.getAgent());
}
}
@@ -308,7 +308,7 @@ public class RealmManager {
if (rep.getOauthClients() != null) {
Map oauthMap = createOAuthClients(rep, newRealm);
for (OAuthClientModel app : oauthMap.values()) {
- userMap.put(app.getOAuthAgent().getLoginName(), app.getOAuthAgent());
+ userMap.put(app.getAgent().getLoginName(), app.getAgent());
}
}
@@ -501,7 +501,7 @@ public class RealmManager {
OAuthClientManager manager = new OAuthClientManager(realm);
for (OAuthClientRepresentation rep : realmRep.getOauthClients()) {
OAuthClientModel app = manager.create(rep);
- appMap.put(app.getOAuthAgent().getLoginName(), app);
+ appMap.put(app.getAgent().getLoginName(), app);
}
return appMap;
}
diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
index 080d52f8d7..93b7c5daae 100755
--- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java
@@ -6,6 +6,8 @@ import org.keycloak.jose.jws.JWSBuilder;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.crypto.RSAProvider;
import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClaimMask;
+import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
@@ -13,6 +15,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.AccessScope;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.representations.IDToken;
import org.keycloak.representations.RefreshToken;
import org.keycloak.util.Base64Url;
import org.keycloak.util.JsonSerialization;
@@ -21,7 +24,6 @@ import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
-import java.security.PrivateKey;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -178,7 +180,9 @@ public class TokenManager {
}
}
- AccessToken accessToken = initToken(realm, client, user);
+ ClientModel claimRequesterModel = getClaimRequester(realm, client);
+
+ AccessToken accessToken = initToken(realm, claimRequesterModel, client, user);
accessToken.setRealmAccess(refreshToken.getRealmAccess());
accessToken.setResourceAccess(refreshToken.getResourceAccess());
return accessToken;
@@ -188,6 +192,12 @@ public class TokenManager {
return createClientAccessToken(scopeParam, realm, client, user, new LinkedList(), new MultivaluedHashMap());
}
+ protected ClientModel getClaimRequester(RealmModel realm, UserModel client) {
+ ClientModel model = realm.getApplicationByName(client.getLoginName());
+ if (model != null) return model;
+ return realm.getOAuthClient(client.getLoginName());
+ }
+
public AccessToken createClientAccessToken(String scopeParam, RealmModel realm, UserModel client, UserModel user, List realmRolesRequested, MultivaluedMap resourceRolesRequested) {
AccessScope scopeMap = null;
@@ -196,6 +206,7 @@ public class TokenManager {
Set roleMappings = realm.getRoleMappings(user);
Set scopeMappings = realm.getScopeMappings(client);
+ ClientModel claimRequesterModel = getClaimRequester(realm, client);
ApplicationModel clientApp = realm.getApplicationByName(client.getLoginName());
Set clientAppRoles = clientApp == null ? null : clientApp.getRoles();
if (clientAppRoles != null) scopeMappings.addAll(clientAppRoles);
@@ -222,7 +233,7 @@ public class TokenManager {
}
}
- AccessToken token = initToken(realm, client, user);
+ AccessToken token = initToken(realm, claimRequesterModel, client, user);
if (realmRolesRequested.size() > 0) {
for (RoleModel role : realmRolesRequested) {
@@ -240,7 +251,42 @@ public class TokenManager {
return token;
}
- protected AccessToken initToken(RealmModel realm, UserModel client, UserModel user) {
+ public void initClaims(IDToken token, ClientModel model, UserModel user) {
+ if (ClaimMask.hasUsername(model.getAllowedClaimsMask())) {
+ token.setPreferredUsername(user.getLoginName());
+ }
+ if (ClaimMask.hasEmail(model.getAllowedClaimsMask())) {
+ token.setEmail(user.getEmail());
+ token.setEmailVerified(user.isEmailVerified());
+ }
+ if (ClaimMask.hasName(model.getAllowedClaimsMask())) {
+ token.setFamilyName(user.getLastName());
+ token.setGivenName(user.getFirstName());
+ StringBuilder fullName = new StringBuilder();
+ if (user.getFirstName() != null) fullName.append(user.getFirstName()).append(" ");
+ if (user.getLastName() != null) fullName.append(user.getLastName());
+ token.setName(fullName.toString());
+ }
+ }
+
+ protected IDToken initIDToken(RealmModel realm, ClientModel claimer, UserModel client, UserModel user) {
+ IDToken token = new IDToken();
+ token.id(KeycloakModelUtils.generateId());
+ token.subject(user.getId());
+ token.audience(realm.getName());
+ token.issuedNow();
+ token.issuedFor(client.getLoginName());
+ token.issuer(realm.getName());
+ if (realm.getAccessTokenLifespan() > 0) {
+ token.expiration((System.currentTimeMillis() / 1000) + realm.getAccessTokenLifespan());
+ }
+ initClaims(token, claimer, user);
+ return token;
+ }
+
+
+
+ protected AccessToken initToken(RealmModel realm, ClientModel claimer, UserModel client, UserModel user) {
AccessToken token = new AccessToken();
token.id(KeycloakModelUtils.generateId());
token.subject(user.getId());
@@ -250,12 +296,12 @@ public class TokenManager {
token.issuer(realm.getName());
if (realm.getAccessTokenLifespan() > 0) {
token.expiration((System.currentTimeMillis() / 1000) + realm.getAccessTokenLifespan());
- logger.info("Access Token expiration: " + token.getExpiration());
}
Set allowedOrigins = client.getWebOrigins();
if (allowedOrigins != null) {
token.setAllowedOrigins(allowedOrigins);
}
+ initClaims(token, claimer, user);
return token;
}
@@ -324,6 +370,7 @@ public class TokenManager {
RealmModel realm;
AccessToken accessToken;
RefreshToken refreshToken;
+ IDToken idToken;
public AccessTokenResponseBuilder(RealmModel realm) {
this.realm = realm;
@@ -354,8 +401,53 @@ public class TokenManager {
return this;
}
+ public AccessTokenResponseBuilder generateIDToken() {
+ if (accessToken == null) {
+ throw new IllegalStateException("accessToken not set");
+ }
+ idToken = new IDToken();
+ idToken.id(KeycloakModelUtils.generateId());
+ idToken.subject(accessToken.getSubject());
+ idToken.audience(realm.getName());
+ idToken.issuedNow();
+ idToken.issuedFor(accessToken.getIssuedFor());
+ idToken.issuer(accessToken.getIssuer());
+ if (realm.getAccessTokenLifespan() > 0) {
+ idToken.expiration((System.currentTimeMillis() / 1000) + realm.getAccessTokenLifespan());
+ }
+ idToken.setPreferredUsername(accessToken.getPreferredUsername());
+ idToken.setGivenName(accessToken.getGivenName());
+ idToken.setMiddleName(accessToken.getMiddleName());
+ idToken.setFamilyName(accessToken.getFamilyName());
+ idToken.setName(accessToken.getName());
+ idToken.setNickName(accessToken.getNickName());
+ idToken.setGender(accessToken.getGender());
+ idToken.setPicture(accessToken.getPicture());
+ idToken.setProfile(accessToken.getProfile());
+ idToken.setWebsite(accessToken.getWebsite());
+ idToken.setBirthdate(accessToken.getBirthdate());
+ idToken.setEmail(accessToken.getEmail());
+ idToken.setEmailVerified(accessToken.getEmailVerified());
+ idToken.setLocale(accessToken.getLocale());
+ idToken.setFormattedAddress(accessToken.getFormattedAddress());
+ idToken.setAddress(accessToken.getAddress());
+ idToken.setStreetAddress(accessToken.getStreetAddress());
+ idToken.setLocality(accessToken.getLocality());
+ idToken.setRegion(accessToken.getRegion());
+ idToken.setPostalCode(accessToken.getPostalCode());
+ idToken.setCountry(accessToken.getCountry());
+ idToken.setPhoneNumber(accessToken.getPhoneNumber());
+ idToken.setPhoneNumberVerified(accessToken.getPhoneNumberVerified());
+ idToken.setZoneinfo(accessToken.getZoneinfo());
+ return this;
+ }
+
public AccessTokenResponse build() {
AccessTokenResponse res = new AccessTokenResponse();
+ if (idToken != null) {
+ String encodedToken = new JWSBuilder().jsonContent(idToken).rsa256(realm.getPrivateKey());
+ res.setIdToken(encodedToken);
+ }
if (accessToken != null) {
String encodedToken = new JWSBuilder().jsonContent(accessToken).rsa256(realm.getPrivateKey());
res.setToken(encodedToken);
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index a3afea9b38..dd94e6f143 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -27,12 +27,9 @@ import org.keycloak.account.Account;
import org.keycloak.account.AccountLoader;
import org.keycloak.account.AccountPages;
import org.keycloak.jaxrs.JaxrsOAuthClient;
-import org.keycloak.jose.jws.JWSInput;
-import org.keycloak.jose.jws.crypto.RSAProvider;
import org.keycloak.models.*;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.AccessCodeEntry;
import org.keycloak.services.managers.AppAuthManager;
import org.keycloak.services.managers.Auth;
import org.keycloak.services.managers.ModelToRepresentation;
@@ -257,7 +254,7 @@ public class AccountService {
logger.debug("realm not enabled");
throw new ForbiddenException();
}
- UserModel client = application.getApplicationUser();
+ UserModel client = application.getAgent();
if (!client.isEnabled() || !application.isEnabled()) {
logger.debug("account management app not enabled");
throw new ForbiddenException();
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index 44ac6e2821..ba6ce97a19 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -159,7 +159,9 @@ public class TokenService {
}
String scope = form.getFirst("scope");
AccessTokenResponse res = tokenManager.responseBuilder(realm)
- .generateAccessToken(scope, client, user).build();
+ .generateAccessToken(scope, client, user)
+ .generateIDToken()
+ .build();
return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build();
}
@@ -188,6 +190,7 @@ public class TokenService {
AccessTokenResponse res = tokenManager.responseBuilder(realm)
.accessToken(accessToken)
+ .generateIDToken()
.generateRefreshToken().build();
return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build();
}
@@ -410,6 +413,7 @@ public class TokenService {
logger.debug("accessRequest SUCCESS");
AccessTokenResponse res = tokenManager.responseBuilder(realm)
.accessToken(accessCode.getToken())
+ .generateIDToken()
.generateRefreshToken().build();
return Cors.add(request, Response.ok(res)).allowedOrigins(client).allowedMethods("POST").build();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java
index 7a3fad1ba2..7c1e3f56ff 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java
@@ -325,7 +325,7 @@ public class AdminService {
return redirectOnLoginError("realm not enabled");
}
ApplicationModel adminConsole = adminRealm.getApplicationNameMap().get(Constants.ADMIN_CONSOLE_APPLICATION);
- UserModel adminConsoleUser = adminConsole.getApplicationUser();
+ UserModel adminConsoleUser = adminConsole.getAgent();
if (!adminConsole.isEnabled() || !adminConsoleUser.isEnabled()) {
logger.debug("admin app not enabled");
return redirectOnLoginError("admin app not enabled");
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 92c184592a..30270e5db9 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
@@ -6,7 +6,6 @@ import org.keycloak.models.ApplicationModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
-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;
@@ -59,6 +58,11 @@ public class ApplicationResource {
auth.init(RealmAuth.Resource.APPLICATION);
}
+ @Path("claims")
+ public ClaimResource getClaimResource() {
+ return new ClaimResource(application);
+ }
+
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public void update(final ApplicationRepresentation rep) {
@@ -133,7 +137,7 @@ public class ApplicationResource {
auth.requireView();
logger.debug("getClientSecret");
- UserCredentialModel model = realm.getSecret(application.getApplicationUser());
+ UserCredentialModel model = realm.getSecret(application.getAgent());
if (model == null) throw new NotFoundException("Application does not have a secret");
return ModelToRepresentation.toRepresentation(model);
}
@@ -141,7 +145,7 @@ public class ApplicationResource {
@Path("scope-mappings")
public ScopeMappedResource getScopeMappedResource() {
- return new ScopeMappedResource(realm, auth, application.getApplicationUser(), session);
+ return new ScopeMappedResource(realm, auth, application.getAgent(), session);
}
@Path("roles")
@@ -156,7 +160,7 @@ public class ApplicationResource {
{
auth.requireView();
- return application.getApplicationUser().getWebOrigins();
+ return application.getAgent().getWebOrigins();
}
@Path("allowed-origins")
@@ -166,7 +170,7 @@ public class ApplicationResource {
{
auth.requireManage();
- application.getApplicationUser().setWebOrigins(allowedOrigins);
+ application.getAgent().setWebOrigins(allowedOrigins);
}
@Path("allowed-origins")
@@ -177,7 +181,7 @@ public class ApplicationResource {
auth.requireManage();
for (String origin : allowedOrigins) {
- application.getApplicationUser().removeWebOrigin(origin);
+ application.getAgent().removeWebOrigin(origin);
}
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java
new file mode 100755
index 0000000000..579394eefa
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java
@@ -0,0 +1,36 @@
+package org.keycloak.services.resources.admin;
+
+import org.keycloak.models.ClientModel;
+import org.keycloak.representations.idm.ClaimRepresentation;
+import org.keycloak.services.managers.ClaimManager;
+import org.keycloak.services.managers.ModelToRepresentation;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class ClaimResource {
+ protected ClientModel model;
+
+ public ClaimResource(ClientModel model) {
+ this.model = model;
+ }
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public ClaimRepresentation getClaims() {
+ return ModelToRepresentation.toRepresentation(model);
+ }
+
+ @PUT
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void updateClaims(ClaimRepresentation rep) {
+ ClaimManager.setClaims(model, rep);
+ }
+}
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 7ae8fe33cb..cbd6018f86 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
@@ -6,13 +6,10 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
-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;
import org.keycloak.util.JsonSerialization;
@@ -29,7 +26,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;
/**
* @author Bill Burke
@@ -60,6 +56,12 @@ public class OAuthClientResource {
auth.init(RealmAuth.Resource.CLIENT);
}
+ @Path("claims")
+ public ClaimResource getClaimResource() {
+ return new ClaimResource(oauthClient);
+ }
+
+
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public void update(final OAuthClientRepresentation rep) {
@@ -110,7 +112,7 @@ public class OAuthClientResource {
logger.debug("regenerateSecret");
UserCredentialModel cred = UserCredentialModel.generateSecret();
- realm.updateCredential(oauthClient.getOAuthAgent(), cred);
+ realm.updateCredential(oauthClient.getAgent(), cred);
CredentialRepresentation rep = ModelToRepresentation.toRepresentation(cred);
return rep;
}
@@ -122,14 +124,14 @@ public class OAuthClientResource {
auth.requireView();
logger.debug("getClientSecret");
- UserCredentialModel model = realm.getSecret(oauthClient.getOAuthAgent());
+ UserCredentialModel model = realm.getSecret(oauthClient.getAgent());
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, auth, oauthClient.getOAuthAgent(), session);
+ return new ScopeMappedResource(realm, auth, oauthClient.getAgent(), session);
}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
index 445622429a..0c0deb99dd 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
@@ -58,7 +58,7 @@ public class OAuthClientsResource {
rep.add(OAuthClientManager.toRepresentation(oauth));
} else {
OAuthClientRepresentation client = new OAuthClientRepresentation();
- client.setName(oauth.getOAuthAgent().getLoginName());
+ client.setName(oauth.getAgent().getLoginName());
rep.add(client);
}
}
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
index 8524807eeb..f523fcc72a 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java
@@ -24,6 +24,7 @@ package org.keycloak.services.resources.flows;
import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.models.Constants;
+import org.keycloak.models.OAuthClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.RoleModel;
@@ -127,6 +128,7 @@ public class OAuthFlows {
if (!isResource
&& (accessCode.getRealmRolesRequested().size() > 0 || accessCode.getResourceRolesRequested().size() > 0)) {
+ OAuthClientModel oauthClient = realm.getOAuthClient(client.getLoginName());
accessCode.setExpiration(System.currentTimeMillis() / 1000 + realm.getAccessCodeLifespanUserAction());
return Flows.forms(realm, request, uriInfo).setAccessCode(accessCode.getId(), accessCode.getCode()).
setAccessRequest(accessCode.getRealmRolesRequested(), accessCode.getResourceRolesRequested()).
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
index 3c96873be4..044d72faea 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/ProfileTest.java
@@ -65,9 +65,9 @@ public class ProfileTest {
appRealm.updateCredential(user2, creds);
ApplicationModel app = appRealm.getApplicationNameMap().get("test-app");
- appRealm.addScopeMapping(app.getApplicationUser(), accountApp.getRole(AccountRoles.VIEW_PROFILE));
+ appRealm.addScopeMapping(app.getAgent(), accountApp.getRole(AccountRoles.VIEW_PROFILE));
- app.getApplicationUser().addWebOrigin("http://localtest.me:8081");
+ app.getAgent().addWebOrigin("http://localtest.me:8081");
UserModel thirdParty = appRealm.getUser("third-party");
appRealm.addScopeMapping(thirdParty, accountApp.getRole(AccountRoles.VIEW_PROFILE));
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 7d6c128c96..a8540ed93b 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
@@ -86,21 +86,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.secret("password"));
+ realm.updateCredential(realmComposite1Application.getAgent(), 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.secret("password"));
+ realm.updateCredential(realmRole1Application.getAgent(), 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.secret("password"));
+ realm.updateCredential(appRoleApplication.getAgent(), UserCredentialModel.secret("password"));
final RoleModel appRole1 = appRoleApplication.addRole("APP_ROLE_1");
final RoleModel appRole2 = appRoleApplication.addRole("APP_ROLE_2");
@@ -121,7 +121,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.secret("password"));
+ realm.updateCredential(appCompositeApplication.getAgent(), 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/oauth/AuthorizationCodeTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
index f35888228f..cf7765ee4c 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
@@ -82,7 +82,7 @@ public class AuthorizationCodeTest {
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
for (ApplicationModel app : appRealm.getApplications()) {
if (app.getName().equals("test-app")) {
- UserModel client = app.getApplicationUser();
+ UserModel client = app.getAgent();
client.addRedirectUri(oauth.getRedirectUri());
}
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java
index ee60bd5b90..8e973c117b 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthRedirectUriTest.java
@@ -48,7 +48,7 @@ public class OAuthRedirectUriTest {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
ApplicationModel app = appRealm.getApplicationNameMap().get("test-app");
- app.getApplicationUser().addRedirectUri("http://localhost:8081/app");
+ app.getAgent().addRedirectUri("http://localhost:8081/app");
}
});
@@ -81,7 +81,7 @@ public class OAuthRedirectUriTest {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.getApplicationNameMap().get("test-app").getApplicationUser().addRedirectUri("http://localhost:8081/app2");
+ appRealm.getApplicationNameMap().get("test-app").getAgent().addRedirectUri("http://localhost:8081/app2");
}
});
@@ -95,7 +95,7 @@ public class OAuthRedirectUriTest {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.getApplicationNameMap().get("test-app").getApplicationUser().removeRedirectUri("http://localhost:8081/app2");
+ appRealm.getApplicationNameMap().get("test-app").getAgent().removeRedirectUri("http://localhost:8081/app2");
}
});
}
@@ -106,7 +106,7 @@ public class OAuthRedirectUriTest {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.getApplicationNameMap().get("test-app").getApplicationUser().removeRedirectUri("http://localhost:8081/app");
+ appRealm.getApplicationNameMap().get("test-app").getAgent().removeRedirectUri("http://localhost:8081/app");
}
});
@@ -120,7 +120,7 @@ public class OAuthRedirectUriTest {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.getApplicationNameMap().get("test-app").getApplicationUser().addRedirectUri("http://localhost:8081/app");
+ appRealm.getApplicationNameMap().get("test-app").getAgent().addRedirectUri("http://localhost:8081/app");
}
});
}
@@ -131,7 +131,7 @@ public class OAuthRedirectUriTest {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.getApplicationNameMap().get("test-app").getApplicationUser().removeRedirectUri("http://localhost:8081/app");
+ appRealm.getApplicationNameMap().get("test-app").getAgent().removeRedirectUri("http://localhost:8081/app");
}
});
@@ -144,7 +144,7 @@ public class OAuthRedirectUriTest {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
- appRealm.getApplicationNameMap().get("test-app").getApplicationUser().addRedirectUri("http://localhost:8081/app");
+ appRealm.getApplicationNameMap().get("test-app").getAgent().addRedirectUri("http://localhost:8081/app");
}
});
}