KEYCLOAK-1750 Option updateProfileOnFirstLogin moved from IdentityProvider to IdpReviewProfile authenticator
This commit is contained in:
parent
99e75c69a0
commit
4ca442d1b2
28 changed files with 240 additions and 259 deletions
|
@ -7,6 +7,7 @@
|
||||||
<constraints nullable="false"/>
|
<constraints nullable="false"/>
|
||||||
</column>
|
</column>
|
||||||
</addColumn>
|
</addColumn>
|
||||||
|
<dropColumn tableName="IDENTITY_PROVIDER" columnName="UPDATE_PROFILE_FIRST_LGN_MD"/>
|
||||||
|
|
||||||
</changeSet>
|
</changeSet>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
|
@ -46,6 +46,7 @@ public class IdentityProviderRepresentation {
|
||||||
* @see #UPFLM_MISSING
|
* @see #UPFLM_MISSING
|
||||||
* @see #UPFLM_OFF
|
* @see #UPFLM_OFF
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
protected String updateProfileFirstLoginMode = UPFLM_ON;
|
protected String updateProfileFirstLoginMode = UPFLM_ON;
|
||||||
|
|
||||||
protected boolean trustEmail;
|
protected boolean trustEmail;
|
||||||
|
@ -107,15 +108,17 @@ public class IdentityProviderRepresentation {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return see {@link #updateProfileFirstLoginMode}
|
* @deprecated deprecated and replaced by configuration on IdpReviewProfileAuthenticator
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public String getUpdateProfileFirstLoginMode() {
|
public String getUpdateProfileFirstLoginMode() {
|
||||||
return updateProfileFirstLoginMode;
|
return updateProfileFirstLoginMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param updateProfileFirstLoginMode see {@link #updateProfileFirstLoginMode}
|
* @deprecated deprecated and replaced by configuration on IdpReviewProfileAuthenticator
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
|
public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
|
||||||
this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
|
this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,16 +79,34 @@
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Version specific migration</title>
|
<title>Version specific migration</title>
|
||||||
|
<section>
|
||||||
|
<title>Migrating to 1.7.0.CR1</title>
|
||||||
|
<simplesect>
|
||||||
|
<title>Option 'Update Profile On First Login' moved from Identity provider to Review Profile authenticator</title>
|
||||||
|
<para>
|
||||||
|
In this version, we added <literal>First Broker Login</literal>, which allows you to specify what exactly should be done
|
||||||
|
when new user is logged through Identity provider (or Social provider), but there is no existing Keycloak user
|
||||||
|
yet linked to the social account. As part of this work, we added option <literal>First Login Flow</literal> to identity providers where
|
||||||
|
you can specify the flow and then you can configure this flow under <literal>Authentication</literal> tab in admin console.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
We also removed the option <literal>Update Profile On First Login</literal> from the Identity provider settings and moved it
|
||||||
|
to the configuration of <literal>Review Profile</literal> authenticator. So once you specify which flow should be used for your
|
||||||
|
Identity provider (by default it's <literal>First Broker Login</literal> flow), you go to <literal>Authentication</literal> tab, select the flow
|
||||||
|
and then you configure the option under <literal>Review Profile</literal> authenticator.
|
||||||
|
</para>
|
||||||
|
</simplesect>
|
||||||
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<title>Migrating to 1.6.0.Final</title>
|
<title>Migrating to 1.6.0.Final</title>
|
||||||
<simplesect>
|
<simplesect>
|
||||||
<title>Refresh tokens are not reusable anymore</title>
|
<title>Option that refresh tokens are not reusable anymore</title>
|
||||||
<para>
|
<para>
|
||||||
Old versions of Keycloak allowed reusing refresh tokens multiple times. Keycloak no longer permits
|
Old versions of Keycloak allowed reusing refresh tokens multiple times. Keycloak still permits this,
|
||||||
this by default. When a refresh token is used to obtain a new access token a new refresh token is also
|
but also have an option <literal>Revoke refresh token</literal> to disallow it. Option is in in admin console under token settings.
|
||||||
included. This new refresh token should be used next time the access token is refreshed. If this is
|
When a refresh token is used to obtain a new access token a new refresh token is also
|
||||||
a problem for you it's possible to enable reuse of refresh tokens in the admin console under token
|
included. When option is enabled, then this new refresh token should be used next time the access token is refreshed.
|
||||||
settings.
|
It won't be possible to reuse old refresh token multiple times.
|
||||||
</para>
|
</para>
|
||||||
</simplesect>
|
</simplesect>
|
||||||
<simplesect>
|
<simplesect>
|
||||||
|
|
|
@ -1348,12 +1348,15 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||||
},
|
},
|
||||||
controller : 'RealmOtpPolicyCtrl'
|
controller : 'RealmOtpPolicyCtrl'
|
||||||
})
|
})
|
||||||
.when('/realms/:realm/authentication/config/:provider/:config', {
|
.when('/realms/:realm/authentication/flows/:flow/config/:provider/:config', {
|
||||||
templateUrl : resourceUrl + '/partials/authenticator-config.html',
|
templateUrl : resourceUrl + '/partials/authenticator-config.html',
|
||||||
resolve : {
|
resolve : {
|
||||||
realm : function(RealmLoader) {
|
realm : function(RealmLoader) {
|
||||||
return RealmLoader();
|
return RealmLoader();
|
||||||
},
|
},
|
||||||
|
flow : function(AuthenticationFlowLoader) {
|
||||||
|
return AuthenticationFlowLoader();
|
||||||
|
},
|
||||||
configType : function(AuthenticationConfigDescriptionLoader) {
|
configType : function(AuthenticationConfigDescriptionLoader) {
|
||||||
return AuthenticationConfigDescriptionLoader();
|
return AuthenticationConfigDescriptionLoader();
|
||||||
},
|
},
|
||||||
|
@ -1363,12 +1366,15 @@ module.config([ '$routeProvider', function($routeProvider) {
|
||||||
},
|
},
|
||||||
controller : 'AuthenticationConfigCtrl'
|
controller : 'AuthenticationConfigCtrl'
|
||||||
})
|
})
|
||||||
.when('/create/authentication/:realm/execution/:executionId/provider/:provider', {
|
.when('/create/authentication/:realm/flows/:flow/execution/:executionId/provider/:provider', {
|
||||||
templateUrl : resourceUrl + '/partials/authenticator-config.html',
|
templateUrl : resourceUrl + '/partials/authenticator-config.html',
|
||||||
resolve : {
|
resolve : {
|
||||||
realm : function(RealmLoader) {
|
realm : function(RealmLoader) {
|
||||||
return RealmLoader();
|
return RealmLoader();
|
||||||
},
|
},
|
||||||
|
flow : function(AuthenticationFlowLoader) {
|
||||||
|
return AuthenticationFlowLoader();
|
||||||
|
},
|
||||||
configType : function(AuthenticationConfigDescriptionLoader) {
|
configType : function(AuthenticationConfigDescriptionLoader) {
|
||||||
return AuthenticationConfigDescriptionLoader();
|
return AuthenticationConfigDescriptionLoader();
|
||||||
},
|
},
|
||||||
|
|
|
@ -599,15 +599,6 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
|
||||||
|
|
||||||
$scope.realm = angular.copy(realm);
|
$scope.realm = angular.copy(realm);
|
||||||
|
|
||||||
$scope.initProvider = function() {
|
|
||||||
if (instance && instance.alias) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$scope.identityProvider.updateProfileFirstLoginMode = "on";
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.initSamlProvider = function() {
|
$scope.initSamlProvider = function() {
|
||||||
$scope.nameIdFormats = [
|
$scope.nameIdFormats = [
|
||||||
/*
|
/*
|
||||||
|
@ -658,7 +649,6 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
|
||||||
} else {
|
} else {
|
||||||
$scope.identityProvider.config.nameIDPolicyFormat = $scope.nameIdFormats[0].format;
|
$scope.identityProvider.config.nameIDPolicyFormat = $scope.nameIdFormats[0].format;
|
||||||
$scope.identityProvider.config.signatureAlgorithm = $scope.signatureAlgorithms[1];
|
$scope.identityProvider.config.signatureAlgorithm = $scope.signatureAlgorithms[1];
|
||||||
$scope.identityProvider.updateProfileFirstLoginMode = "off";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +666,6 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
|
||||||
$scope.identityProvider.alias = providerFactory.id;
|
$scope.identityProvider.alias = providerFactory.id;
|
||||||
$scope.identityProvider.providerId = providerFactory.id;
|
$scope.identityProvider.providerId = providerFactory.id;
|
||||||
$scope.identityProvider.enabled = true;
|
$scope.identityProvider.enabled = true;
|
||||||
$scope.identityProvider.updateProfileFirstLoginMode = "off";
|
|
||||||
$scope.identityProvider.authenticateByDefault = false;
|
$scope.identityProvider.authenticateByDefault = false;
|
||||||
$scope.identityProvider.firstBrokerLoginFlowAlias = 'first broker login';
|
$scope.identityProvider.firstBrokerLoginFlowAlias = 'first broker login';
|
||||||
$scope.newIdentityProvider = true;
|
$scope.newIdentityProvider = true;
|
||||||
|
@ -1909,8 +1898,9 @@ module.controller('RequiredActionsCtrl', function($scope, realm, unregisteredReq
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.controller('AuthenticationConfigCtrl', function($scope, realm, configType, config, AuthenticationConfig, Notifications, Dialog, $location) {
|
module.controller('AuthenticationConfigCtrl', function($scope, realm, flow, configType, config, AuthenticationConfig, Notifications, Dialog, $location) {
|
||||||
$scope.realm = realm;
|
$scope.realm = realm;
|
||||||
|
$scope.flow = flow;
|
||||||
$scope.configType = configType;
|
$scope.configType = configType;
|
||||||
$scope.create = false;
|
$scope.create = false;
|
||||||
$scope.config = angular.copy(config);
|
$scope.config = angular.copy(config);
|
||||||
|
@ -1935,7 +1925,7 @@ module.controller('AuthenticationConfigCtrl', function($scope, realm, configType
|
||||||
}, $scope.config, function() {
|
}, $scope.config, function() {
|
||||||
$scope.changed = false;
|
$scope.changed = false;
|
||||||
config = angular.copy($scope.config);
|
config = angular.copy($scope.config);
|
||||||
$location.url("/realms/" + realm.realm + '/authentication/config/' + configType.providerId + "/" + config.id);
|
$location.url("/realms/" + realm.realm + '/authentication/flows/' + flow.id + '/config/' + configType.providerId + "/" + config.id);
|
||||||
Notifications.success("Your changes have been saved.");
|
Notifications.success("Your changes have been saved.");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1954,15 +1944,16 @@ module.controller('AuthenticationConfigCtrl', function($scope, realm, configType
|
||||||
Dialog.confirmDelete($scope.config.alias, 'config', function() {
|
Dialog.confirmDelete($scope.config.alias, 'config', function() {
|
||||||
AuthenticationConfig.remove({ realm: realm.realm, config : $scope.config.id }, function() {
|
AuthenticationConfig.remove({ realm: realm.realm, config : $scope.config.id }, function() {
|
||||||
Notifications.success("The config has been deleted.");
|
Notifications.success("The config has been deleted.");
|
||||||
$location.url("/realms/" + realm.realm + '/authentication/flows');
|
$location.url("/realms/" + realm.realm + '/authentication/flows/' + flow.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.controller('AuthenticationConfigCreateCtrl', function($scope, realm, configType, execution, AuthenticationExecutionConfig, Notifications, Dialog, $location) {
|
module.controller('AuthenticationConfigCreateCtrl', function($scope, realm, flow, configType, execution, AuthenticationExecutionConfig, Notifications, Dialog, $location) {
|
||||||
$scope.realm = realm;
|
$scope.realm = realm;
|
||||||
|
$scope.flow = flow;
|
||||||
$scope.create = true;
|
$scope.create = true;
|
||||||
$scope.config = { config: {}};
|
$scope.config = { config: {}};
|
||||||
$scope.configType = configType;
|
$scope.configType = configType;
|
||||||
|
@ -1980,7 +1971,7 @@ module.controller('AuthenticationConfigCreateCtrl', function($scope, realm, conf
|
||||||
}, $scope.config, function(data, headers) {
|
}, $scope.config, function(data, headers) {
|
||||||
var l = headers().location;
|
var l = headers().location;
|
||||||
var id = l.substring(l.lastIndexOf("/") + 1);
|
var id = l.substring(l.lastIndexOf("/") + 1);
|
||||||
var url = "/realms/" + realm.realm + '/authentication/config/' + configType.providerId + "/" + id;
|
var url = "/realms/" + realm.realm + '/authentication/flows/' + flow.id + '/config/' + configType.providerId + "/" + id;
|
||||||
console.log('redirect url: ' + url);
|
console.log('redirect url: ' + url);
|
||||||
$location.url(url);
|
$location.url(url);
|
||||||
Notifications.success("Config has been created.");
|
Notifications.success("Config has been created.");
|
||||||
|
|
|
@ -53,8 +53,8 @@
|
||||||
<li data-ng-hide="flow.builtIn"><a href="" ng-click="removeExecution(execution)">Delete</a></li>
|
<li data-ng-hide="flow.builtIn"><a href="" ng-click="removeExecution(execution)">Delete</a></li>
|
||||||
<li data-ng-hide="flow.builtIn || !execution.authenticationFlow"><a href="" ng-click="addSubFlowExecution(execution)">Add Execution</a></li>
|
<li data-ng-hide="flow.builtIn || !execution.authenticationFlow"><a href="" ng-click="addSubFlowExecution(execution)">Add Execution</a></li>
|
||||||
<li data-ng-hide="flow.builtIn || !execution.authenticationFlow"><a href="" ng-click="addSubFlow(execution)">Add Flow</a></li>
|
<li data-ng-hide="flow.builtIn || !execution.authenticationFlow"><a href="" ng-click="addSubFlow(execution)">Add Flow</a></li>
|
||||||
<li data-ng-show="execution.configurable && execution.authenticationConfig == null"><a href="#/create/authentication/{{realm.realm}}/execution/{{execution.id}}/provider/{{execution.providerId}}">Config</a></li>
|
<li data-ng-show="execution.configurable && execution.authenticationConfig == null"><a href="#/create/authentication/{{realm.realm}}/flows/{{flow.id}}/execution/{{execution.id}}/provider/{{execution.providerId}}">Config</a></li>
|
||||||
<li data-ng-show="execution.configurable && execution.authenticationConfig != null"><a href="#/realms/{{realm.realm}}/authentication/config/{{execution.providerId}}/{{execution.authenticationConfig}}">Config</a></li>
|
<li data-ng-show="execution.configurable && execution.authenticationConfig != null"><a href="#/realms/{{realm.realm}}/authentication/flows/{{flow.id}}/config/{{execution.providerId}}/{{execution.authenticationConfig}}">Config</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="#/realms/{{realm.realm}}/authentication/flows">Authentication Flows</a></li>
|
<li><a href="#/realms/{{realm.realm}}/authentication/flows">Authentication Flows</a></li>
|
||||||
|
<li><a href="#/realms/{{realm.realm}}/authentication/flows/{{flow.alias}}">{{flow.alias | capitalize}}</a></li>
|
||||||
<li class="active" data-ng-show="create">Create Authenticator Config</li>
|
<li class="active" data-ng-show="create">Create Authenticator Config</li>
|
||||||
<li class="active" data-ng-hide="create">{{config.alias}}</li>
|
<li class="active" data-ng-hide="create">{{config.alias}}</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" data-ng-init="initProvider()">
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
||||||
<li>{{identityProvider.alias}}</li>
|
<li>{{identityProvider.alias}}</li>
|
||||||
|
@ -52,19 +52,6 @@
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-md-2 control-label" for="updateProfileFirstLoginMode">{{:: 'update-profile-on-first-login' | translate}}</label>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div>
|
|
||||||
<select id="updateProfileFirstLoginMode" ng-model="identityProvider.updateProfileFirstLoginMode" class="form-control">
|
|
||||||
<option value="on">{{:: 'on' | translate}}</option>
|
|
||||||
<option value="missing">{{:: 'on-missing-info' | translate}}</option>
|
|
||||||
<option value="off">{{:: 'off' | translate}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<kc-tooltip>{{:: 'update-profile-on-first-login.tooltip' | translate}}</kc-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label>
|
<label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|
|
@ -52,19 +52,6 @@
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-md-2 control-label" for="updateProfileFirstLoginMode">{{:: 'update-profile-on-first-login' | translate}}</label>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div>
|
|
||||||
<select id="updateProfileFirstLoginMode" ng-model="identityProvider.updateProfileFirstLoginMode" class="form-control">
|
|
||||||
<option value="on">{{:: 'on' | translate}}</option>
|
|
||||||
<option value="missing">{{:: 'on-missing-info' | translate}}</option>
|
|
||||||
<option value="off">{{:: 'off' | translate}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<kc-tooltip>{{:: 'update-profile-on-first-login.tooltip' | translate}}</kc-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label>
|
<label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" data-ng-init="initProvider()">
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
||||||
<li>{{identityProvider.alias}}</li>
|
<li>{{identityProvider.alias}}</li>
|
||||||
|
@ -63,19 +63,6 @@
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-md-2 control-label" for="updateProfileFirstLoginMode">{{:: 'update-profile-on-first-login' | translate}}</label>
|
|
||||||
<div class="col-md-2">
|
|
||||||
<div>
|
|
||||||
<select id="updateProfileFirstLoginMode" ng-model="identityProvider.updateProfileFirstLoginMode" class="form-control">
|
|
||||||
<option value="on">{{:: 'on' | translate}}</option>
|
|
||||||
<option value="missing">{{:: 'on-missing-info' | translate}}</option>
|
|
||||||
<option value="off">{{:: 'off' | translate}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<kc-tooltip>{{:: 'update-profile-on-first-login.tooltip' | translate}}</kc-tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label>
|
<label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<form id="kc-register-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
<form id="kc-register-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||||
|
|
||||||
<div id="kc-form-buttons" class="${properties.kcFormGroupClass!}">
|
<div id="kc-form-buttons" class="${properties.kcFormGroupClass!}">
|
||||||
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="updateProfile">${msg("confirmLinkIdpUpdateProfile")}</button>
|
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="updateProfile">${msg("confirmLinkIdpReviewProfile")}</button>
|
||||||
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="linkAccount">${msg("confirmLinkIdpContinue", idpAlias)}</button>
|
<button type="submit" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" name="submitAction" value="linkAccount">${msg("confirmLinkIdpContinue", idpAlias)}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ federatedIdentityExistsMessage=User with {0} {1} already exists. Please login to
|
||||||
confirmLinkIdpTitle=Account already exists
|
confirmLinkIdpTitle=Account already exists
|
||||||
federatedIdentityConfirmLinkMessage=User with {0} {1} already exists. How do you want to continue?
|
federatedIdentityConfirmLinkMessage=User with {0} {1} already exists. How do you want to continue?
|
||||||
federatedIdentityConfirmReauthenticateMessage=Authenticate as {0} to link your account with {1}
|
federatedIdentityConfirmReauthenticateMessage=Authenticate as {0} to link your account with {1}
|
||||||
confirmLinkIdpUpdateProfile=Update profile info
|
confirmLinkIdpReviewProfile=Review profile info
|
||||||
confirmLinkIdpContinue=Link {0} with existing account
|
confirmLinkIdpContinue=Link {0} with existing account
|
||||||
|
|
||||||
configureTotpMessage=You need to set up Mobile Authenticator to activate your account.
|
configureTotpMessage=You need to set up Mobile Authenticator to activate your account.
|
||||||
|
|
|
@ -45,14 +45,6 @@ public class IdentityProviderModel implements Serializable {
|
||||||
private String providerId;
|
private String providerId;
|
||||||
|
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
|
||||||
/**
|
|
||||||
* For possible values see {@link IdentityProviderRepresentation#getUpdateProfileFirstLoginMode()}
|
|
||||||
* @see IdentityProviderRepresentation#UPFLM_ON
|
|
||||||
* @see IdentityProviderRepresentation#UPFLM_MISSING
|
|
||||||
* @see IdentityProviderRepresentation#UPFLM_OFF
|
|
||||||
*/
|
|
||||||
protected String updateProfileFirstLoginMode = IdentityProviderRepresentation.UPFLM_ON;
|
|
||||||
|
|
||||||
private boolean trustEmail;
|
private boolean trustEmail;
|
||||||
|
|
||||||
|
@ -81,7 +73,6 @@ public class IdentityProviderModel implements Serializable {
|
||||||
this.alias = model.getAlias();
|
this.alias = model.getAlias();
|
||||||
this.config = new HashMap<String, String>(model.getConfig());
|
this.config = new HashMap<String, String>(model.getConfig());
|
||||||
this.enabled = model.isEnabled();
|
this.enabled = model.isEnabled();
|
||||||
this.updateProfileFirstLoginMode = model.getUpdateProfileFirstLoginMode();
|
|
||||||
this.trustEmail = model.isTrustEmail();
|
this.trustEmail = model.isTrustEmail();
|
||||||
this.storeToken = model.isStoreToken();
|
this.storeToken = model.isStoreToken();
|
||||||
this.authenticateByDefault = model.isAuthenticateByDefault();
|
this.authenticateByDefault = model.isAuthenticateByDefault();
|
||||||
|
@ -121,20 +112,6 @@ public class IdentityProviderModel implements Serializable {
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IdentityProviderRepresentation#getUpdateProfileFirstLoginMode()
|
|
||||||
*/
|
|
||||||
public String getUpdateProfileFirstLoginMode() {
|
|
||||||
return updateProfileFirstLoginMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IdentityProviderRepresentation#setUpdateProfileFirstLoginMode(String)
|
|
||||||
*/
|
|
||||||
public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
|
|
||||||
this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStoreToken() {
|
public boolean isStoreToken() {
|
||||||
return this.storeToken;
|
return this.storeToken;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ public class IdentityProviderEntity {
|
||||||
private String providerId;
|
private String providerId;
|
||||||
private String name;
|
private String name;
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
private String updateProfileFirstLoginMode;
|
|
||||||
private boolean trustEmail;
|
private boolean trustEmail;
|
||||||
private boolean storeToken;
|
private boolean storeToken;
|
||||||
protected boolean addReadTokenRoleOnCreate;
|
protected boolean addReadTokenRoleOnCreate;
|
||||||
|
@ -63,14 +62,6 @@ public class IdentityProviderEntity {
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUpdateProfileFirstLoginMode() {
|
|
||||||
return updateProfileFirstLoginMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
|
|
||||||
this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAuthenticateByDefault() {
|
public boolean isAuthenticateByDefault() {
|
||||||
return authenticateByDefault;
|
return authenticateByDefault;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
package org.keycloak.models.utils;
|
package org.keycloak.models.utils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
import org.keycloak.models.AuthenticationFlowModel;
|
import org.keycloak.models.AuthenticationFlowModel;
|
||||||
|
import org.keycloak.models.AuthenticatorConfigModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RequiredCredentialModel;
|
import org.keycloak.models.RequiredCredentialModel;
|
||||||
|
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -21,6 +26,8 @@ public class DefaultAuthenticationFlows {
|
||||||
public static final String CLIENT_AUTHENTICATION_FLOW = "clients";
|
public static final String CLIENT_AUTHENTICATION_FLOW = "clients";
|
||||||
public static final String FIRST_BROKER_LOGIN_FLOW = "first broker login";
|
public static final String FIRST_BROKER_LOGIN_FLOW = "first broker login";
|
||||||
|
|
||||||
|
public static final String IDP_REVIEW_PROFILE_CONFIG_ALIAS = "review profile config";
|
||||||
|
|
||||||
public static void addFlows(RealmModel realm) {
|
public static void addFlows(RealmModel realm) {
|
||||||
if (realm.getFlowByAlias(BROWSER_FLOW) == null) browserFlow(realm);
|
if (realm.getFlowByAlias(BROWSER_FLOW) == null) browserFlow(realm);
|
||||||
if (realm.getFlowByAlias(DIRECT_GRANT_FLOW) == null) directGrantFlow(realm, false);
|
if (realm.getFlowByAlias(DIRECT_GRANT_FLOW) == null) directGrantFlow(realm, false);
|
||||||
|
@ -321,24 +328,41 @@ public class DefaultAuthenticationFlows {
|
||||||
firstBrokerLogin.setTopLevel(true);
|
firstBrokerLogin.setTopLevel(true);
|
||||||
firstBrokerLogin.setBuiltIn(true);
|
firstBrokerLogin.setBuiltIn(true);
|
||||||
firstBrokerLogin = realm.addAuthenticationFlow(firstBrokerLogin);
|
firstBrokerLogin = realm.addAuthenticationFlow(firstBrokerLogin);
|
||||||
// realm.setClientAuthenticationFlow(clients);
|
|
||||||
|
AuthenticatorConfigModel reviewProfileConfig = new AuthenticatorConfigModel();
|
||||||
|
reviewProfileConfig.setAlias(IDP_REVIEW_PROFILE_CONFIG_ALIAS);
|
||||||
|
Map<String, String> config = new HashMap<>();
|
||||||
|
config.put("update.profile.on.first.login", IdentityProviderRepresentation.UPFLM_MISSING);
|
||||||
|
reviewProfileConfig.setConfig(config);
|
||||||
|
reviewProfileConfig = realm.addAuthenticatorConfig(reviewProfileConfig);
|
||||||
|
|
||||||
AuthenticationExecutionModel execution = new AuthenticationExecutionModel();
|
AuthenticationExecutionModel execution = new AuthenticationExecutionModel();
|
||||||
execution.setParentFlow(firstBrokerLogin.getId());
|
execution.setParentFlow(firstBrokerLogin.getId());
|
||||||
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
|
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
|
||||||
execution.setAuthenticator("idp-update-profile");
|
execution.setAuthenticator("idp-review-profile");
|
||||||
execution.setPriority(10);
|
execution.setPriority(10);
|
||||||
execution.setAuthenticatorFlow(false);
|
execution.setAuthenticatorFlow(false);
|
||||||
|
execution.setAuthenticatorConfig(reviewProfileConfig.getId());
|
||||||
realm.addAuthenticatorExecution(execution);
|
realm.addAuthenticatorExecution(execution);
|
||||||
|
|
||||||
|
|
||||||
|
AuthenticatorConfigModel createUserIfUniqueConfig = new AuthenticatorConfigModel();
|
||||||
|
createUserIfUniqueConfig.setAlias("create unique user config");
|
||||||
|
config = new HashMap<>();
|
||||||
|
config.put("require.password.update.after.registration", "false");
|
||||||
|
createUserIfUniqueConfig.setConfig(config);
|
||||||
|
createUserIfUniqueConfig = realm.addAuthenticatorConfig(createUserIfUniqueConfig);
|
||||||
|
|
||||||
execution = new AuthenticationExecutionModel();
|
execution = new AuthenticationExecutionModel();
|
||||||
execution.setParentFlow(firstBrokerLogin.getId());
|
execution.setParentFlow(firstBrokerLogin.getId());
|
||||||
execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
|
execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
|
||||||
execution.setAuthenticator("idp-create-user-if-unique");
|
execution.setAuthenticator("idp-create-user-if-unique");
|
||||||
execution.setPriority(20);
|
execution.setPriority(20);
|
||||||
execution.setAuthenticatorFlow(false);
|
execution.setAuthenticatorFlow(false);
|
||||||
|
execution.setAuthenticatorConfig(createUserIfUniqueConfig.getId());
|
||||||
realm.addAuthenticatorExecution(execution);
|
realm.addAuthenticatorExecution(execution);
|
||||||
|
|
||||||
|
|
||||||
AuthenticationFlowModel linkExistingAccountFlow = new AuthenticationFlowModel();
|
AuthenticationFlowModel linkExistingAccountFlow = new AuthenticationFlowModel();
|
||||||
linkExistingAccountFlow.setTopLevel(false);
|
linkExistingAccountFlow.setTopLevel(false);
|
||||||
linkExistingAccountFlow.setBuiltIn(true);
|
linkExistingAccountFlow.setBuiltIn(true);
|
||||||
|
|
|
@ -389,7 +389,6 @@ public class ModelToRepresentation {
|
||||||
providerRep.setAlias(identityProviderModel.getAlias());
|
providerRep.setAlias(identityProviderModel.getAlias());
|
||||||
providerRep.setEnabled(identityProviderModel.isEnabled());
|
providerRep.setEnabled(identityProviderModel.isEnabled());
|
||||||
providerRep.setStoreToken(identityProviderModel.isStoreToken());
|
providerRep.setStoreToken(identityProviderModel.isStoreToken());
|
||||||
providerRep.setUpdateProfileFirstLoginMode(identityProviderModel.getUpdateProfileFirstLoginMode());
|
|
||||||
providerRep.setTrustEmail(identityProviderModel.isTrustEmail());
|
providerRep.setTrustEmail(identityProviderModel.isTrustEmail());
|
||||||
providerRep.setAuthenticateByDefault(identityProviderModel.isAuthenticateByDefault());
|
providerRep.setAuthenticateByDefault(identityProviderModel.isAuthenticateByDefault());
|
||||||
providerRep.setConfig(identityProviderModel.getConfig());
|
providerRep.setConfig(identityProviderModel.getConfig());
|
||||||
|
|
|
@ -1080,7 +1080,6 @@ public class RepresentationToModel {
|
||||||
identityProviderModel.setAlias(representation.getAlias());
|
identityProviderModel.setAlias(representation.getAlias());
|
||||||
identityProviderModel.setProviderId(representation.getProviderId());
|
identityProviderModel.setProviderId(representation.getProviderId());
|
||||||
identityProviderModel.setEnabled(representation.isEnabled());
|
identityProviderModel.setEnabled(representation.isEnabled());
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(representation.getUpdateProfileFirstLoginMode());
|
|
||||||
identityProviderModel.setTrustEmail(representation.isTrustEmail());
|
identityProviderModel.setTrustEmail(representation.isTrustEmail());
|
||||||
identityProviderModel.setAuthenticateByDefault(representation.isAuthenticateByDefault());
|
identityProviderModel.setAuthenticateByDefault(representation.isAuthenticateByDefault());
|
||||||
identityProviderModel.setStoreToken(representation.isStoreToken());
|
identityProviderModel.setStoreToken(representation.isStoreToken());
|
||||||
|
|
|
@ -1216,7 +1216,6 @@ public class RealmAdapter implements RealmModel {
|
||||||
identityProviderModel.setInternalId(entity.getInternalId());
|
identityProviderModel.setInternalId(entity.getInternalId());
|
||||||
identityProviderModel.setConfig(entity.getConfig());
|
identityProviderModel.setConfig(entity.getConfig());
|
||||||
identityProviderModel.setEnabled(entity.isEnabled());
|
identityProviderModel.setEnabled(entity.isEnabled());
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(entity.getUpdateProfileFirstLoginMode());
|
|
||||||
identityProviderModel.setTrustEmail(entity.isTrustEmail());
|
identityProviderModel.setTrustEmail(entity.isTrustEmail());
|
||||||
identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
|
identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
|
||||||
identityProviderModel.setFirstBrokerLoginFlowId(entity.getFirstBrokerLoginFlowId());
|
identityProviderModel.setFirstBrokerLoginFlowId(entity.getFirstBrokerLoginFlowId());
|
||||||
|
@ -1250,7 +1249,6 @@ public class RealmAdapter implements RealmModel {
|
||||||
entity.setEnabled(identityProvider.isEnabled());
|
entity.setEnabled(identityProvider.isEnabled());
|
||||||
entity.setStoreToken(identityProvider.isStoreToken());
|
entity.setStoreToken(identityProvider.isStoreToken());
|
||||||
entity.setAddReadTokenRoleOnCreate(identityProvider.isAddReadTokenRoleOnCreate());
|
entity.setAddReadTokenRoleOnCreate(identityProvider.isAddReadTokenRoleOnCreate());
|
||||||
entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
|
|
||||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||||
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
||||||
entity.setFirstBrokerLoginFlowId(identityProvider.getFirstBrokerLoginFlowId());
|
entity.setFirstBrokerLoginFlowId(identityProvider.getFirstBrokerLoginFlowId());
|
||||||
|
@ -1278,7 +1276,6 @@ public class RealmAdapter implements RealmModel {
|
||||||
if (entity.getInternalId().equals(identityProvider.getInternalId())) {
|
if (entity.getInternalId().equals(identityProvider.getInternalId())) {
|
||||||
entity.setAlias(identityProvider.getAlias());
|
entity.setAlias(identityProvider.getAlias());
|
||||||
entity.setEnabled(identityProvider.isEnabled());
|
entity.setEnabled(identityProvider.isEnabled());
|
||||||
entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
|
|
||||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||||
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
||||||
entity.setFirstBrokerLoginFlowId(identityProvider.getFirstBrokerLoginFlowId());
|
entity.setFirstBrokerLoginFlowId(identityProvider.getFirstBrokerLoginFlowId());
|
||||||
|
|
|
@ -42,9 +42,6 @@ public class IdentityProviderEntity {
|
||||||
@Column(name="ENABLED")
|
@Column(name="ENABLED")
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
|
||||||
@Column(name = "UPDATE_PROFILE_FIRST_LGN_MD")
|
|
||||||
private String updateProfileFirstLoginMode;
|
|
||||||
|
|
||||||
@Column(name = "TRUST_EMAIL")
|
@Column(name = "TRUST_EMAIL")
|
||||||
private boolean trustEmail;
|
private boolean trustEmail;
|
||||||
|
|
||||||
|
@ -106,14 +103,6 @@ public class IdentityProviderEntity {
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUpdateProfileFirstLoginMode() {
|
|
||||||
return updateProfileFirstLoginMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
|
|
||||||
this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStoreToken() {
|
public boolean isStoreToken() {
|
||||||
return this.storeToken;
|
return this.storeToken;
|
||||||
}
|
}
|
||||||
|
|
|
@ -823,7 +823,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
identityProviderModel.setInternalId(entity.getInternalId());
|
identityProviderModel.setInternalId(entity.getInternalId());
|
||||||
identityProviderModel.setConfig(entity.getConfig());
|
identityProviderModel.setConfig(entity.getConfig());
|
||||||
identityProviderModel.setEnabled(entity.isEnabled());
|
identityProviderModel.setEnabled(entity.isEnabled());
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(entity.getUpdateProfileFirstLoginMode());
|
|
||||||
identityProviderModel.setTrustEmail(entity.isTrustEmail());
|
identityProviderModel.setTrustEmail(entity.isTrustEmail());
|
||||||
identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
|
identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
|
||||||
identityProviderModel.setFirstBrokerLoginFlowId(entity.getFirstBrokerLoginFlowId());
|
identityProviderModel.setFirstBrokerLoginFlowId(entity.getFirstBrokerLoginFlowId());
|
||||||
|
@ -855,7 +854,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
entity.setAlias(identityProvider.getAlias());
|
entity.setAlias(identityProvider.getAlias());
|
||||||
entity.setProviderId(identityProvider.getProviderId());
|
entity.setProviderId(identityProvider.getProviderId());
|
||||||
entity.setEnabled(identityProvider.isEnabled());
|
entity.setEnabled(identityProvider.isEnabled());
|
||||||
entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
|
|
||||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||||
entity.setAddReadTokenRoleOnCreate(identityProvider.isAddReadTokenRoleOnCreate());
|
entity.setAddReadTokenRoleOnCreate(identityProvider.isAddReadTokenRoleOnCreate());
|
||||||
entity.setStoreToken(identityProvider.isStoreToken());
|
entity.setStoreToken(identityProvider.isStoreToken());
|
||||||
|
@ -884,7 +882,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
if (entity.getInternalId().equals(identityProvider.getInternalId())) {
|
if (entity.getInternalId().equals(identityProvider.getInternalId())) {
|
||||||
entity.setAlias(identityProvider.getAlias());
|
entity.setAlias(identityProvider.getAlias());
|
||||||
entity.setEnabled(identityProvider.isEnabled());
|
entity.setEnabled(identityProvider.isEnabled());
|
||||||
entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
|
|
||||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||||
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
||||||
entity.setFirstBrokerLoginFlowId(identityProvider.getFirstBrokerLoginFlowId());
|
entity.setFirstBrokerLoginFlowId(identityProvider.getFirstBrokerLoginFlowId());
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.login.LoginFormsProvider;
|
import org.keycloak.login.LoginFormsProvider;
|
||||||
|
import org.keycloak.models.AuthenticatorConfigModel;
|
||||||
import org.keycloak.models.IdentityProviderModel;
|
import org.keycloak.models.IdentityProviderModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
@ -26,9 +27,9 @@ import org.keycloak.services.validation.Validation;
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
public class IdpUpdateProfileAuthenticator extends AbstractIdpAuthenticator {
|
public class IdpReviewProfileAuthenticator extends AbstractIdpAuthenticator {
|
||||||
|
|
||||||
protected static Logger logger = Logger.getLogger(IdpUpdateProfileAuthenticator.class);
|
protected static Logger logger = Logger.getLogger(IdpReviewProfileAuthenticator.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean requiresUser() {
|
public boolean requiresUser() {
|
||||||
|
@ -61,10 +62,17 @@ public class IdpUpdateProfileAuthenticator extends AbstractIdpAuthenticator {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityProviderModel idpConfig = brokerContext.getIdpConfig();
|
String updateProfileFirstLogin;
|
||||||
|
AuthenticatorConfigModel authenticatorConfig = context.getAuthenticatorConfig();
|
||||||
|
if (authenticatorConfig == null || !authenticatorConfig.getConfig().containsKey(IdpReviewProfileAuthenticatorFactory.UPDATE_PROFILE_ON_FIRST_LOGIN)) {
|
||||||
|
updateProfileFirstLogin = IdentityProviderRepresentation.UPFLM_MISSING;
|
||||||
|
} else {
|
||||||
|
updateProfileFirstLogin = authenticatorConfig.getConfig().get(IdpReviewProfileAuthenticatorFactory.UPDATE_PROFILE_ON_FIRST_LOGIN);
|
||||||
|
}
|
||||||
|
|
||||||
RealmModel realm = context.getRealm();
|
RealmModel realm = context.getRealm();
|
||||||
return IdentityProviderRepresentation.UPFLM_ON.equals(idpConfig.getUpdateProfileFirstLoginMode())
|
return IdentityProviderRepresentation.UPFLM_ON.equals(updateProfileFirstLogin)
|
||||||
|| (IdentityProviderRepresentation.UPFLM_MISSING.equals(idpConfig.getUpdateProfileFirstLoginMode()) && !Validation.validateUserMandatoryFields(realm, userCtx));
|
|| (IdentityProviderRepresentation.UPFLM_MISSING.equals(updateProfileFirstLogin) && !Validation.validateUserMandatoryFields(realm, userCtx));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -0,0 +1,107 @@
|
||||||
|
package org.keycloak.authentication.authenticators.broker;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.keycloak.Config;
|
||||||
|
import org.keycloak.authentication.Authenticator;
|
||||||
|
import org.keycloak.authentication.AuthenticatorFactory;
|
||||||
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.provider.ProviderConfigProperty;
|
||||||
|
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class IdpReviewProfileAuthenticatorFactory implements AuthenticatorFactory {
|
||||||
|
|
||||||
|
public static final String PROVIDER_ID = "idp-review-profile";
|
||||||
|
static IdpReviewProfileAuthenticator SINGLETON = new IdpReviewProfileAuthenticator();
|
||||||
|
|
||||||
|
public static final String UPDATE_PROFILE_ON_FIRST_LOGIN = "update.profile.on.first.login";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authenticator create(KeycloakSession session) {
|
||||||
|
return SINGLETON;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Config.Scope config) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postInit(KeycloakSessionFactory factory) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return PROVIDER_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getReferenceCategory() {
|
||||||
|
return "reviewProfile";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isConfigurable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = {
|
||||||
|
AuthenticationExecutionModel.Requirement.REQUIRED,
|
||||||
|
AuthenticationExecutionModel.Requirement.DISABLED};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
|
||||||
|
return REQUIREMENT_CHOICES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayType() {
|
||||||
|
return "Review Profile";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelpText() {
|
||||||
|
return "User reviews and updates profile data retrieved from Identity Provider in the displayed form";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUserSetupAllowed() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
ProviderConfigProperty property;
|
||||||
|
property = new ProviderConfigProperty();
|
||||||
|
property.setName(UPDATE_PROFILE_ON_FIRST_LOGIN);
|
||||||
|
property.setLabel("{{:: 'update-profile-on-first-login' | translate}}");
|
||||||
|
property.setType(ProviderConfigProperty.LIST_TYPE);
|
||||||
|
List<String> updateProfileValues = Arrays.asList(IdentityProviderRepresentation.UPFLM_ON, IdentityProviderRepresentation.UPFLM_MISSING, IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
|
property.setDefaultValue(updateProfileValues);
|
||||||
|
property.setHelpText("Define conditions under which a user has to review and update his profile after first-time login. Value 'On' means that"
|
||||||
|
+ " page for reviewing profile will be displayed and user can review and update his profile. Value 'off' means that page won't be displayed."
|
||||||
|
+ " Value 'missing' means that page is displayed just when some required attribute is missing (wasn't downloaded from identity provider). Value 'missing' is the default one");
|
||||||
|
|
||||||
|
configProperties.add(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ProviderConfigProperty> getConfigProperties() {
|
||||||
|
return configProperties;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,84 +0,0 @@
|
||||||
package org.keycloak.authentication.authenticators.broker;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.keycloak.Config;
|
|
||||||
import org.keycloak.authentication.Authenticator;
|
|
||||||
import org.keycloak.authentication.AuthenticatorFactory;
|
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
|
||||||
import org.keycloak.provider.ProviderConfigProperty;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class IdpUpdateProfileAuthenticatorFactory implements AuthenticatorFactory {
|
|
||||||
|
|
||||||
public static final String PROVIDER_ID = "idp-update-profile";
|
|
||||||
static IdpUpdateProfileAuthenticator SINGLETON = new IdpUpdateProfileAuthenticator();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Authenticator create(KeycloakSession session) {
|
|
||||||
return SINGLETON;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Config.Scope config) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postInit(KeycloakSessionFactory factory) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return PROVIDER_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getReferenceCategory() {
|
|
||||||
return "updateProfile";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isConfigurable() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = {
|
|
||||||
AuthenticationExecutionModel.Requirement.REQUIRED,
|
|
||||||
AuthenticationExecutionModel.Requirement.DISABLED};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
|
|
||||||
return REQUIREMENT_CHOICES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDisplayType() {
|
|
||||||
return "Update Profile";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHelpText() {
|
|
||||||
return "Updates profile data retrieved from Identity Provider in the displayed form";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<ProviderConfigProperty> getConfigProperties() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isUserSetupAllowed() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,7 +9,7 @@ org.keycloak.authentication.authenticators.resetcred.ResetCredentialChooseUser
|
||||||
org.keycloak.authentication.authenticators.resetcred.ResetCredentialEmail
|
org.keycloak.authentication.authenticators.resetcred.ResetCredentialEmail
|
||||||
org.keycloak.authentication.authenticators.resetcred.ResetOTP
|
org.keycloak.authentication.authenticators.resetcred.ResetOTP
|
||||||
org.keycloak.authentication.authenticators.resetcred.ResetPassword
|
org.keycloak.authentication.authenticators.resetcred.ResetPassword
|
||||||
org.keycloak.authentication.authenticators.broker.IdpUpdateProfileAuthenticatorFactory
|
org.keycloak.authentication.authenticators.broker.IdpReviewProfileAuthenticatorFactory
|
||||||
org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticatorFactory
|
org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticatorFactory
|
||||||
org.keycloak.authentication.authenticators.broker.IdpConfirmLinkAuthenticatorFactory
|
org.keycloak.authentication.authenticators.broker.IdpConfirmLinkAuthenticatorFactory
|
||||||
org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticatorFactory
|
org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticatorFactory
|
||||||
|
|
|
@ -52,7 +52,6 @@ public class IdentityProviderTest extends AbstractClientTest {
|
||||||
assertEquals("clientSecret", representation.getConfig().get("clientSecret"));
|
assertEquals("clientSecret", representation.getConfig().get("clientSecret"));
|
||||||
assertTrue(representation.isEnabled());
|
assertTrue(representation.isEnabled());
|
||||||
assertFalse(representation.isStoreToken());
|
assertFalse(representation.isStoreToken());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_ON, representation.getUpdateProfileFirstLoginMode());
|
|
||||||
assertFalse(representation.isTrustEmail());
|
assertFalse(representation.isTrustEmail());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,15 +23,20 @@ import org.junit.Before;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.authentication.authenticators.broker.IdpReviewProfileAuthenticatorFactory;
|
||||||
|
import org.keycloak.models.AuthenticatorConfigModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.FederatedIdentityModel;
|
import org.keycloak.models.FederatedIdentityModel;
|
||||||
import org.keycloak.models.IdentityProviderModel;
|
import org.keycloak.models.IdentityProviderModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.KeycloakSessionTask;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserModel.RequiredAction;
|
import org.keycloak.models.UserModel.RequiredAction;
|
||||||
|
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.representations.IDToken;
|
import org.keycloak.representations.IDToken;
|
||||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||||
import org.keycloak.services.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
@ -138,7 +143,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulAuthentication() {
|
public void testSuccessfulAuthentication() {
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_ON);
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_ON);
|
||||||
|
|
||||||
UserModel user = assertSuccessfulAuthentication(identityProviderModel, "test-user", "new@email.com", true);
|
UserModel user = assertSuccessfulAuthentication(identityProviderModel, "test-user", "new@email.com", true);
|
||||||
Assert.assertEquals("617-666-7777", user.getFirstAttribute("mobile"));
|
Assert.assertEquals("617-666-7777", user.getFirstAttribute("mobile"));
|
||||||
|
@ -147,7 +152,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulAuthenticationUpdateProfileOnMissing_nothingMissing() {
|
public void testSuccessfulAuthenticationUpdateProfileOnMissing_nothingMissing() {
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_MISSING);
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_MISSING);
|
||||||
|
|
||||||
assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
|
assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
|
||||||
}
|
}
|
||||||
|
@ -155,7 +160,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulAuthenticationUpdateProfileOnMissing_missingEmail() {
|
public void testSuccessfulAuthenticationUpdateProfileOnMissing_missingEmail() {
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_MISSING);
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_MISSING);
|
||||||
|
|
||||||
assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", "new@email.com", true);
|
assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", "new@email.com", true);
|
||||||
}
|
}
|
||||||
|
@ -163,7 +168,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulAuthenticationWithoutUpdateProfile() {
|
public void testSuccessfulAuthenticationWithoutUpdateProfile() {
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
|
|
||||||
assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
|
assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
|
||||||
}
|
}
|
||||||
|
@ -182,7 +187,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
|
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
try {
|
try {
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
identityProviderModel.setTrustEmail(false);
|
identityProviderModel.setTrustEmail(false);
|
||||||
|
|
||||||
UserModel federatedUser = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "test-user@localhost", false);
|
UserModel federatedUser = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "test-user@localhost", false);
|
||||||
|
@ -251,7 +256,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
|
|
||||||
UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", null, false);
|
UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", null, false);
|
||||||
|
|
||||||
|
@ -268,12 +273,12 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulAuthenticationWithoutUpdateProfile_emailProvided_emailVerifyEnabled_emailTrustEnabled() {
|
public void testSuccessfulAuthenticationWithoutUpdateProfile_emailProvided_emailVerifyEnabled_emailTrustEnabled() {
|
||||||
getRealm().setVerifyEmail(true);
|
getRealm().setVerifyEmail(true);
|
||||||
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
brokerServerRule.stopSession(this.session, true);
|
brokerServerRule.stopSession(this.session, true);
|
||||||
this.session = brokerServerRule.startSession();
|
this.session = brokerServerRule.startSession();
|
||||||
|
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
try {
|
try {
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
|
||||||
identityProviderModel.setTrustEmail(true);
|
identityProviderModel.setTrustEmail(true);
|
||||||
|
|
||||||
UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
|
UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
|
||||||
|
@ -300,7 +305,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
|
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
try {
|
try {
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_ON);
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_ON);
|
||||||
identityProviderModel.setTrustEmail(true);
|
identityProviderModel.setTrustEmail(true);
|
||||||
|
|
||||||
UserModel user = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "new@email.com", true);
|
UserModel user = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "new@email.com", true);
|
||||||
|
@ -320,7 +325,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
|
|
||||||
authenticateWithIdentityProvider(identityProviderModel, "test-user", false);
|
authenticateWithIdentityProvider(identityProviderModel, "test-user", false);
|
||||||
|
|
||||||
|
@ -368,7 +373,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
|
|
||||||
authenticateWithIdentityProvider(identityProviderModel, "test-user-noemail", false);
|
authenticateWithIdentityProvider(identityProviderModel, "test-user-noemail", false);
|
||||||
|
|
||||||
|
@ -475,7 +480,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
public void testUserAlreadyExistsWhenNotUpdatingProfile() {
|
public void testUserAlreadyExistsWhenNotUpdatingProfile() {
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
|
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
|
|
||||||
this.driver.navigate().to("http://localhost:8081/test-app/");
|
this.driver.navigate().to("http://localhost:8081/test-app/");
|
||||||
|
|
||||||
|
@ -509,6 +514,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
|
|
||||||
// Link my "pedroigor" identity with "test-user" from brokered Keycloak
|
// Link my "pedroigor" identity with "test-user" from brokered Keycloak
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_ON);
|
||||||
accountFederatedIdentityPage.clickAddProvider(identityProviderModel.getAlias());
|
accountFederatedIdentityPage.clickAddProvider(identityProviderModel.getAlias());
|
||||||
|
|
||||||
assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8082/auth/"));
|
assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8082/auth/"));
|
||||||
|
@ -609,6 +615,7 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTokenStorageAndRetrievalByApplication() {
|
public void testTokenStorageAndRetrievalByApplication() {
|
||||||
|
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_ON);
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
|
|
||||||
identityProviderModel.setStoreToken(true);
|
identityProviderModel.setStoreToken(true);
|
||||||
|
@ -774,7 +781,6 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
|
|
||||||
assertNotNull(identityProviderModel);
|
assertNotNull(identityProviderModel);
|
||||||
|
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_ON);
|
|
||||||
identityProviderModel.setEnabled(true);
|
identityProviderModel.setEnabled(true);
|
||||||
|
|
||||||
return identityProviderModel;
|
return identityProviderModel;
|
||||||
|
@ -851,4 +857,18 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
|
|
||||||
return htmlVerificationUrl;
|
return htmlVerificationUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setUpdateProfileFirstLogin(final String updateProfileFirstLogin) {
|
||||||
|
KeycloakModelUtils.runJobInTransaction(this.session.getKeycloakSessionFactory(), new KeycloakSessionTask() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(KeycloakSession session) {
|
||||||
|
RealmModel realm = session.realms().getRealm("realm-with-broker");
|
||||||
|
AuthenticatorConfigModel reviewProfileConfig = realm.getAuthenticatorConfigByAlias(DefaultAuthenticationFlows.IDP_REVIEW_PROFILE_CONFIG_ALIAS);
|
||||||
|
reviewProfileConfig.getConfig().put(IdpReviewProfileAuthenticatorFactory.UPDATE_PROFILE_ON_FIRST_LOGIN, updateProfileFirstLogin);
|
||||||
|
realm.updateAuthenticatorConfig(reviewProfileConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
|
|
||||||
identityProviderModel.getConfig().put("config-added", "value-added");
|
identityProviderModel.getConfig().put("config-added", "value-added");
|
||||||
identityProviderModel.setEnabled(false);
|
identityProviderModel.setEnabled(false);
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
|
||||||
identityProviderModel.setTrustEmail(true);
|
identityProviderModel.setTrustEmail(true);
|
||||||
identityProviderModel.setStoreToken(true);
|
identityProviderModel.setStoreToken(true);
|
||||||
identityProviderModel.setAuthenticateByDefault(true);
|
identityProviderModel.setAuthenticateByDefault(true);
|
||||||
|
@ -97,7 +96,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
|
|
||||||
assertEquals("value-added", identityProviderModel.getConfig().get("config-added"));
|
assertEquals("value-added", identityProviderModel.getConfig().get("config-added"));
|
||||||
assertFalse(identityProviderModel.isEnabled());
|
assertFalse(identityProviderModel.isEnabled());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_OFF, identityProviderModel.getUpdateProfileFirstLoginMode());
|
|
||||||
assertTrue(identityProviderModel.isTrustEmail());
|
assertTrue(identityProviderModel.isTrustEmail());
|
||||||
assertTrue(identityProviderModel.isStoreToken());
|
assertTrue(identityProviderModel.isStoreToken());
|
||||||
assertTrue(identityProviderModel.isAuthenticateByDefault());
|
assertTrue(identityProviderModel.isAuthenticateByDefault());
|
||||||
|
@ -105,7 +103,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
|
|
||||||
identityProviderModel.getConfig().remove("config-added");
|
identityProviderModel.getConfig().remove("config-added");
|
||||||
identityProviderModel.setEnabled(true);
|
identityProviderModel.setEnabled(true);
|
||||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_MISSING);
|
|
||||||
identityProviderModel.setTrustEmail(false);
|
identityProviderModel.setTrustEmail(false);
|
||||||
identityProviderModel.setAuthenticateByDefault(false);
|
identityProviderModel.setAuthenticateByDefault(false);
|
||||||
|
|
||||||
|
@ -118,7 +115,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
|
|
||||||
assertFalse(identityProviderModel.getConfig().containsKey("config-added"));
|
assertFalse(identityProviderModel.getConfig().containsKey("config-added"));
|
||||||
assertTrue(identityProviderModel.isEnabled());
|
assertTrue(identityProviderModel.isEnabled());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_MISSING, identityProviderModel.getUpdateProfileFirstLoginMode());
|
|
||||||
assertFalse(identityProviderModel.isTrustEmail());
|
assertFalse(identityProviderModel.isTrustEmail());
|
||||||
assertFalse(identityProviderModel.isAuthenticateByDefault());
|
assertFalse(identityProviderModel.isAuthenticateByDefault());
|
||||||
this.realmManager.removeRealm(realm);
|
this.realmManager.removeRealm(realm);
|
||||||
|
@ -167,7 +163,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
assertEquals("model-google", config.getAlias());
|
assertEquals("model-google", config.getAlias());
|
||||||
assertEquals(GoogleIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
assertEquals(GoogleIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||||
assertEquals(true, config.isEnabled());
|
assertEquals(true, config.isEnabled());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_ON, config.getUpdateProfileFirstLoginMode());
|
|
||||||
assertEquals(true, config.isTrustEmail());
|
assertEquals(true, config.isTrustEmail());
|
||||||
assertEquals(false, config.isAuthenticateByDefault());
|
assertEquals(false, config.isAuthenticateByDefault());
|
||||||
assertEquals(true, config.isStoreToken());
|
assertEquals(true, config.isStoreToken());
|
||||||
|
@ -186,7 +181,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
assertEquals("model-saml-signed-idp", config.getAlias());
|
assertEquals("model-saml-signed-idp", config.getAlias());
|
||||||
assertEquals(SAMLIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
assertEquals(SAMLIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||||
assertEquals(true, config.isEnabled());
|
assertEquals(true, config.isEnabled());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_ON, config.getUpdateProfileFirstLoginMode());
|
|
||||||
assertEquals(false, config.isAuthenticateByDefault());
|
assertEquals(false, config.isAuthenticateByDefault());
|
||||||
assertEquals(false, config.isTrustEmail());
|
assertEquals(false, config.isTrustEmail());
|
||||||
assertEquals(false, config.isStoreToken());
|
assertEquals(false, config.isStoreToken());
|
||||||
|
@ -207,7 +201,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
assertEquals("model-oidc-idp", config.getAlias());
|
assertEquals("model-oidc-idp", config.getAlias());
|
||||||
assertEquals(OIDCIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
assertEquals(OIDCIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||||
assertEquals(false, config.isEnabled());
|
assertEquals(false, config.isEnabled());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
|
|
||||||
assertEquals(false, config.isTrustEmail());
|
assertEquals(false, config.isTrustEmail());
|
||||||
assertEquals(false, config.isAuthenticateByDefault());
|
assertEquals(false, config.isAuthenticateByDefault());
|
||||||
assertEquals(false, config.isStoreToken());
|
assertEquals(false, config.isStoreToken());
|
||||||
|
@ -222,7 +215,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
assertEquals("model-facebook", config.getAlias());
|
assertEquals("model-facebook", config.getAlias());
|
||||||
assertEquals(FacebookIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
assertEquals(FacebookIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||||
assertEquals(true, config.isEnabled());
|
assertEquals(true, config.isEnabled());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
|
|
||||||
assertEquals(false, config.isTrustEmail());
|
assertEquals(false, config.isTrustEmail());
|
||||||
assertEquals(false, config.isAuthenticateByDefault());
|
assertEquals(false, config.isAuthenticateByDefault());
|
||||||
assertEquals(false, config.isStoreToken());
|
assertEquals(false, config.isStoreToken());
|
||||||
|
@ -241,7 +233,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
assertEquals("model-github", config.getAlias());
|
assertEquals("model-github", config.getAlias());
|
||||||
assertEquals(GitHubIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
assertEquals(GitHubIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||||
assertEquals(true, config.isEnabled());
|
assertEquals(true, config.isEnabled());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_ON, config.getUpdateProfileFirstLoginMode());
|
|
||||||
assertEquals(false, config.isTrustEmail());
|
assertEquals(false, config.isTrustEmail());
|
||||||
assertEquals(false, config.isAuthenticateByDefault());
|
assertEquals(false, config.isAuthenticateByDefault());
|
||||||
assertEquals(false, config.isStoreToken());
|
assertEquals(false, config.isStoreToken());
|
||||||
|
@ -258,17 +249,16 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
OAuth2IdentityProviderConfig config = liIdentityProvider.getConfig();
|
OAuth2IdentityProviderConfig config = liIdentityProvider.getConfig();
|
||||||
|
|
||||||
assertEquals("model-linkedin", config.getAlias());
|
assertEquals("model-linkedin", config.getAlias());
|
||||||
assertEquals(LinkedInIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
assertEquals(LinkedInIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||||
assertEquals(true, config.isEnabled());
|
assertEquals(true, config.isEnabled());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_MISSING, config.getUpdateProfileFirstLoginMode());
|
|
||||||
assertEquals(false, config.isTrustEmail());
|
assertEquals(false, config.isTrustEmail());
|
||||||
assertEquals(false, config.isAuthenticateByDefault());
|
assertEquals(false, config.isAuthenticateByDefault());
|
||||||
assertEquals(false, config.isStoreToken());
|
assertEquals(false, config.isStoreToken());
|
||||||
assertEquals("clientId", config.getClientId());
|
assertEquals("clientId", config.getClientId());
|
||||||
assertEquals("clientSecret", config.getClientSecret());
|
assertEquals("clientSecret", config.getClientSecret());
|
||||||
assertEquals(LinkedInIdentityProvider.AUTH_URL, config.getAuthorizationUrl());
|
assertEquals(LinkedInIdentityProvider.AUTH_URL, config.getAuthorizationUrl());
|
||||||
assertEquals(LinkedInIdentityProvider.TOKEN_URL, config.getTokenUrl());
|
assertEquals(LinkedInIdentityProvider.TOKEN_URL, config.getTokenUrl());
|
||||||
assertEquals(LinkedInIdentityProvider.PROFILE_URL, config.getUserInfoUrl());
|
assertEquals(LinkedInIdentityProvider.PROFILE_URL, config.getUserInfoUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertStackoverflowIdentityProviderConfig(IdentityProviderModel identityProvider) {
|
private void assertStackoverflowIdentityProviderConfig(IdentityProviderModel identityProvider) {
|
||||||
|
@ -278,7 +268,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
assertEquals("model-stackoverflow", config.getAlias());
|
assertEquals("model-stackoverflow", config.getAlias());
|
||||||
assertEquals(StackoverflowIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
assertEquals(StackoverflowIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||||
assertEquals(true, config.isEnabled());
|
assertEquals(true, config.isEnabled());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
|
|
||||||
assertEquals(false, config.isTrustEmail());
|
assertEquals(false, config.isTrustEmail());
|
||||||
assertEquals(false, config.isAuthenticateByDefault());
|
assertEquals(false, config.isAuthenticateByDefault());
|
||||||
assertEquals(false, config.isStoreToken());
|
assertEquals(false, config.isStoreToken());
|
||||||
|
@ -297,7 +286,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
||||||
assertEquals("model-twitter", config.getAlias());
|
assertEquals("model-twitter", config.getAlias());
|
||||||
assertEquals(TwitterIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
assertEquals(TwitterIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||||
assertEquals(true, config.isEnabled());
|
assertEquals(true, config.isEnabled());
|
||||||
assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
|
|
||||||
assertEquals(false, config.isTrustEmail());
|
assertEquals(false, config.isTrustEmail());
|
||||||
assertEquals(false, config.isAuthenticateByDefault());
|
assertEquals(false, config.isAuthenticateByDefault());
|
||||||
assertEquals(true, config.isStoreToken());
|
assertEquals(true, config.isStoreToken());
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
"alias" : "model-google",
|
"alias" : "model-google",
|
||||||
"providerId" : "google",
|
"providerId" : "google",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"updateProfileFirstLogin" : "true",
|
|
||||||
"trustEmail" : "true",
|
"trustEmail" : "true",
|
||||||
"storeToken": "true",
|
"storeToken": "true",
|
||||||
"config": {
|
"config": {
|
||||||
|
@ -29,7 +28,6 @@
|
||||||
"alias" : "model-facebook",
|
"alias" : "model-facebook",
|
||||||
"providerId" : "facebook",
|
"providerId" : "facebook",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"updateProfileFirstLogin" : "false",
|
|
||||||
"firstBrokerLoginFlowAlias" : "browser",
|
"firstBrokerLoginFlowAlias" : "browser",
|
||||||
"config": {
|
"config": {
|
||||||
"authorizationUrl": "authorizationUrl",
|
"authorizationUrl": "authorizationUrl",
|
||||||
|
@ -43,7 +41,6 @@
|
||||||
"alias" : "model-github",
|
"alias" : "model-github",
|
||||||
"providerId" : "github",
|
"providerId" : "github",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"updateProfileFirstLoginMode" : "on",
|
|
||||||
"storeToken": "false",
|
"storeToken": "false",
|
||||||
"config": {
|
"config": {
|
||||||
"authorizationUrl": "authorizationUrl",
|
"authorizationUrl": "authorizationUrl",
|
||||||
|
@ -57,7 +54,6 @@
|
||||||
"alias" : "model-twitter",
|
"alias" : "model-twitter",
|
||||||
"providerId" : "twitter",
|
"providerId" : "twitter",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"updateProfileFirstLoginMode" : "off",
|
|
||||||
"storeToken": true,
|
"storeToken": true,
|
||||||
"config": {
|
"config": {
|
||||||
"authorizationUrl": "authorizationUrl",
|
"authorizationUrl": "authorizationUrl",
|
||||||
|
@ -71,7 +67,6 @@
|
||||||
"alias" : "model-linkedin",
|
"alias" : "model-linkedin",
|
||||||
"providerId" : "linkedin",
|
"providerId" : "linkedin",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"updateProfileFirstLoginMode" : "missing",
|
|
||||||
"storeToken": false,
|
"storeToken": false,
|
||||||
"config": {
|
"config": {
|
||||||
"authorizationUrl": "authorizationUrl",
|
"authorizationUrl": "authorizationUrl",
|
||||||
|
@ -85,7 +80,6 @@
|
||||||
"alias" : "model-stackoverflow",
|
"alias" : "model-stackoverflow",
|
||||||
"providerId" : "stackoverflow",
|
"providerId" : "stackoverflow",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"updateProfileFirstLoginMode" : "off",
|
|
||||||
"storeToken": false,
|
"storeToken": false,
|
||||||
"config": {
|
"config": {
|
||||||
"key": "keyValue",
|
"key": "keyValue",
|
||||||
|
@ -100,7 +94,6 @@
|
||||||
"alias" : "model-saml-signed-idp",
|
"alias" : "model-saml-signed-idp",
|
||||||
"providerId" : "saml",
|
"providerId" : "saml",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"updateProfileFirstLoginMode" : "on",
|
|
||||||
"config": {
|
"config": {
|
||||||
"singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-identity-provider/protocol/saml",
|
"singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-identity-provider/protocol/saml",
|
||||||
"nameIDPolicyFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
|
"nameIDPolicyFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
|
||||||
|
@ -116,7 +109,6 @@
|
||||||
"alias" : "kc-saml-signed-idp",
|
"alias" : "kc-saml-signed-idp",
|
||||||
"providerId" : "saml",
|
"providerId" : "saml",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"updateProfileFirstLoginMode" : "on",
|
|
||||||
"addReadTokenRoleOnCreate": true,
|
"addReadTokenRoleOnCreate": true,
|
||||||
"config": {
|
"config": {
|
||||||
"singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-signed-idp/protocol/saml",
|
"singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-signed-idp/protocol/saml",
|
||||||
|
@ -135,7 +127,6 @@
|
||||||
"alias" : "kc-saml-idp-basic",
|
"alias" : "kc-saml-idp-basic",
|
||||||
"providerId" : "saml",
|
"providerId" : "saml",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"updateProfileFirstLoginMode" : "on",
|
|
||||||
"trustEmail" : false,
|
"trustEmail" : false,
|
||||||
"addReadTokenRoleOnCreate": true,
|
"addReadTokenRoleOnCreate": true,
|
||||||
"config": {
|
"config": {
|
||||||
|
@ -151,7 +142,6 @@
|
||||||
"alias" : "model-oidc-idp",
|
"alias" : "model-oidc-idp",
|
||||||
"providerId" : "oidc",
|
"providerId" : "oidc",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"updateProfileFirstLoginMode" : "off",
|
|
||||||
"authenticateByDefault" : "false",
|
"authenticateByDefault" : "false",
|
||||||
"config": {
|
"config": {
|
||||||
"clientId": "clientId",
|
"clientId": "clientId",
|
||||||
|
@ -167,7 +157,6 @@
|
||||||
"alias" : "kc-oidc-idp",
|
"alias" : "kc-oidc-idp",
|
||||||
"providerId" : "keycloak-oidc",
|
"providerId" : "keycloak-oidc",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"updateProfileFirstLoginMode" : "off",
|
|
||||||
"storeToken" : true,
|
"storeToken" : true,
|
||||||
"addReadTokenRoleOnCreate": true,
|
"addReadTokenRoleOnCreate": true,
|
||||||
"config": {
|
"config": {
|
||||||
|
|
Loading…
Reference in a new issue