Merge pull request #589 from patriot1burke/master

app full scope
This commit is contained in:
Bill Burke 2014-08-04 16:26:51 -04:00
commit ea0ceeb65d
26 changed files with 183 additions and 30 deletions

View file

@ -21,6 +21,7 @@ public class ApplicationRepresentation {
protected Integer notBefore; protected Integer notBefore;
protected Boolean bearerOnly; protected Boolean bearerOnly;
protected Boolean publicClient; protected Boolean publicClient;
protected Boolean fullScopeAllowed;
public String getId() { public String getId() {
@ -134,4 +135,12 @@ public class ApplicationRepresentation {
public void setPublicClient(Boolean publicClient) { public void setPublicClient(Boolean publicClient) {
this.publicClient = publicClient; this.publicClient = publicClient;
} }
public Boolean isFullScopeAllowed() {
return fullScopeAllowed;
}
public void setFullScopeAllowed(Boolean fullScopeAllowed) {
this.fullScopeAllowed = fullScopeAllowed;
}
} }

View file

@ -17,6 +17,7 @@ public class OAuthClientRepresentation {
protected Integer notBefore; protected Integer notBefore;
protected Boolean publicClient; protected Boolean publicClient;
protected Boolean directGrantsOnly; protected Boolean directGrantsOnly;
protected Boolean fullScopeAllowed;
public String getId() { public String getId() {
@ -98,4 +99,13 @@ public class OAuthClientRepresentation {
public void setDirectGrantsOnly(Boolean directGrantsOnly) { public void setDirectGrantsOnly(Boolean directGrantsOnly) {
this.directGrantsOnly = directGrantsOnly; this.directGrantsOnly = directGrantsOnly;
} }
public Boolean isFullScopeAllowed() {
return fullScopeAllowed;
}
public void setFullScopeAllowed(Boolean fullScopeAllowed) {
this.fullScopeAllowed = fullScopeAllowed;
}
} }

View file

@ -88,7 +88,12 @@
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<!-- authentication api --> <!-- ldap federation api -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-ldap-federation</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.picketlink</groupId> <groupId>org.picketlink</groupId>
<artifactId>picketlink-common</artifactId> <artifactId>picketlink-common</artifactId>

View file

@ -11,14 +11,18 @@
Authentication SPI has been removed and rewritten. The new SPI is UserFederationProvider and is Authentication SPI has been removed and rewritten. The new SPI is UserFederationProvider and is
more flexible. more flexible.
</listitem> </listitem>
<listitem>
DB Schema has changed again.
</listitem>
<listitem> <listitem>
<literal>ssl-not-required</literal> property in adapter config has been removed. Replaced with <literal>ssl-not-required</literal> property in adapter config has been removed. Replaced with
<literal>ssl-required</literal>, valid values are <literal>all</literal> (require SSL for all requests), <literal>external</literal> <literal>ssl-required</literal>, valid values are <literal>all</literal> (require SSL for all requests), <literal>external</literal>
(require SSL only for external request) and <literal>none</literal> (SSL not required). (require SSL only for external request) and <literal>none</literal> (SSL not required).
</listitem> </listitem>
<listitem>
DB Schema has changed again.
</listitem>
<listitem>
Created applications now have a full scope by default. This means that you don't have to configure
the scope of an application if you don't want to.
</listitem>
</itemizedlist> </itemizedlist>
</sect1> </sect1>
<sect1> <sect1>

View file

@ -92,28 +92,7 @@
{ {
"client": "third-party", "client": "third-party",
"roles": ["user"] "roles": ["user"]
},
{
"client": "customer-portal",
"roles": ["user", "admin" ]
},
{
"client": "customer-portal-js",
"roles": ["user"]
},
{
"client": "customer-portal-cli",
"roles": ["user"]
},
{
"client": "angular-product",
"roles": ["user"]
},
{
"client": "product-portal",
"roles": ["user", "admin" ]
} }
], ],
"applications": [ "applications": [
{ {

View file

@ -348,11 +348,12 @@ module.controller('ApplicationDetailCtrl', function($scope, realm, application,
}); });
module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, application, applications, module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm, application, applications,
Application,
ApplicationRealmScopeMapping, ApplicationApplicationScopeMapping, ApplicationRole, ApplicationRealmScopeMapping, ApplicationApplicationScopeMapping, ApplicationRole,
ApplicationAvailableRealmScopeMapping, ApplicationAvailableApplicationScopeMapping, ApplicationAvailableRealmScopeMapping, ApplicationAvailableApplicationScopeMapping,
ApplicationCompositeRealmScopeMapping, ApplicationCompositeApplicationScopeMapping) { ApplicationCompositeRealmScopeMapping, ApplicationCompositeApplicationScopeMapping) {
$scope.realm = realm; $scope.realm = realm;
$scope.application = application; $scope.application = angular.copy(application);
$scope.selectedRealmRoles = []; $scope.selectedRealmRoles = [];
$scope.selectedRealmMappings = []; $scope.selectedRealmMappings = [];
$scope.realmMappings = []; $scope.realmMappings = [];
@ -364,6 +365,21 @@ module.controller('ApplicationScopeMappingCtrl', function($scope, $http, realm,
$scope.applicationMappings = []; $scope.applicationMappings = [];
$scope.dummymodel = []; $scope.dummymodel = [];
$scope.changeFullScopeAllowed = function() {
console.log('change full scope');
Application.update({
realm : realm.realm,
application : application.name
}, $scope.application, function() {
$scope.changed = false;
application = angular.copy($scope.application);
updateRealmRoles();
});
}
function updateRealmRoles() { function updateRealmRoles() {
$scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.name}); $scope.realmRoles = ApplicationAvailableRealmScopeMapping.query({realm : realm.realm, application : application.name});
$scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name}); $scope.realmMappings = ApplicationRealmScopeMapping.query({realm : realm.realm, application : application.name});

View file

@ -183,11 +183,12 @@ module.controller('OAuthClientDetailCtrl', function($scope, realm, oauth, OAuthC
}); });
module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, oauth, applications, module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm, oauth, applications,
OAuthClient,
OAuthClientRealmScopeMapping, OAuthClientApplicationScopeMapping, ApplicationRole, OAuthClientRealmScopeMapping, OAuthClientApplicationScopeMapping, ApplicationRole,
OAuthClientAvailableRealmScopeMapping, OAuthClientAvailableApplicationScopeMapping, OAuthClientAvailableRealmScopeMapping, OAuthClientAvailableApplicationScopeMapping,
OAuthClientCompositeRealmScopeMapping, OAuthClientCompositeApplicationScopeMapping) { OAuthClientCompositeRealmScopeMapping, OAuthClientCompositeApplicationScopeMapping) {
$scope.realm = realm; $scope.realm = realm;
$scope.oauth = oauth; $scope.oauth = angular.copy(oauth);
$scope.selectedRealmRoles = []; $scope.selectedRealmRoles = [];
$scope.selectedRealmMappings = []; $scope.selectedRealmMappings = [];
$scope.realmMappings = []; $scope.realmMappings = [];
@ -199,6 +200,19 @@ module.controller('OAuthClientScopeMappingCtrl', function($scope, $http, realm,
$scope.applicationMappings = []; $scope.applicationMappings = [];
$scope.dummymodel = []; $scope.dummymodel = [];
$scope.changeFullScopeAllowed = function() {
console.log('change full scope');
OAuthClient.update({
realm : realm.realm,
oauth : oauth.name
}, $scope.oauth, function() {
$scope.changed = false;
oauth = angular.copy($scope.oauth);
});
}
function updateRealmRoles() { function updateRealmRoles() {
$scope.realmRoles = OAuthClientAvailableRealmScopeMapping.query({realm : realm.realm, oauth : oauth.name}); $scope.realmRoles = OAuthClientAvailableRealmScopeMapping.query({realm : realm.realm, oauth : oauth.name});
$scope.realmMappings = OAuthClientRealmScopeMapping.query({realm : realm.realm, oauth : oauth.name}); $scope.realmMappings = OAuthClientRealmScopeMapping.query({realm : realm.realm, oauth : oauth.name});

View file

@ -21,7 +21,18 @@
</ol> </ol>
<h2><span>{{application.name}}</span> Scope Mappings</h2> <h2><span>{{application.name}}</span> Scope Mappings</h2>
<p class="subtitle"></p> <p class="subtitle"></p>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageApplications"> <form class="form-horizontal" name="allowScope" novalidate kc-read-only="!access.manageApplications">
<fieldset class="border-top">
<div class="form-group">
<label class="col-sm-2 control-label" for="fullScopeAllowed">Full Scope Allowed</label>
<div class="col-sm-4">
<input ng-model="application.fullScopeAllowed" ng-click="changeFullScopeAllowed()" name="fullScopeAllowed" id="fullScopeAllowed" onoffswitch />
</div>
</div>
</fieldset>
</form>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageApplications" data-ng-show="!application.fullScopeAllowed">
<fieldset> <fieldset>
<legend><span class="text">Realm Roles</span></legend> <legend><span class="text">Realm Roles</span></legend>
<div class="form-group col-sm-10"> <div class="form-group col-sm-10">

View file

@ -19,7 +19,17 @@
</ol> </ol>
<h2><span>{{oauth.name}}</span> Scope Mappings</h2> <h2><span>{{oauth.name}}</span> Scope Mappings</h2>
<p class="subtitle"></p> <p class="subtitle"></p>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients"> <form class="form-horizontal" name="allowScope" novalidate kc-read-only="!access.manageClients">
<fieldset class="border-top">
<div class="form-group">
<label class="col-sm-2 control-label" for="fullScopeAllowed">Full Scope Allowed</label>
<div class="col-sm-4">
<input ng-model="oauth.fullScopeAllowed" ng-click="changeFullScopeAllowed()" name="fullScopeAllowed" id="fullScopeAllowed" onoffswitch />
</div>
</div>
</fieldset>
</form>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients" data-ng-show="!oauth.fullScopeAllowed">
<fieldset> <fieldset>
<legend><span class="text">Realm Roles</span></legend> <legend><span class="text">Realm Roles</span></legend>
<div class="form-group col-sm-10"> <div class="form-group col-sm-10">

View file

@ -50,6 +50,9 @@ public interface ClientModel {
String getSecret(); String getSecret();
public void setSecret(String secret); public void setSecret(String secret);
boolean isFullScopeAllowed();
void setFullScopeAllowed(boolean value);
boolean isPublicClient(); boolean isPublicClient();
void setPublicClient(boolean flag); void setPublicClient(boolean flag);

View file

@ -14,6 +14,7 @@ public class ClientEntity extends AbstractIdentifiableEntity {
private long allowedClaimsMask; private long allowedClaimsMask;
private int notBefore; private int notBefore;
private boolean publicClient; private boolean publicClient;
private boolean fullScopeAllowed;
private String realmId; private String realmId;
@ -100,4 +101,12 @@ public class ClientEntity extends AbstractIdentifiableEntity {
public void setScopeIds(List<String> scopeIds) { public void setScopeIds(List<String> scopeIds) {
this.scopeIds = scopeIds; this.scopeIds = scopeIds;
} }
public boolean isFullScopeAllowed() {
return fullScopeAllowed;
}
public void setFullScopeAllowed(boolean fullScopeAllowed) {
this.fullScopeAllowed = fullScopeAllowed;
}
} }

View file

@ -91,6 +91,7 @@ public final class KeycloakModelUtils {
public static ApplicationModel createApplication(RealmModel realm, String name) { public static ApplicationModel createApplication(RealmModel realm, String name) {
ApplicationModel app = realm.addApplication(name); ApplicationModel app = realm.addApplication(name);
generateSecret(app); generateSecret(app);
app.setFullScopeAllowed(true);
return app; return app;
} }

View file

@ -214,6 +214,7 @@ public class ModelToRepresentation {
rep.setEnabled(applicationModel.isEnabled()); rep.setEnabled(applicationModel.isEnabled());
rep.setAdminUrl(applicationModel.getManagementUrl()); rep.setAdminUrl(applicationModel.getManagementUrl());
rep.setPublicClient(applicationModel.isPublicClient()); rep.setPublicClient(applicationModel.isPublicClient());
rep.setFullScopeAllowed(applicationModel.isFullScopeAllowed());
rep.setBearerOnly(applicationModel.isBearerOnly()); rep.setBearerOnly(applicationModel.isBearerOnly());
rep.setSurrogateAuthRequired(applicationModel.isSurrogateAuthRequired()); rep.setSurrogateAuthRequired(applicationModel.isSurrogateAuthRequired());
rep.setBaseUrl(applicationModel.getBaseUrl()); rep.setBaseUrl(applicationModel.getBaseUrl());
@ -242,6 +243,7 @@ public class ModelToRepresentation {
rep.setName(model.getClientId()); rep.setName(model.getClientId());
rep.setEnabled(model.isEnabled()); rep.setEnabled(model.isEnabled());
rep.setPublicClient(model.isPublicClient()); rep.setPublicClient(model.isPublicClient());
rep.setFullScopeAllowed(model.isFullScopeAllowed());
rep.setDirectGrantsOnly(model.isDirectGrantsOnly()); rep.setDirectGrantsOnly(model.isDirectGrantsOnly());
Set<String> redirectUris = model.getRedirectUris(); Set<String> redirectUris = model.getRedirectUris();
if (redirectUris != null) { if (redirectUris != null) {

View file

@ -353,6 +353,8 @@ public class RepresentationToModel {
applicationModel.setBaseUrl(resourceRep.getBaseUrl()); applicationModel.setBaseUrl(resourceRep.getBaseUrl());
if (resourceRep.isBearerOnly() != null) applicationModel.setBearerOnly(resourceRep.isBearerOnly()); if (resourceRep.isBearerOnly() != null) applicationModel.setBearerOnly(resourceRep.isBearerOnly());
if (resourceRep.isPublicClient() != null) applicationModel.setPublicClient(resourceRep.isPublicClient()); if (resourceRep.isPublicClient() != null) applicationModel.setPublicClient(resourceRep.isPublicClient());
if (resourceRep.isFullScopeAllowed() != null) applicationModel.setFullScopeAllowed(resourceRep.isFullScopeAllowed());
else applicationModel.setFullScopeAllowed(true);
applicationModel.updateApplication(); applicationModel.updateApplication();
if (resourceRep.getNotBefore() != null) { if (resourceRep.getNotBefore() != null) {
@ -415,6 +417,7 @@ public class RepresentationToModel {
if (rep.isEnabled() != null) resource.setEnabled(rep.isEnabled()); if (rep.isEnabled() != null) resource.setEnabled(rep.isEnabled());
if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly()); if (rep.isBearerOnly() != null) resource.setBearerOnly(rep.isBearerOnly());
if (rep.isPublicClient() != null) resource.setPublicClient(rep.isPublicClient()); if (rep.isPublicClient() != null) resource.setPublicClient(rep.isPublicClient());
if (rep.isFullScopeAllowed() != null) resource.setFullScopeAllowed(rep.isFullScopeAllowed());
if (rep.getAdminUrl() != null) resource.setManagementUrl(rep.getAdminUrl()); if (rep.getAdminUrl() != null) resource.setManagementUrl(rep.getAdminUrl());
if (rep.getBaseUrl() != null) resource.setBaseUrl(rep.getBaseUrl()); if (rep.getBaseUrl() != null) resource.setBaseUrl(rep.getBaseUrl());
if (rep.isSurrogateAuthRequired() != null) resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired()); if (rep.isSurrogateAuthRequired() != null) resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
@ -521,6 +524,7 @@ public class RepresentationToModel {
if (rep.getName() != null) model.setClientId(rep.getName()); if (rep.getName() != null) model.setClientId(rep.getName());
if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled()); if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled());
if (rep.isPublicClient() != null) model.setPublicClient(rep.isPublicClient()); if (rep.isPublicClient() != null) model.setPublicClient(rep.isPublicClient());
if (rep.isFullScopeAllowed() != null) model.setFullScopeAllowed(rep.isFullScopeAllowed());
if (rep.isDirectGrantsOnly() != null) model.setDirectGrantsOnly(rep.isDirectGrantsOnly()); if (rep.isDirectGrantsOnly() != null) model.setDirectGrantsOnly(rep.isDirectGrantsOnly());
if (rep.getClaims() != null) { if (rep.getClaims() != null) {
setClaims(model, rep.getClaims()); setClaims(model, rep.getClaims());

View file

@ -123,6 +123,19 @@ public abstract class ClientAdapter implements ClientModel {
updatedClient.setPublicClient(flag); updatedClient.setPublicClient(flag);
} }
@Override
public boolean isFullScopeAllowed() {
if (updatedClient != null) return updatedClient.isFullScopeAllowed();
return cachedClient.isFullScopeAllowed();
}
@Override
public void setFullScopeAllowed(boolean value) {
getDelegateForUpdate();
updatedClient.setFullScopeAllowed(value);
}
public boolean isDirectGrantsOnly() { public boolean isDirectGrantsOnly() {
if (updatedClient != null) return updatedClient.isDirectGrantsOnly(); if (updatedClient != null) return updatedClient.isDirectGrantsOnly();
return cachedClient.isDirectGrantsOnly(); return cachedClient.isDirectGrantsOnly();
@ -171,7 +184,7 @@ public abstract class ClientAdapter implements ClientModel {
public boolean hasScope(RoleModel role) { public boolean hasScope(RoleModel role) {
if (updatedClient != null) return updatedClient.hasScope(role); if (updatedClient != null) return updatedClient.hasScope(role);
if (cachedClient.getScope().contains(role.getId())) return true; if (cachedClient.isFullScopeAllowed() || cachedClient.getScope().contains(role.getId())) return true;
Set<RoleModel> roles = getScopeMappings(); Set<RoleModel> roles = getScopeMappings();

View file

@ -22,6 +22,7 @@ public class CachedClient {
protected boolean enabled; protected boolean enabled;
protected String secret; protected String secret;
protected boolean publicClient; protected boolean publicClient;
protected boolean fullScopeAllowed;
protected boolean directGrantsOnly; protected boolean directGrantsOnly;
protected int notBefore; protected int notBefore;
protected Set<String> scope = new HashSet<String>(); protected Set<String> scope = new HashSet<String>();
@ -37,6 +38,7 @@ public class CachedClient {
directGrantsOnly = model.isDirectGrantsOnly(); directGrantsOnly = model.isDirectGrantsOnly();
publicClient = model.isPublicClient(); publicClient = model.isPublicClient();
allowedClaimsMask = model.getAllowedClaimsMask(); allowedClaimsMask = model.getAllowedClaimsMask();
fullScopeAllowed = model.isFullScopeAllowed();
redirectUris.addAll(model.getRedirectUris()); redirectUris.addAll(model.getRedirectUris());
webOrigins.addAll(model.getWebOrigins()); webOrigins.addAll(model.getWebOrigins());
for (RoleModel role : model.getScopeMappings()) { for (RoleModel role : model.getScopeMappings()) {
@ -92,4 +94,8 @@ public class CachedClient {
public Set<String> getWebOrigins() { public Set<String> getWebOrigins() {
return webOrigins; return webOrigins;
} }
public boolean isFullScopeAllowed() {
return fullScopeAllowed;
}
} }

View file

@ -78,6 +78,16 @@ public abstract class ClientAdapter implements ClientModel {
entity.setPublicClient(flag); entity.setPublicClient(flag);
} }
@Override
public boolean isFullScopeAllowed() {
return entity.isFullScopeAllowed();
}
@Override
public void setFullScopeAllowed(boolean value) {
entity.setFullScopeAllowed(value);
}
@Override @Override
public Set<String> getWebOrigins() { public Set<String> getWebOrigins() {
Set<String> result = new HashSet<String>(); Set<String> result = new HashSet<String>();
@ -214,6 +224,7 @@ public abstract class ClientAdapter implements ClientModel {
@Override @Override
public boolean hasScope(RoleModel role) { public boolean hasScope(RoleModel role) {
if (isFullScopeAllowed()) return true;
Set<RoleModel> roles = getScopeMappings(); Set<RoleModel> roles = getScopeMappings();
if (roles.contains(role)) return true; if (roles.contains(role)) return true;

View file

@ -38,6 +38,8 @@ public abstract class ClientEntity {
private int notBefore; private int notBefore;
@Column(name="PUBLIC_CLIENT") @Column(name="PUBLIC_CLIENT")
private boolean publicClient; private boolean publicClient;
@Column(name="FULL_SCOPE_ALLOWED")
private boolean fullScopeAllowed;
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "REALM_ID") @JoinColumn(name = "REALM_ID")
@ -132,4 +134,12 @@ public abstract class ClientEntity {
public void setPublicClient(boolean publicClient) { public void setPublicClient(boolean publicClient) {
this.publicClient = publicClient; this.publicClient = publicClient;
} }
public boolean isFullScopeAllowed() {
return fullScopeAllowed;
}
public void setFullScopeAllowed(boolean fullScopeAllowed) {
this.fullScopeAllowed = fullScopeAllowed;
}
} }

View file

@ -157,6 +157,18 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
updateMongoEntity(); updateMongoEntity();
} }
@Override
public boolean isFullScopeAllowed() {
return getMongoEntityAsClient().isFullScopeAllowed();
}
@Override
public void setFullScopeAllowed(boolean value) {
getMongoEntityAsClient().setFullScopeAllowed(value);
updateMongoEntity();
}
@Override @Override
public RealmModel getRealm() { public RealmModel getRealm() {
return realm; return realm;
@ -207,6 +219,7 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
@Override @Override
public boolean hasScope(RoleModel role) { public boolean hasScope(RoleModel role) {
if (isFullScopeAllowed()) return true;
Set<RoleModel> roles = getScopeMappings(); Set<RoleModel> roles = getScopeMappings();
if (roles.contains(role)) return true; if (roles.contains(role)) return true;

View file

@ -95,6 +95,7 @@ public class RealmManager {
adminConsole.setEnabled(true); adminConsole.setEnabled(true);
adminConsole.setPublicClient(true); adminConsole.setPublicClient(true);
adminConsole.addRedirectUri(baseUrl + "/*"); adminConsole.addRedirectUri(baseUrl + "/*");
adminConsole.setFullScopeAllowed(false);
RoleModel adminRole; RoleModel adminRole;
if (realm.getName().equals(Config.getAdminRealm())) { if (realm.getName().equals(Config.getAdminRealm())) {
@ -163,6 +164,7 @@ public class RealmManager {
} }
RoleModel adminRole = realmAdminApp.addRole(AdminRoles.REALM_ADMIN); RoleModel adminRole = realmAdminApp.addRole(AdminRoles.REALM_ADMIN);
realmAdminApp.setBearerOnly(true); realmAdminApp.setBearerOnly(true);
realmAdminApp.setFullScopeAllowed(false);
for (String r : AdminRoles.ALL_REALM_ROLES) { for (String r : AdminRoles.ALL_REALM_ROLES) {
RoleModel role = realmAdminApp.addRole(r); RoleModel role = realmAdminApp.addRole(r);
@ -176,6 +178,7 @@ public class RealmManager {
if (application == null) { if (application == null) {
application = new ApplicationManager(this).createApplication(realm, Constants.ACCOUNT_MANAGEMENT_APP); application = new ApplicationManager(this).createApplication(realm, Constants.ACCOUNT_MANAGEMENT_APP);
application.setEnabled(true); application.setEnabled(true);
application.setFullScopeAllowed(false);
String base = contextPath + "/realms/" + realm.getName() + "/account"; String base = contextPath + "/realms/" + realm.getName() + "/account";
String redirectUri = base + "/*"; String redirectUri = base + "/*";
application.addRedirectUri(redirectUri); application.addRedirectUri(redirectUri);

View file

@ -135,6 +135,8 @@ public class TokenManager {
Set<RoleModel> requestedRoles = new HashSet<RoleModel>(); Set<RoleModel> requestedRoles = new HashSet<RoleModel>();
Set<RoleModel> roleMappings = user.getRoleMappings(); Set<RoleModel> roleMappings = user.getRoleMappings();
if (client.isFullScopeAllowed()) return roleMappings;
Set<RoleModel> scopeMappings = client.getScopeMappings(); Set<RoleModel> scopeMappings = client.getScopeMappings();
if (client instanceof ApplicationModel) { if (client instanceof ApplicationModel) {
scopeMappings.addAll(((ApplicationModel) client).getRoles()); scopeMappings.addAll(((ApplicationModel) client).getRoles());

View file

@ -1069,6 +1069,11 @@ public class TokenService {
if (redirectUri != null) { if (redirectUri != null) {
// todo manage legal redirects // todo manage legal redirects
if (redirectUri.startsWith("/")) { // handle relative uri
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.replacePath(redirectUri);
return Response.status(302).location(builder.build()).build();
}
return Response.status(302).location(UriBuilder.fromUri(redirectUri).build()).build(); return Response.status(302).location(UriBuilder.fromUri(redirectUri).build()).build();
} else { } else {
return Response.ok().build(); return Response.ok().build();

View file

@ -166,6 +166,7 @@ public class AdminAPITest {
if (appRep.isEnabled() != null) Assert.assertEquals(appRep.isEnabled(), storedApp.isEnabled()); if (appRep.isEnabled() != null) Assert.assertEquals(appRep.isEnabled(), storedApp.isEnabled());
if (appRep.isBearerOnly() != null) Assert.assertEquals(appRep.isBearerOnly(), storedApp.isBearerOnly()); if (appRep.isBearerOnly() != null) Assert.assertEquals(appRep.isBearerOnly(), storedApp.isBearerOnly());
if (appRep.isPublicClient() != null) Assert.assertEquals(appRep.isPublicClient(), storedApp.isPublicClient()); if (appRep.isPublicClient() != null) Assert.assertEquals(appRep.isPublicClient(), storedApp.isPublicClient());
if (appRep.isFullScopeAllowed() != null) Assert.assertEquals(appRep.isFullScopeAllowed(), storedApp.isFullScopeAllowed());
if (appRep.getAdminUrl() != null) Assert.assertEquals(appRep.getAdminUrl(), storedApp.getAdminUrl()); if (appRep.getAdminUrl() != null) Assert.assertEquals(appRep.getAdminUrl(), storedApp.getAdminUrl());
if (appRep.getBaseUrl() != null) Assert.assertEquals(appRep.getBaseUrl(), storedApp.getBaseUrl()); if (appRep.getBaseUrl() != null) Assert.assertEquals(appRep.getBaseUrl(), storedApp.getBaseUrl());
if (appRep.isSurrogateAuthRequired() != null) Assert.assertEquals(appRep.isSurrogateAuthRequired(), storedApp.isSurrogateAuthRequired()); if (appRep.isSurrogateAuthRequired() != null) Assert.assertEquals(appRep.isSurrogateAuthRequired(), storedApp.isSurrogateAuthRequired());

View file

@ -86,6 +86,7 @@ public class CompositeRoleTest {
realmRole1User.grantRole(realmRole1); realmRole1User.grantRole(realmRole1);
final ApplicationModel realmComposite1Application = new ApplicationManager(manager).createApplication(realm, "REALM_COMPOSITE_1_APPLICATION"); final ApplicationModel realmComposite1Application = new ApplicationManager(manager).createApplication(realm, "REALM_COMPOSITE_1_APPLICATION");
realmComposite1Application.setFullScopeAllowed(false);
realmComposite1Application.setEnabled(true); realmComposite1Application.setEnabled(true);
realmComposite1Application.addScopeMapping(realmComposite1); realmComposite1Application.addScopeMapping(realmComposite1);
realmComposite1Application.addRedirectUri("http://localhost:8081/app/*"); realmComposite1Application.addRedirectUri("http://localhost:8081/app/*");
@ -94,6 +95,7 @@ public class CompositeRoleTest {
realmComposite1Application.setSecret("password"); realmComposite1Application.setSecret("password");
final ApplicationModel realmRole1Application = new ApplicationManager(manager).createApplication(realm, "REALM_ROLE_1_APPLICATION"); final ApplicationModel realmRole1Application = new ApplicationManager(manager).createApplication(realm, "REALM_ROLE_1_APPLICATION");
realmRole1Application.setFullScopeAllowed(false);
realmRole1Application.setEnabled(true); realmRole1Application.setEnabled(true);
realmRole1Application.addScopeMapping(realmRole1); realmRole1Application.addScopeMapping(realmRole1);
realmRole1Application.addRedirectUri("http://localhost:8081/app/*"); realmRole1Application.addRedirectUri("http://localhost:8081/app/*");
@ -103,6 +105,7 @@ public class CompositeRoleTest {
final ApplicationModel appRoleApplication = new ApplicationManager(manager).createApplication(realm, "APP_ROLE_APPLICATION"); final ApplicationModel appRoleApplication = new ApplicationManager(manager).createApplication(realm, "APP_ROLE_APPLICATION");
appRoleApplication.setFullScopeAllowed(false);
appRoleApplication.setEnabled(true); appRoleApplication.setEnabled(true);
appRoleApplication.addRedirectUri("http://localhost:8081/app/*"); appRoleApplication.addRedirectUri("http://localhost:8081/app/*");
appRoleApplication.setBaseUrl("http://localhost:8081/app"); appRoleApplication.setBaseUrl("http://localhost:8081/app");
@ -125,6 +128,7 @@ public class CompositeRoleTest {
realmAppRoleUser.grantRole(appRole2); realmAppRoleUser.grantRole(appRole2);
final ApplicationModel appCompositeApplication = new ApplicationManager(manager).createApplication(realm, "APP_COMPOSITE_APPLICATION"); final ApplicationModel appCompositeApplication = new ApplicationManager(manager).createApplication(realm, "APP_COMPOSITE_APPLICATION");
appCompositeApplication.setFullScopeAllowed(false);
appCompositeApplication.setEnabled(true); appCompositeApplication.setEnabled(true);
appCompositeApplication.addRedirectUri("http://localhost:8081/app/*"); appCompositeApplication.addRedirectUri("http://localhost:8081/app/*");
appCompositeApplication.setBaseUrl("http://localhost:8081/app"); appCompositeApplication.setBaseUrl("http://localhost:8081/app");

View file

@ -88,6 +88,7 @@
"applications": [ "applications": [
{ {
"name": "REALM_COMPOSITE_1_APPLICATION", "name": "REALM_COMPOSITE_1_APPLICATION",
"fullScopeAllowed": false,
"enabled": true, "enabled": true,
"baseUrl": "http://localhost:8081/app", "baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout", "adminUrl": "http://localhost:8081/app/logout",
@ -95,6 +96,7 @@
}, },
{ {
"name": "REALM_ROLE_1_APPLICATION", "name": "REALM_ROLE_1_APPLICATION",
"fullScopeAllowed": false,
"enabled": true, "enabled": true,
"baseUrl": "http://localhost:8081/app", "baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout", "adminUrl": "http://localhost:8081/app/logout",
@ -102,6 +104,7 @@
}, },
{ {
"name": "APP_ROLE_APPLICATION", "name": "APP_ROLE_APPLICATION",
"fullScopeAllowed": false,
"enabled": true, "enabled": true,
"baseUrl": "http://localhost:8081/app", "baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout", "adminUrl": "http://localhost:8081/app/logout",
@ -109,6 +112,7 @@
}, },
{ {
"name": "APP_COMPOSITE_APPLICATION", "name": "APP_COMPOSITE_APPLICATION",
"fullScopeAllowed": false,
"enabled": true, "enabled": true,
"baseUrl": "http://localhost:8081/app", "baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout", "adminUrl": "http://localhost:8081/app/logout",

View file

@ -89,6 +89,7 @@
{ {
"name": "REALM_COMPOSITE_1_APPLICATION", "name": "REALM_COMPOSITE_1_APPLICATION",
"enabled": true, "enabled": true,
"fullScopeAllowed": false,
"baseUrl": "http://localhost:8081/app", "baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout", "adminUrl": "http://localhost:8081/app/logout",
"redirectUris": [ "redirectUris": [
@ -98,6 +99,7 @@
}, },
{ {
"name": "REALM_ROLE_1_APPLICATION", "name": "REALM_ROLE_1_APPLICATION",
"fullScopeAllowed": false,
"enabled": true, "enabled": true,
"baseUrl": "http://localhost:8081/app", "baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout", "adminUrl": "http://localhost:8081/app/logout",
@ -108,6 +110,7 @@
}, },
{ {
"name": "APP_ROLE_APPLICATION", "name": "APP_ROLE_APPLICATION",
"fullScopeAllowed": false,
"enabled": true, "enabled": true,
"baseUrl": "http://localhost:8081/app", "baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout", "adminUrl": "http://localhost:8081/app/logout",
@ -118,6 +121,7 @@
}, },
{ {
"name": "APP_COMPOSITE_APPLICATION", "name": "APP_COMPOSITE_APPLICATION",
"fullScopeAllowed": false,
"enabled": true, "enabled": true,
"baseUrl": "http://localhost:8081/app", "baseUrl": "http://localhost:8081/app",
"adminUrl": "http://localhost:8081/app/logout", "adminUrl": "http://localhost:8081/app/logout",