commit
a8e588216b
72 changed files with 1649 additions and 497 deletions
|
@ -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 : {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
|
||||
<div id="content-area" class="col-md-9" role="main">
|
||||
<ul class="nav nav-tabs nav-tabs-pf" data-ng-show="!create">
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}">Settings</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/installation">Installation</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
|
||||
</ul>
|
||||
<div id="content">
|
||||
<ol class="breadcrumb" data-ng-hide="create">
|
||||
<li><a href="#/realms/{{realm.realm}}">{{realm.realm}}</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications">Applications</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}">{{application.name}}</a></li>
|
||||
<li class="active">Claims</li>
|
||||
</ol>
|
||||
<h2 data-ng-hide="create"><span>{{application.name}}</span> Allowed Claims</h2>
|
||||
<form class="form-horizontal" name="claimForm">
|
||||
<div data-ng-include data-src="'partials/claims.html'"></div>
|
||||
<div class="pull-right form-actions" data-ng-show="access.manageApplications">
|
||||
<button kc-reset data-ng-show="changed">Clear changes</button>
|
||||
<button kc-save data-ng-show="changed">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -5,6 +5,7 @@
|
|||
<li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/installation">Installation</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/installation">Installation</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/credentials">Credentials</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/installation">Installation</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/installation">Installation</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/installation">Installation</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/credentials">Credentials</a></li>
|
||||
<li><a href="#">Installation</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/installation">Installation</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/roles">Roles</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/scope-mappings">Scope</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/applications/{{application.name}}/sessions">Sessions</a></li>
|
||||
</ul>
|
||||
|
|
62
admin-ui/src/main/resources/META-INF/resources/admin/partials/claims.html
Executable file
62
admin-ui/src/main/resources/META-INF/resources/admin/partials/claims.html
Executable file
|
@ -0,0 +1,62 @@
|
|||
<fieldset class="border-top">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="username">Username</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="claims.username" name="username" id="username" onoffswitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="claimName">Name</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="claims.name" name="claimName" id="claimName" onoffswitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="email">Email</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="claims.email" name="email" id="email" onoffswitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="gender">Gender</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="claims.gender" name="gender" id="gender" onoffswitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="address">Address</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="claims.address" name="address" id="address" onoffswitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="locale">Locale</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="claims.locale" name="locale" id="locale" onoffswitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="phone">Phone</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="claims.phone" name="phone" id="phone" onoffswitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="profile">Profile URL</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="claims.profile" name="profile" id="profile" onoffswitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="picture">Picture URL</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="claims.picture" name="picture" id="picture" onoffswitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="website">Website</label>
|
||||
<div class="col-sm-4">
|
||||
<input ng-model="claims.website" name="website" id="website" onoffswitch />
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
|
@ -0,0 +1,20 @@
|
|||
<div class="bs-sidebar col-md-3 clearfix" data-ng-include data-src="'partials/realm-menu.html'"></div>
|
||||
<div id="content-area" class="col-md-9" role="main">
|
||||
<ul class="nav nav-tabs nav-tabs-pf">
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}">Settings</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/credentials">Credentials</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/installation">Installation</a></li>
|
||||
</ul>
|
||||
<div id="content">
|
||||
<h2 data-ng-hide="create"><span>{{oauth.name}}</span> Allowed Claims</h2>
|
||||
<form class="form-horizontal" name="claimForm">
|
||||
<div data-ng-include data-src="'partials/claims.html'"></div>
|
||||
<div class="pull-right form-actions" data-ng-show="access.manageClients">
|
||||
<button kc-reset data-ng-show="changed">Clear changes</button>
|
||||
<button kc-save data-ng-show="changed">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -3,6 +3,7 @@
|
|||
<ul class="nav nav-tabs nav-tabs-pf">
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}">Settings</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/installation">Installation</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<ul class="nav nav-tabs nav-tabs-pf" data-ng-show="!create">
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}">Settings</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/installation">Installation</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<ul class="nav nav-tabs nav-tabs-pf" data-ng-show="!create">
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}">Settings</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/claims">Claims</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/scope-mappings">Scope</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/installation">Installation</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<ul class="nav nav-tabs nav-tabs-pf" data-ng-show="!create">
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}">Settings</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/credentials">Credentials</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/claims">Claims</a></li>
|
||||
<li class="active"><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/scope-mappings">Scope</a></li>
|
||||
<li><a href="#/realms/{{realm.realm}}/oauth-clients/{{oauth.id}}/installation">Installation</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.util.Set;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class AccessToken extends JsonWebToken {
|
||||
public class AccessToken extends IDToken {
|
||||
public static class Access {
|
||||
@JsonProperty("roles")
|
||||
protected Set<String> roles;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
306
core/src/main/java/org/keycloak/representations/IDToken.java
Executable file
306
core/src/main/java/org/keycloak/representations/IDToken.java
Executable file
|
@ -0,0 +1,306 @@
|
|||
package org.keycloak.representations;
|
||||
|
||||
import org.codehaus.jackson.annotate.JsonProperty;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @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;
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ public class ApplicationRepresentation {
|
|||
protected String[] defaultRoles;
|
||||
protected List<String> redirectUris;
|
||||
protected List<String> 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;
|
||||
}
|
||||
}
|
||||
|
|
98
core/src/main/java/org/keycloak/representations/idm/ClaimRepresentation.java
Executable file
98
core/src/main/java/org/keycloak/representations/idm/ClaimRepresentation.java
Executable file
|
@ -0,0 +1,98 @@
|
|||
package org.keycloak.representations.idm;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @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;
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ public class OAuthClientRepresentation {
|
|||
protected List<String> webOrigins;
|
||||
protected boolean enabled;
|
||||
protected List<CredentialRepresentation> credentials;
|
||||
protected ClaimRepresentation claims;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
|
@ -70,4 +71,12 @@ public class OAuthClientRepresentation {
|
|||
public void setCredentials(List<CredentialRepresentation> credentials) {
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
public ClaimRepresentation getClaims() {
|
||||
return claims;
|
||||
}
|
||||
|
||||
public void setClaims(ClaimRepresentation claims) {
|
||||
this.claims = claims;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
Password and TOTP support (via Google Authenticator). Client cert auth coming soon.
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
Pluggable theme and style support for user facing screens.
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
OAuth Bearer token auth for REST Services
|
||||
</listitem>
|
||||
|
@ -60,7 +64,7 @@
|
|||
Deployable as a WAR, appliance, or on Openshift.
|
||||
</listitem>
|
||||
<listitem>
|
||||
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
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
|
|
@ -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<String> getCustomers(HttpServletRequest req) throws Failure {
|
||||
KeycloakAuthenticatedSession session = (KeycloakAuthenticatedSession) req.getAttribute(KeycloakAuthenticatedSession.class.getName());
|
||||
|
||||
|
|
|
@ -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" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Customer View Page</title>
|
||||
|
@ -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);
|
||||
%>
|
||||
<p>Goto: <a href="http://localhost:8080/product-portal">products</a> | <a href="<%=logoutUri%>">logout</a> | <a
|
||||
href="<%=acctUri%>">manage acct</a></p>
|
||||
User <b><%=request.getUserPrincipal().getName()%>
|
||||
Servlet User Principal <b><%=request.getUserPrincipal().getName()%>
|
||||
</b> made this request.
|
||||
<p><b>Caller IDToken values</b> (<i>You can specify what is returned in IDToken in the customer-portal claims page in the admin console</i>:</p>
|
||||
<p>Username: <%=idToken.getPreferredUsername()%></p>
|
||||
<p>Email: <%=idToken.getEmail()%></p>
|
||||
<p>Full Name: <%=idToken.getName()%></p>
|
||||
<p>First: <%=idToken.getGivenName()%></p>
|
||||
<p>Last: <%=idToken.getFamilyName()%></p>
|
||||
<h2>Customer Listing</h2>
|
||||
<%
|
||||
java.util.List<String> list = null;
|
||||
|
|
94
forms/login-api/src/main/java/org/keycloak/login/LoginForms.java
Normal file → Executable file
94
forms/login-api/src/main/java/org/keycloak/login/LoginForms.java
Normal file → Executable file
|
@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
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<RoleModel> realmRolesRequested, MultivaluedMap<String,RoleModel> 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<String, String> 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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
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<RoleModel> realmRolesRequested, MultivaluedMap<String,RoleModel> 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<String, String> formData);
|
||||
|
||||
public LoginForms setStatus(Response.Status status);
|
||||
|
||||
}
|
||||
|
|
546
forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginForms.java
Normal file → Executable file
546
forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginForms.java
Normal file → Executable file
|
@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
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<RoleModel> realmRolesRequested;
|
||||
private MultivaluedMap<String, RoleModel> resourceRolesRequested;
|
||||
|
||||
public static enum MessageType {SUCCESS, WARNING, ERROR}
|
||||
|
||||
private MessageType messageType = MessageType.ERROR;
|
||||
|
||||
private MultivaluedMap<String, String> 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<String, String> 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<String, Object> attributes = new HashMap<String, Object>();
|
||||
|
||||
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<String, String> 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<RoleModel> realmRolesRequested, MultivaluedMap<String, RoleModel> 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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
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<RoleModel> realmRolesRequested;
|
||||
private MultivaluedMap<String, RoleModel> resourceRolesRequested;
|
||||
|
||||
public static enum MessageType {SUCCESS, WARNING, ERROR}
|
||||
|
||||
private MessageType messageType = MessageType.ERROR;
|
||||
|
||||
private MultivaluedMap<String, String> 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<String, String> 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<String, Object> attributes = new HashMap<String, Object>();
|
||||
|
||||
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<String, String> 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<RoleModel> realmRolesRequested, MultivaluedMap<String, RoleModel> resourceRolesRequested) {
|
||||
this.realmRolesRequested = realmRolesRequested;
|
||||
this.resourceRolesRequested = resourceRolesRequested;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginForms setStatus(Response.Status status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
|
||||
*/
|
||||
public class OAuthGrantBean {
|
||||
|
||||
private List<RoleModel> realmRolesRequested;
|
||||
private MultivaluedMap<String, RoleModel> resourceRolesRequested;
|
||||
private String code;
|
||||
private UserModel client;
|
||||
private String oAuthCode;
|
||||
private String action;
|
||||
|
||||
public OAuthGrantBean(String code, UserModel client, List<RoleModel> realmRolesRequested, MultivaluedMap<String, RoleModel> resourceRolesRequested) {
|
||||
this.code = code;
|
||||
this.client = client;
|
||||
this.realmRolesRequested = realmRolesRequested;
|
||||
this.resourceRolesRequested = resourceRolesRequested;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public MultivaluedMap<String, RoleModel> getResourceRolesRequested() {
|
||||
return resourceRolesRequested;
|
||||
}
|
||||
|
||||
public List<RoleModel> 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 <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
|
||||
*/
|
||||
public class OAuthGrantBean {
|
||||
|
||||
private List<RoleModel> realmRolesRequested;
|
||||
private MultivaluedMap<String, RoleModel> resourceRolesRequested;
|
||||
private String code;
|
||||
private UserModel client;
|
||||
private String oAuthCode;
|
||||
private String action;
|
||||
|
||||
public OAuthGrantBean(String code, UserModel client, List<RoleModel> realmRolesRequested, MultivaluedMap<String, RoleModel> resourceRolesRequested) {
|
||||
this.code = code;
|
||||
this.client = client;
|
||||
this.realmRolesRequested = realmRolesRequested;
|
||||
this.resourceRolesRequested = resourceRolesRequested;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public MultivaluedMap<String, RoleModel> getResourceRolesRequested() {
|
||||
return resourceRolesRequested;
|
||||
}
|
||||
|
||||
public List<RoleModel> getRealmRolesRequested() {
|
||||
return realmRolesRequested;
|
||||
}
|
||||
|
||||
public String getClient() {
|
||||
return client.getLoginName();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -7,13 +7,9 @@ import java.util.Set;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @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<RoleModel> getApplicationScopeMappings(UserModel user);
|
||||
|
||||
void addScope(RoleModel role);
|
||||
|
||||
}
|
||||
|
|
50
model/api/src/main/java/org/keycloak/models/ClaimMask.java
Executable file
50
model/api/src/main/java/org/keycloak/models/ClaimMask.java
Executable file
|
@ -0,0 +1,50 @@
|
|||
package org.keycloak.models;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @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;
|
||||
}
|
||||
|
||||
}
|
15
model/api/src/main/java/org/keycloak/models/ClientModel.java
Executable file
15
model/api/src/main/java/org/keycloak/models/ClientModel.java
Executable file
|
@ -0,0 +1,15 @@
|
|||
package org.keycloak.models;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ClientModel {
|
||||
long getAllowedClaimsMask();
|
||||
|
||||
void setAllowedClaimsMask(long mask);
|
||||
|
||||
UserModel getAgent();
|
||||
|
||||
String getId();
|
||||
}
|
|
@ -4,8 +4,6 @@ package org.keycloak.models;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface OAuthClientModel {
|
||||
String getId();
|
||||
public interface OAuthClientModel extends ClientModel {
|
||||
|
||||
UserModel getOAuthAgent();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
10
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
Normal file → Executable file
10
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/ApplicationEntity.java
Normal file → Executable file
|
@ -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<String> defaultRoles = new ArrayList<String>();
|
||||
|
@ -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;
|
||||
|
|
10
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
Normal file → Executable file
10
model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/entities/OAuthClientEntity.java
Normal file → Executable file
|
@ -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
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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()));
|
||||
|
|
2
model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
Normal file → Executable file
2
model/tests/src/test/java/org/keycloak/model/test/CompositeRolesModelTest.java
Normal file → Executable file
|
@ -60,7 +60,7 @@ public class CompositeRolesModelTest extends AbstractModelTest {
|
|||
ApplicationModel application = realm.getApplicationByName(applicationName);
|
||||
|
||||
Set<RoleModel> roleMappings = realm.getRoleMappings(user);
|
||||
Set<RoleModel> scopeMappings = realm.getScopeMappings(application.getApplicationUser());
|
||||
Set<RoleModel> scopeMappings = realm.getScopeMappings(application.getAgent());
|
||||
Set<RoleModel> appRoles = application.getRoles();
|
||||
if (appRoles != null) scopeMappings.addAll(appRoles);
|
||||
|
||||
|
|
|
@ -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<String> redirectUris = rep.getRedirectUris();
|
||||
if (redirectUris != null) {
|
||||
resource.getApplicationUser().setRedirectUris(new HashSet<String>(redirectUris));
|
||||
resource.getAgent().setRedirectUris(new HashSet<String>(redirectUris));
|
||||
}
|
||||
|
||||
List<String> webOrigins = rep.getWebOrigins();
|
||||
if (webOrigins != null) {
|
||||
resource.getApplicationUser().setWebOrigins(new HashSet<String>(webOrigins));
|
||||
resource.getAgent().setWebOrigins(new HashSet<String>(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<String> redirectUris = applicationModel.getApplicationUser().getRedirectUris();
|
||||
Set<String> redirectUris = applicationModel.getAgent().getRedirectUris();
|
||||
if (redirectUris != null) {
|
||||
rep.setRedirectUris(new LinkedList<String>(redirectUris));
|
||||
}
|
||||
|
||||
Set<String> webOrigins = applicationModel.getApplicationUser().getWebOrigins();
|
||||
Set<String> webOrigins = applicationModel.getAgent().getWebOrigins();
|
||||
if (webOrigins != null) {
|
||||
rep.setWebOrigins(new LinkedList<String>(webOrigins));
|
||||
}
|
||||
|
@ -240,7 +251,7 @@ public class ApplicationManager {
|
|||
rep.setResource(applicationModel.getName());
|
||||
|
||||
Map<String, String> creds = new HashMap<String, String>();
|
||||
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(" <auth-server-url>").append(baseUri.toString()).append("</auth-server-url>\n");
|
||||
buffer.append(" <ssl-not-required>").append(realmModel.isSslNotRequired()).append("</ssl-not-required>\n");
|
||||
buffer.append(" <resource>").append(applicationModel.getName()).append("</resource>\n");
|
||||
String cred = realmModel.getSecret(applicationModel.getApplicationUser()).getValue();
|
||||
String cred = realmModel.getSecret(applicationModel.getAgent()).getValue();
|
||||
buffer.append(" <credential name=\"secret\">").append(cred).append("</credential>\n");
|
||||
buffer.append("</secure-deployment>\n");
|
||||
return buffer.toString();
|
||||
|
|
66
services/src/main/java/org/keycloak/services/managers/ClaimManager.java
Executable file
66
services/src/main/java/org/keycloak/services/managers/ClaimManager.java
Executable file
|
@ -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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String> redirectUris = rep.getRedirectUris();
|
||||
if (redirectUris != null) {
|
||||
model.getOAuthAgent().setRedirectUris(new HashSet<String>(redirectUris));
|
||||
model.getAgent().setRedirectUris(new HashSet<String>(redirectUris));
|
||||
}
|
||||
|
||||
List<String> webOrigins = rep.getWebOrigins();
|
||||
if (webOrigins != null) {
|
||||
model.getOAuthAgent().setWebOrigins(new HashSet<String>(webOrigins));
|
||||
model.getAgent().setWebOrigins(new HashSet<String>(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<String> redirectUris = model.getOAuthAgent().getRedirectUris();
|
||||
rep.setName(model.getAgent().getLoginName());
|
||||
rep.setEnabled(model.getAgent().isEnabled());
|
||||
Set<String> redirectUris = model.getAgent().getRedirectUris();
|
||||
if (redirectUris != null) {
|
||||
rep.setRedirectUris(new LinkedList<String>(redirectUris));
|
||||
}
|
||||
|
||||
Set<String> webOrigins = model.getOAuthAgent().getWebOrigins();
|
||||
Set<String> webOrigins = model.getAgent().getWebOrigins();
|
||||
if (webOrigins != null) {
|
||||
rep.setWebOrigins(new LinkedList<String>(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<String, String> creds = new HashMap<String, String>();
|
||||
creds.put(CredentialRepresentation.SECRET, realmModel.getSecret(model.getOAuthAgent()).getValue());
|
||||
creds.put(CredentialRepresentation.SECRET, realmModel.getSecret(model.getAgent()).getValue());
|
||||
rep.setCredentials(creds);
|
||||
|
||||
return rep;
|
||||
|
|
|
@ -255,7 +255,7 @@ public class RealmManager {
|
|||
if (rep.getApplications() != null) {
|
||||
Map<String, ApplicationModel> 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<String, OAuthClientModel> 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;
|
||||
}
|
||||
|
|
|
@ -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<RoleModel>(), new MultivaluedHashMap<String, RoleModel>());
|
||||
}
|
||||
|
||||
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<RoleModel> realmRolesRequested, MultivaluedMap<String, RoleModel> resourceRolesRequested) {
|
||||
AccessScope scopeMap = null;
|
||||
|
@ -196,6 +206,7 @@ public class TokenManager {
|
|||
|
||||
Set<RoleModel> roleMappings = realm.getRoleMappings(user);
|
||||
Set<RoleModel> scopeMappings = realm.getScopeMappings(client);
|
||||
ClientModel claimRequesterModel = getClaimRequester(realm, client);
|
||||
ApplicationModel clientApp = realm.getApplicationByName(client.getLoginName());
|
||||
Set<RoleModel> 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<String> 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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @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);
|
||||
}
|
||||
}
|
|
@ -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 <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()).
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue