Skip to content

Commit

Permalink
[KEYCLOAK-883] - Configuration option to disable token retrieval from…
Browse files Browse the repository at this point in the history
… applications.
  • Loading branch information
pedroigor committed Feb 27, 2015
1 parent cd39d52 commit b45d6b8
Show file tree
Hide file tree
Showing 28 changed files with 725 additions and 183 deletions.
Expand Up @@ -73,13 +73,14 @@
<constraints nullable="false"/>
</column>
</createTable>
<createTable tableName="CLIENT_ALLOWED_IDENTITY_PROVIDER">
<createTable tableName="CLIENT_IDENTITY_PROVIDER_MAPPING">
<column name="CLIENT_ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
<column name="INTERNAL_ID" type="VARCHAR(36)">
<column name="IDENTITY_PROVIDER_ID" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
<column name="RETRIEVE_TOKEN" type="BOOLEAN(1)"/>
</createTable>
<createTable tableName="CLIENT_PROTOCOL_MAPPER">
<column name="CLIENT_ID" type="VARCHAR(36)">
Expand All @@ -104,10 +105,11 @@
<addForeignKeyConstraint baseColumnNames="USER_ID" baseTableName="FEDERATED_IDENTITY" constraintName="FK404288B92EF007A6" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="USER_ENTITY"/>
<addForeignKeyConstraint baseColumnNames="IDENTITY_PROVIDER_ID" baseTableName="IDENTITY_PROVIDER_CONFIG" constraintName="FKDC4897CF864C4E43" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="INTERNAL_ID" referencedTableName="IDENTITY_PROVIDER"/>
<addForeignKeyConstraint baseColumnNames="PROTOCOL_MAPPER_ID" baseTableName="PROTOCOL_MAPPER_CONFIG" constraintName="FK_PMConfig" deferrable="false" initiallyDeferred="false" onDelete="RESTRICT" onUpdate="RESTRICT" referencedColumnNames="ID" referencedTableName="PROTOCOL_MAPPER"/>
<addForeignKeyConstraint baseColumnNames="INTERNAL_ID" baseTableName="CLIENT_ALLOWED_IDENTITY_PROVIDER" constraintName="FK_7CELWNIBJI49AVXSRTUF6XJ12" referencedColumnNames="INTERNAL_ID" referencedTableName="IDENTITY_PROVIDER"/>
<addUniqueConstraint columnNames="INTERNAL_ID,CLIENT_ID" constraintName="UK_7CAELWNIBJI49AVXSRTUF6XJ12" tableName="CLIENT_ALLOWED_IDENTITY_PROVIDER"/>
<addForeignKeyConstraint baseColumnNames="IDENTITY_PROVIDER_ID" baseTableName="CLIENT_IDENTITY_PROVIDER_MAPPING" constraintName="FK_7CELWNIBJI49AVXSRTUF6XJ12" referencedColumnNames="INTERNAL_ID" referencedTableName="IDENTITY_PROVIDER"/>
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="CLIENT_IDENTITY_PROVIDER_MAPPING" constraintName="FK_56ELWNIBJI49AVXSRTUF6XJ23" referencedColumnNames="ID" referencedTableName="CLIENT"/>
<addForeignKeyConstraint baseColumnNames="MAPPING_ID" baseTableName="CLIENT_PROTOCOL_MAPPER" constraintName="FK_CPCM" referencedColumnNames="ID" referencedTableName="PROTOCOL_MAPPER"/>
<addUniqueConstraint columnNames="CLIENT_ID,MAPPING_ID" constraintName="UK_CPCM" tableName="CLIENT_PROTOCOL_MAPPER"/>
<addUniqueConstraint columnNames="PROVIDER_NONIMAL_ID" constraintName="UK_2DAELWNIBJI49AVXSRTUF6XJ33" tableName="IDENTITY_PROVIDER"/>
<addUniqueConstraint columnNames="IDENTITY_PROVIDER_ID,CLIENT_ID" constraintName="UK_7CAELWNIBJI49AVXSRTUF6XJ12" tableName="CLIENT_IDENTITY_PROVIDER_MAPPING"/>
</changeSet>
</databaseChangeLog>
Expand Up @@ -18,6 +18,7 @@
<class>org.keycloak.models.jpa.entities.UserRoleMappingEntity</class>
<class>org.keycloak.models.jpa.entities.ScopeMappingEntity</class>
<class>org.keycloak.models.jpa.entities.IdentityProviderEntity</class>
<class>org.keycloak.models.jpa.entities.ClientIdentityProviderMappingEntity</class>
<class>org.keycloak.models.jpa.entities.ClaimTypeEntity</class>
<class>org.keycloak.models.jpa.entities.ProtocolMapperEntity</class>

Expand Down
Expand Up @@ -2,7 +2,6 @@

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
Expand All @@ -29,7 +28,7 @@ public class ApplicationRepresentation {
protected Boolean fullScopeAllowed;
protected Integer nodeReRegistrationTimeout;
protected Map<String, Integer> registeredNodes;
protected List<String> allowedIdentityProviders;
protected List<ClientIdentityProviderMappingRepresentation> identityProviders;
protected List<ClientProtocolMappingRepresentation> protocolMappers;

public String getId() {
Expand Down Expand Up @@ -192,12 +191,12 @@ public void setFrontchannelLogout(Boolean frontchannelLogout) {
this.frontchannelLogout = frontchannelLogout;
}

public List<String> getAllowedIdentityProviders() {
return this.allowedIdentityProviders;
public List<ClientIdentityProviderMappingRepresentation> getIdentityProviders() {
return this.identityProviders;
}

public void setAllowedIdentityProviders(List<String> allowedIdentityProviders) {
this.allowedIdentityProviders = allowedIdentityProviders;
public void setIdentityProviders(List<ClientIdentityProviderMappingRepresentation> identityProviders) {
this.identityProviders = identityProviders;
}

public List<ClientProtocolMappingRepresentation> getProtocolMappers() {
Expand Down
@@ -0,0 +1,43 @@
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.representations.idm;

/**
* @author pedroigor
*/
public class ClientIdentityProviderMappingRepresentation {

protected String id;
protected boolean retrieveToken;

public String getId() {
return this.id;
}

public void setId(String identityProviderId) {
this.id = identityProviderId;
}

public boolean isRetrieveToken() {
return this.retrieveToken;
}

public void setRetrieveToken(boolean retrieveToken) {
this.retrieveToken = retrieveToken;
}
}
Expand Up @@ -2,7 +2,6 @@

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
Expand All @@ -23,8 +22,8 @@ public class OAuthClientRepresentation {
protected Boolean directGrantsOnly;
protected Boolean fullScopeAllowed;
protected Boolean frontchannelLogout;
protected List<String> allowedIdentityProviders;
protected List<ClientProtocolMappingRepresentation> protocolMappers;
private List<ClientIdentityProviderMappingRepresentation> identityProviders;


public String getId() {
Expand Down Expand Up @@ -139,12 +138,12 @@ public void setFrontchannelLogout(Boolean frontchannelLogout) {
this.frontchannelLogout = frontchannelLogout;
}

public List<String> getAllowedIdentityProviders() {
return this.allowedIdentityProviders;
public List<ClientIdentityProviderMappingRepresentation> getIdentityProviders() {
return this.identityProviders;
}

public void setAllowedIdentityProviders(List<String> allowedIdentityProviders) {
this.allowedIdentityProviders = allowedIdentityProviders;
public void setIdentityProviders(List<ClientIdentityProviderMappingRepresentation> identityProviders) {
this.identityProviders = identityProviders;
}

public List<ClientProtocolMappingRepresentation> getProtocolMappers() {
Expand Down
6 changes: 5 additions & 1 deletion docbook/reference/en/en-US/modules/identity-broker.xml
Expand Up @@ -962,7 +962,7 @@ Authorization: Bearer {keycloak_access_token}]]></programlisting>
</section>

<section>
<title>Enabling/Disabling Identity Providers for Service Providers</title>
<title>Configuring Identity Providers for Applications</title>
<para>
By default, all identity providers enabled for a particular realm are also available to all its applications.
However, you can also specify which identity providers should be available when
Expand Down Expand Up @@ -993,6 +993,10 @@ Authorization: Bearer {keycloak_access_token}]]></programlisting>
</para>
</listitem>
</orderedlist>
<para>
From this page you can also configure if an application is allowed to retrieve tokens from an specific identity provider. For that,
just click on the <emphasis>Can Retrieve Token</emphasis> button.
</para>
</section>

<section>
Expand Down
Expand Up @@ -43,75 +43,95 @@ module.controller('ApplicationCredentialsCtrl', function($scope, $location, real
});
});

module.controller('ApplicationIdentityProviderCtrl', function($scope, $location, realm, application, Application, $location, Notifications) {
module.controller('ApplicationIdentityProviderCtrl', function($scope, $location, $route, realm, application, Application, $location, Notifications) {
$scope.realm = realm;
$scope.application = angular.copy(application);
var length = 0;

$scope.identityProviders = [];
if ($scope.application.identityProviders) {
length = $scope.application.identityProviders.length;
} else {
$scope.application.identityProviders = new Array(realm.identityProviders.length);
}

if (!$scope.application.allowedIdentityProviders) {
$scope.application.allowedIdentityProviders = [];
for (j = length; j < realm.identityProviders.length; j++) {
$scope.application.identityProviders[j] = {};
}

$scope.identityProviders = [];

for (j = 0; j < realm.identityProviders.length; j++) {
var identityProvider = realm.identityProviders[j];
var match = false;

for (i = 0; i < $scope.application.allowedIdentityProviders.length; i++) {
var appProvider = $scope.application.allowedIdentityProviders[i];

if (appProvider == identityProvider.id) {
$scope.identityProviders[i] = identityProvider;
match = true;
var applicationProvider;

for (i = 0; i < $scope.application.identityProviders.length; i++) {
applicationProvider = $scope.application.identityProviders[i];

if (applicationProvider) {
if (applicationProvider.retrieveToken) {
applicationProvider.retrieveToken = applicationProvider.retrieveToken.toString();
} else {
applicationProvider.retrieveToken = false.toString();
}

if (applicationProvider.id == identityProvider.id) {
$scope.identityProviders[i] = {};
$scope.identityProviders[i].identityProvider = identityProvider;
$scope.identityProviders[i].retrieveToken = applicationProvider.retrieveToken.toString();
break;
}

applicationProvider = null;
}
}

if (!match) {
var length = $scope.identityProviders.length;

length = length + $scope.application.allowedIdentityProviders.length;
if (applicationProvider == null) {
var length = $scope.identityProviders.length + $scope.application.identityProviders.length;

$scope.identityProviders[length] = identityProvider;
$scope.identityProviders[length] = {};
$scope.identityProviders[length].identityProvider = identityProvider;
$scope.identityProviders[length].retrieveToken = false.toString();
}
}

$scope.identityProviders = $scope.identityProviders.filter(function(n){ return n != undefined });

var oldCopy = angular.copy($scope.application);

$scope.save = function() {
var selectedProviders = [];

for (i = 0; i < $scope.application.allowedIdentityProviders.length; i++) {
var appProvider = $scope.application.allowedIdentityProviders[i];
for (i = 0; i < $scope.application.identityProviders.length; i++) {
var appProvider = $scope.application.identityProviders[i];

if (appProvider) {
if (appProvider.id != null && appProvider.id != false) {
selectedProviders[selectedProviders.length] = appProvider;
}
}

$scope.allowedIdentityProviders = $scope.application.allowedIdentityProviders;
$scope.application.allowedIdentityProviders = selectedProviders;
$scope.application.identityProviders = selectedProviders;

Application.update({
realm : realm.realm,
application : application.id
}, $scope.application, function() {
$scope.changed = false;
$scope.application.allowedIdentityProviders = $scope.allowedIdentityProviders;
$location.url("/realms/" + realm.realm + "/applications/" + application.id + "/identity-provider");
$route.reload();
Notifications.success("Your changes have been saved to the application.");
});
};

$scope.reset = function() {
$scope.application = angular.copy(application);
$scope.application = angular.copy(oldCopy);
$scope.changed = false;
};

$scope.$watch(function() {
return $location.path();
}, function() {
$scope.path = $location.path().substring(1).split("/");
});
$scope.$watch('application', function() {
if (!angular.equals($scope.application, oldCopy)) {
$scope.changed = true;
}
}, true);
});

module.controller('ApplicationSamlKeyCtrl', function($scope, $location, $http, $upload, realm, application,
Expand Down

0 comments on commit b45d6b8

Please sign in to comment.