Merge pull request #1804 from mposolda/broker-reauthentication
KEYCLOAK-1750 First broker login changes
This commit is contained in:
commit
caea1a3458
30 changed files with 277 additions and 272 deletions
|
@ -7,6 +7,7 @@
|
|||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
<dropColumn tableName="IDENTITY_PROVIDER" columnName="UPDATE_PROFILE_FIRST_LGN_MD"/>
|
||||
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
|
@ -46,6 +46,7 @@ public class IdentityProviderRepresentation {
|
|||
* @see #UPFLM_MISSING
|
||||
* @see #UPFLM_OFF
|
||||
*/
|
||||
@Deprecated
|
||||
protected String updateProfileFirstLoginMode = UPFLM_ON;
|
||||
|
||||
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() {
|
||||
return updateProfileFirstLoginMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param updateProfileFirstLoginMode see {@link #updateProfileFirstLoginMode}
|
||||
* @deprecated deprecated and replaced by configuration on IdpReviewProfileAuthenticator
|
||||
*/
|
||||
@Deprecated
|
||||
public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
|
||||
this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
|
||||
}
|
||||
|
|
|
@ -79,16 +79,34 @@
|
|||
|
||||
<section>
|
||||
<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>
|
||||
<title>Migrating to 1.6.0.Final</title>
|
||||
<simplesect>
|
||||
<title>Refresh tokens are not reusable anymore</title>
|
||||
<title>Option that refresh tokens are not reusable anymore</title>
|
||||
<para>
|
||||
Old versions of Keycloak allowed reusing refresh tokens multiple times. Keycloak no longer permits
|
||||
this by default. When a refresh token is used to obtain a new access token a new refresh token is also
|
||||
included. This new refresh token should be used next time the access token is refreshed. If this is
|
||||
a problem for you it's possible to enable reuse of refresh tokens in the admin console under token
|
||||
settings.
|
||||
Old versions of Keycloak allowed reusing refresh tokens multiple times. Keycloak still permits this,
|
||||
but also have an option <literal>Revoke refresh token</literal> to disallow it. Option is in in admin console under token settings.
|
||||
When a refresh token is used to obtain a new access token a new refresh token is also
|
||||
included. When option is enabled, then this new refresh token should be used next time the access token is refreshed.
|
||||
It won't be possible to reuse old refresh token multiple times.
|
||||
</para>
|
||||
</simplesect>
|
||||
<simplesect>
|
||||
|
|
|
@ -1348,12 +1348,15 @@ module.config([ '$routeProvider', function($routeProvider) {
|
|||
},
|
||||
controller : 'RealmOtpPolicyCtrl'
|
||||
})
|
||||
.when('/realms/:realm/authentication/config/:provider/:config', {
|
||||
.when('/realms/:realm/authentication/flows/:flow/config/:provider/:config', {
|
||||
templateUrl : resourceUrl + '/partials/authenticator-config.html',
|
||||
resolve : {
|
||||
realm : function(RealmLoader) {
|
||||
return RealmLoader();
|
||||
},
|
||||
flow : function(AuthenticationFlowLoader) {
|
||||
return AuthenticationFlowLoader();
|
||||
},
|
||||
configType : function(AuthenticationConfigDescriptionLoader) {
|
||||
return AuthenticationConfigDescriptionLoader();
|
||||
},
|
||||
|
@ -1363,12 +1366,15 @@ module.config([ '$routeProvider', function($routeProvider) {
|
|||
},
|
||||
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',
|
||||
resolve : {
|
||||
realm : function(RealmLoader) {
|
||||
return RealmLoader();
|
||||
},
|
||||
flow : function(AuthenticationFlowLoader) {
|
||||
return AuthenticationFlowLoader();
|
||||
},
|
||||
configType : function(AuthenticationConfigDescriptionLoader) {
|
||||
return AuthenticationConfigDescriptionLoader();
|
||||
},
|
||||
|
|
|
@ -599,15 +599,6 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
|
|||
|
||||
$scope.realm = angular.copy(realm);
|
||||
|
||||
$scope.initProvider = function() {
|
||||
if (instance && instance.alias) {
|
||||
|
||||
} else {
|
||||
$scope.identityProvider.updateProfileFirstLoginMode = "on";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.initSamlProvider = function() {
|
||||
$scope.nameIdFormats = [
|
||||
/*
|
||||
|
@ -658,7 +649,6 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
|
|||
} else {
|
||||
$scope.identityProvider.config.nameIDPolicyFormat = $scope.nameIdFormats[0].format;
|
||||
$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.providerId = providerFactory.id;
|
||||
$scope.identityProvider.enabled = true;
|
||||
$scope.identityProvider.updateProfileFirstLoginMode = "off";
|
||||
$scope.identityProvider.authenticateByDefault = false;
|
||||
$scope.identityProvider.firstBrokerLoginFlowAlias = 'first broker login';
|
||||
$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.flow = flow;
|
||||
$scope.configType = configType;
|
||||
$scope.create = false;
|
||||
$scope.config = angular.copy(config);
|
||||
|
@ -1935,7 +1925,7 @@ module.controller('AuthenticationConfigCtrl', function($scope, realm, configType
|
|||
}, $scope.config, function() {
|
||||
$scope.changed = false;
|
||||
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.");
|
||||
});
|
||||
};
|
||||
|
@ -1954,15 +1944,16 @@ module.controller('AuthenticationConfigCtrl', function($scope, realm, configType
|
|||
Dialog.confirmDelete($scope.config.alias, 'config', function() {
|
||||
AuthenticationConfig.remove({ realm: realm.realm, config : $scope.config.id }, function() {
|
||||
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.flow = flow;
|
||||
$scope.create = true;
|
||||
$scope.config = { config: {}};
|
||||
$scope.configType = configType;
|
||||
|
@ -1980,7 +1971,7 @@ module.controller('AuthenticationConfigCreateCtrl', function($scope, realm, conf
|
|||
}, $scope.config, function(data, headers) {
|
||||
var l = headers().location;
|
||||
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);
|
||||
$location.url(url);
|
||||
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 || !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-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="#/realms/{{realm.realm}}/authentication/config/{{execution.providerId}}/{{execution.authenticationConfig}}">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/flows/{{flow.id}}/config/{{execution.providerId}}/{{execution.authenticationConfig}}">Config</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
<ol class="breadcrumb">
|
||||
<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-hide="create">{{config.alias}}</li>
|
||||
</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">
|
||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
||||
<li>{{identityProvider.alias}}</li>
|
||||
|
@ -52,19 +52,6 @@
|
|||
</div>
|
||||
<kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip>
|
||||
</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">
|
||||
<label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label>
|
||||
<div class="col-md-6">
|
||||
|
|
|
@ -52,19 +52,6 @@
|
|||
</div>
|
||||
<kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip>
|
||||
</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">
|
||||
<label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label>
|
||||
<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">
|
||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
||||
<li>{{identityProvider.alias}}</li>
|
||||
|
@ -63,19 +63,6 @@
|
|||
</div>
|
||||
<kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip>
|
||||
</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">
|
||||
<label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label>
|
||||
<div class="col-md-6">
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<form id="kc-register-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||
|
||||
<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>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ federatedIdentityExistsMessage=User with {0} {1} already exists. Please login to
|
|||
confirmLinkIdpTitle=Account already exists
|
||||
federatedIdentityConfirmLinkMessage=User with {0} {1} already exists. How do you want to continue?
|
||||
federatedIdentityConfirmReauthenticateMessage=Authenticate as {0} to link your account with {1}
|
||||
confirmLinkIdpUpdateProfile=Update profile info
|
||||
confirmLinkIdpReviewProfile=Review profile info
|
||||
confirmLinkIdpContinue=Link {0} with existing 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 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;
|
||||
|
||||
|
@ -81,7 +73,6 @@ public class IdentityProviderModel implements Serializable {
|
|||
this.alias = model.getAlias();
|
||||
this.config = new HashMap<String, String>(model.getConfig());
|
||||
this.enabled = model.isEnabled();
|
||||
this.updateProfileFirstLoginMode = model.getUpdateProfileFirstLoginMode();
|
||||
this.trustEmail = model.isTrustEmail();
|
||||
this.storeToken = model.isStoreToken();
|
||||
this.authenticateByDefault = model.isAuthenticateByDefault();
|
||||
|
@ -121,20 +112,6 @@ public class IdentityProviderModel implements Serializable {
|
|||
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() {
|
||||
return this.storeToken;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ public class IdentityProviderEntity {
|
|||
private String providerId;
|
||||
private String name;
|
||||
private boolean enabled;
|
||||
private String updateProfileFirstLoginMode;
|
||||
private boolean trustEmail;
|
||||
private boolean storeToken;
|
||||
protected boolean addReadTokenRoleOnCreate;
|
||||
|
@ -63,14 +62,6 @@ public class IdentityProviderEntity {
|
|||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getUpdateProfileFirstLoginMode() {
|
||||
return updateProfileFirstLoginMode;
|
||||
}
|
||||
|
||||
public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
|
||||
this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
|
||||
}
|
||||
|
||||
public boolean isAuthenticateByDefault() {
|
||||
return authenticateByDefault;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
package org.keycloak.models.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.AuthenticatorConfigModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredCredentialModel;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
|
||||
/**
|
||||
* @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 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) {
|
||||
if (realm.getFlowByAlias(BROWSER_FLOW) == null) browserFlow(realm);
|
||||
if (realm.getFlowByAlias(DIRECT_GRANT_FLOW) == null) directGrantFlow(realm, false);
|
||||
|
@ -321,24 +328,41 @@ public class DefaultAuthenticationFlows {
|
|||
firstBrokerLogin.setTopLevel(true);
|
||||
firstBrokerLogin.setBuiltIn(true);
|
||||
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();
|
||||
execution.setParentFlow(firstBrokerLogin.getId());
|
||||
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
|
||||
execution.setAuthenticator("idp-update-profile");
|
||||
execution.setAuthenticator("idp-review-profile");
|
||||
execution.setPriority(10);
|
||||
execution.setAuthenticatorFlow(false);
|
||||
execution.setAuthenticatorConfig(reviewProfileConfig.getId());
|
||||
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.setParentFlow(firstBrokerLogin.getId());
|
||||
execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
|
||||
execution.setAuthenticator("idp-detect-duplications");
|
||||
execution.setAuthenticator("idp-create-user-if-unique");
|
||||
execution.setPriority(20);
|
||||
execution.setAuthenticatorFlow(false);
|
||||
execution.setAuthenticatorConfig(createUserIfUniqueConfig.getId());
|
||||
realm.addAuthenticatorExecution(execution);
|
||||
|
||||
|
||||
AuthenticationFlowModel linkExistingAccountFlow = new AuthenticationFlowModel();
|
||||
linkExistingAccountFlow.setTopLevel(false);
|
||||
linkExistingAccountFlow.setBuiltIn(true);
|
||||
|
|
|
@ -389,7 +389,6 @@ public class ModelToRepresentation {
|
|||
providerRep.setAlias(identityProviderModel.getAlias());
|
||||
providerRep.setEnabled(identityProviderModel.isEnabled());
|
||||
providerRep.setStoreToken(identityProviderModel.isStoreToken());
|
||||
providerRep.setUpdateProfileFirstLoginMode(identityProviderModel.getUpdateProfileFirstLoginMode());
|
||||
providerRep.setTrustEmail(identityProviderModel.isTrustEmail());
|
||||
providerRep.setAuthenticateByDefault(identityProviderModel.isAuthenticateByDefault());
|
||||
providerRep.setConfig(identityProviderModel.getConfig());
|
||||
|
|
|
@ -1080,7 +1080,6 @@ public class RepresentationToModel {
|
|||
identityProviderModel.setAlias(representation.getAlias());
|
||||
identityProviderModel.setProviderId(representation.getProviderId());
|
||||
identityProviderModel.setEnabled(representation.isEnabled());
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(representation.getUpdateProfileFirstLoginMode());
|
||||
identityProviderModel.setTrustEmail(representation.isTrustEmail());
|
||||
identityProviderModel.setAuthenticateByDefault(representation.isAuthenticateByDefault());
|
||||
identityProviderModel.setStoreToken(representation.isStoreToken());
|
||||
|
|
|
@ -1216,7 +1216,6 @@ public class RealmAdapter implements RealmModel {
|
|||
identityProviderModel.setInternalId(entity.getInternalId());
|
||||
identityProviderModel.setConfig(entity.getConfig());
|
||||
identityProviderModel.setEnabled(entity.isEnabled());
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(entity.getUpdateProfileFirstLoginMode());
|
||||
identityProviderModel.setTrustEmail(entity.isTrustEmail());
|
||||
identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
|
||||
identityProviderModel.setFirstBrokerLoginFlowId(entity.getFirstBrokerLoginFlowId());
|
||||
|
@ -1250,7 +1249,6 @@ public class RealmAdapter implements RealmModel {
|
|||
entity.setEnabled(identityProvider.isEnabled());
|
||||
entity.setStoreToken(identityProvider.isStoreToken());
|
||||
entity.setAddReadTokenRoleOnCreate(identityProvider.isAddReadTokenRoleOnCreate());
|
||||
entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
|
||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
||||
entity.setFirstBrokerLoginFlowId(identityProvider.getFirstBrokerLoginFlowId());
|
||||
|
@ -1278,7 +1276,6 @@ public class RealmAdapter implements RealmModel {
|
|||
if (entity.getInternalId().equals(identityProvider.getInternalId())) {
|
||||
entity.setAlias(identityProvider.getAlias());
|
||||
entity.setEnabled(identityProvider.isEnabled());
|
||||
entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
|
||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
||||
entity.setFirstBrokerLoginFlowId(identityProvider.getFirstBrokerLoginFlowId());
|
||||
|
|
|
@ -42,9 +42,6 @@ public class IdentityProviderEntity {
|
|||
@Column(name="ENABLED")
|
||||
private boolean enabled;
|
||||
|
||||
@Column(name = "UPDATE_PROFILE_FIRST_LGN_MD")
|
||||
private String updateProfileFirstLoginMode;
|
||||
|
||||
@Column(name = "TRUST_EMAIL")
|
||||
private boolean trustEmail;
|
||||
|
||||
|
@ -106,14 +103,6 @@ public class IdentityProviderEntity {
|
|||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getUpdateProfileFirstLoginMode() {
|
||||
return updateProfileFirstLoginMode;
|
||||
}
|
||||
|
||||
public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
|
||||
this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
|
||||
}
|
||||
|
||||
public boolean isStoreToken() {
|
||||
return this.storeToken;
|
||||
}
|
||||
|
|
|
@ -823,7 +823,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
|||
identityProviderModel.setInternalId(entity.getInternalId());
|
||||
identityProviderModel.setConfig(entity.getConfig());
|
||||
identityProviderModel.setEnabled(entity.isEnabled());
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(entity.getUpdateProfileFirstLoginMode());
|
||||
identityProviderModel.setTrustEmail(entity.isTrustEmail());
|
||||
identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
|
||||
identityProviderModel.setFirstBrokerLoginFlowId(entity.getFirstBrokerLoginFlowId());
|
||||
|
@ -855,7 +854,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
|||
entity.setAlias(identityProvider.getAlias());
|
||||
entity.setProviderId(identityProvider.getProviderId());
|
||||
entity.setEnabled(identityProvider.isEnabled());
|
||||
entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
|
||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||
entity.setAddReadTokenRoleOnCreate(identityProvider.isAddReadTokenRoleOnCreate());
|
||||
entity.setStoreToken(identityProvider.isStoreToken());
|
||||
|
@ -884,7 +882,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
|||
if (entity.getInternalId().equals(identityProvider.getInternalId())) {
|
||||
entity.setAlias(identityProvider.getAlias());
|
||||
entity.setEnabled(identityProvider.isEnabled());
|
||||
entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
|
||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
||||
entity.setFirstBrokerLoginFlowId(identityProvider.getFirstBrokerLoginFlowId());
|
||||
|
|
|
@ -10,17 +10,19 @@ import org.keycloak.authentication.AuthenticationFlowContext;
|
|||
import org.keycloak.authentication.authenticators.broker.util.ExistingUserInfo;
|
||||
import org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext;
|
||||
import org.keycloak.broker.provider.BrokeredIdentityContext;
|
||||
import org.keycloak.models.AuthenticatorConfigModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.FormMessage;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class IdpDetectDuplicationsAuthenticator extends AbstractIdpAuthenticator {
|
||||
public class IdpCreateUserIfUniqueAuthenticator extends AbstractIdpAuthenticator {
|
||||
|
||||
protected static Logger logger = Logger.getLogger(IdpDetectDuplicationsAuthenticator.class);
|
||||
protected static Logger logger = Logger.getLogger(IdpCreateUserIfUniqueAuthenticator.class);
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -54,6 +56,12 @@ public class IdpDetectDuplicationsAuthenticator extends AbstractIdpAuthenticator
|
|||
federatedUser.setAttribute(attr.getKey(), attr.getValue());
|
||||
}
|
||||
|
||||
AuthenticatorConfigModel config = context.getAuthenticatorConfig();
|
||||
if (config != null && Boolean.parseBoolean(config.getConfig().get(IdpCreateUserIfUniqueAuthenticatorFactory.REQUIRE_PASSWORD_UPDATE_AFTER_REGISTRATION))) {
|
||||
logger.debugf("User '%s' required to update password", federatedUser.getUsername());
|
||||
federatedUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
|
||||
}
|
||||
|
||||
// TODO: Event
|
||||
|
||||
context.setUser(federatedUser);
|
|
@ -1,5 +1,6 @@
|
|||
package org.keycloak.authentication.authenticators.broker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.keycloak.Config;
|
||||
|
@ -13,10 +14,12 @@ import org.keycloak.provider.ProviderConfigProperty;
|
|||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class IdpDetectDuplicationsAuthenticatorFactory implements AuthenticatorFactory {
|
||||
public class IdpCreateUserIfUniqueAuthenticatorFactory implements AuthenticatorFactory {
|
||||
|
||||
public static final String PROVIDER_ID = "idp-detect-duplications";
|
||||
static IdpDetectDuplicationsAuthenticator SINGLETON = new IdpDetectDuplicationsAuthenticator();
|
||||
public static final String PROVIDER_ID = "idp-create-user-if-unique";
|
||||
static IdpCreateUserIfUniqueAuthenticator SINGLETON = new IdpCreateUserIfUniqueAuthenticator();
|
||||
|
||||
public static final String REQUIRE_PASSWORD_UPDATE_AFTER_REGISTRATION = "require.password.update.after.registration";
|
||||
|
||||
@Override
|
||||
public Authenticator create(KeycloakSession session) {
|
||||
|
@ -50,7 +53,7 @@ public class IdpDetectDuplicationsAuthenticatorFactory implements AuthenticatorF
|
|||
|
||||
@Override
|
||||
public boolean isConfigurable() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = {
|
||||
|
@ -73,13 +76,26 @@ public class IdpDetectDuplicationsAuthenticatorFactory implements AuthenticatorF
|
|||
return "Detect if there is existing Keycloak account with same email like identity provider. If no, create new user";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProviderConfigProperty> getConfigProperties() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserSetupAllowed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final List<ProviderConfigProperty> configProperties = new ArrayList<ProviderConfigProperty>();
|
||||
|
||||
static {
|
||||
ProviderConfigProperty property;
|
||||
property = new ProviderConfigProperty();
|
||||
property.setName(REQUIRE_PASSWORD_UPDATE_AFTER_REGISTRATION);
|
||||
property.setLabel("Require Password Update After Registration");
|
||||
property.setType(ProviderConfigProperty.BOOLEAN_TYPE);
|
||||
property.setHelpText("If this option is true and new user is successfully imported from Identity Provider to Keycloak (there is no duplicated email or username detected in Keycloak DB), then this user is required to update his password");
|
||||
configProperties.add(property);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<ProviderConfigProperty> getConfigProperties() {
|
||||
return configProperties;
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ import org.keycloak.events.Details;
|
|||
import org.keycloak.events.EventBuilder;
|
||||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.login.LoginFormsProvider;
|
||||
import org.keycloak.models.AuthenticatorConfigModel;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
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>
|
||||
*/
|
||||
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
|
||||
public boolean requiresUser() {
|
||||
|
@ -61,10 +62,17 @@ public class IdpUpdateProfileAuthenticator extends AbstractIdpAuthenticator {
|
|||
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();
|
||||
return IdentityProviderRepresentation.UPFLM_ON.equals(idpConfig.getUpdateProfileFirstLoginMode())
|
||||
|| (IdentityProviderRepresentation.UPFLM_MISSING.equals(idpConfig.getUpdateProfileFirstLoginMode()) && !Validation.validateUserMandatoryFields(realm, userCtx));
|
||||
return IdentityProviderRepresentation.UPFLM_ON.equals(updateProfileFirstLogin)
|
||||
|| (IdentityProviderRepresentation.UPFLM_MISSING.equals(updateProfileFirstLogin) && !Validation.validateUserMandatoryFields(realm, userCtx));
|
||||
}
|
||||
|
||||
@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,8 +9,8 @@ org.keycloak.authentication.authenticators.resetcred.ResetCredentialChooseUser
|
|||
org.keycloak.authentication.authenticators.resetcred.ResetCredentialEmail
|
||||
org.keycloak.authentication.authenticators.resetcred.ResetOTP
|
||||
org.keycloak.authentication.authenticators.resetcred.ResetPassword
|
||||
org.keycloak.authentication.authenticators.broker.IdpUpdateProfileAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.broker.IdpDetectDuplicationsAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.broker.IdpReviewProfileAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.broker.IdpConfirmLinkAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticatorFactory
|
||||
org.keycloak.authentication.authenticators.broker.IdpUsernamePasswordFormFactory
|
||||
|
|
|
@ -52,7 +52,6 @@ public class IdentityProviderTest extends AbstractClientTest {
|
|||
assertEquals("clientSecret", representation.getConfig().get("clientSecret"));
|
||||
assertTrue(representation.isEnabled());
|
||||
assertFalse(representation.isStoreToken());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_ON, representation.getUpdateProfileFirstLoginMode());
|
||||
assertFalse(representation.isTrustEmail());
|
||||
}
|
||||
|
||||
|
|
|
@ -23,15 +23,20 @@ import org.junit.Before;
|
|||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
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.Constants;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionTask;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
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.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.services.Urls;
|
||||
|
@ -138,7 +143,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
@Test
|
||||
public void testSuccessfulAuthentication() {
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_ON);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_ON);
|
||||
|
||||
UserModel user = assertSuccessfulAuthentication(identityProviderModel, "test-user", "new@email.com", true);
|
||||
Assert.assertEquals("617-666-7777", user.getFirstAttribute("mobile"));
|
||||
|
@ -147,7 +152,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
@Test
|
||||
public void testSuccessfulAuthenticationUpdateProfileOnMissing_nothingMissing() {
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_MISSING);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_MISSING);
|
||||
|
||||
assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
|
||||
}
|
||||
|
@ -155,7 +160,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
@Test
|
||||
public void testSuccessfulAuthenticationUpdateProfileOnMissing_missingEmail() {
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_MISSING);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_MISSING);
|
||||
|
||||
assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", "new@email.com", true);
|
||||
}
|
||||
|
@ -163,7 +168,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
@Test
|
||||
public void testSuccessfulAuthenticationWithoutUpdateProfile() {
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
|
||||
assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
|
||||
}
|
||||
|
@ -182,7 +187,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
try {
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
identityProviderModel.setTrustEmail(false);
|
||||
|
||||
UserModel federatedUser = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "test-user@localhost", false);
|
||||
|
@ -251,7 +256,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
|
||||
try {
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
|
||||
UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", null, false);
|
||||
|
||||
|
@ -268,12 +273,12 @@ public abstract class AbstractIdentityProviderTest {
|
|||
@Test
|
||||
public void testSuccessfulAuthenticationWithoutUpdateProfile_emailProvided_emailVerifyEnabled_emailTrustEnabled() {
|
||||
getRealm().setVerifyEmail(true);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
brokerServerRule.stopSession(this.session, true);
|
||||
this.session = brokerServerRule.startSession();
|
||||
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
try {
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
identityProviderModel.setTrustEmail(true);
|
||||
|
||||
UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
|
||||
|
@ -300,7 +305,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
try {
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_ON);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_ON);
|
||||
identityProviderModel.setTrustEmail(true);
|
||||
|
||||
UserModel user = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "new@email.com", true);
|
||||
|
@ -320,7 +325,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
|
||||
try {
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
|
||||
authenticateWithIdentityProvider(identityProviderModel, "test-user", false);
|
||||
|
||||
|
@ -368,7 +373,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
|
||||
try {
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
|
||||
authenticateWithIdentityProvider(identityProviderModel, "test-user-noemail", false);
|
||||
|
||||
|
@ -475,7 +480,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
public void testUserAlreadyExistsWhenNotUpdatingProfile() {
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
|
||||
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
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_ON);
|
||||
accountFederatedIdentityPage.clickAddProvider(identityProviderModel.getAlias());
|
||||
|
||||
assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8082/auth/"));
|
||||
|
@ -609,6 +615,7 @@ public abstract class AbstractIdentityProviderTest {
|
|||
|
||||
@Test
|
||||
public void testTokenStorageAndRetrievalByApplication() {
|
||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_ON);
|
||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||
|
||||
identityProviderModel.setStoreToken(true);
|
||||
|
@ -774,7 +781,6 @@ public abstract class AbstractIdentityProviderTest {
|
|||
|
||||
assertNotNull(identityProviderModel);
|
||||
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_ON);
|
||||
identityProviderModel.setEnabled(true);
|
||||
|
||||
return identityProviderModel;
|
||||
|
@ -851,4 +857,18 @@ public abstract class AbstractIdentityProviderTest {
|
|||
|
||||
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.setEnabled(false);
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
|
||||
identityProviderModel.setTrustEmail(true);
|
||||
identityProviderModel.setStoreToken(true);
|
||||
identityProviderModel.setAuthenticateByDefault(true);
|
||||
|
@ -97,7 +96,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
|
||||
assertEquals("value-added", identityProviderModel.getConfig().get("config-added"));
|
||||
assertFalse(identityProviderModel.isEnabled());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_OFF, identityProviderModel.getUpdateProfileFirstLoginMode());
|
||||
assertTrue(identityProviderModel.isTrustEmail());
|
||||
assertTrue(identityProviderModel.isStoreToken());
|
||||
assertTrue(identityProviderModel.isAuthenticateByDefault());
|
||||
|
@ -105,7 +103,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
|
||||
identityProviderModel.getConfig().remove("config-added");
|
||||
identityProviderModel.setEnabled(true);
|
||||
identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_MISSING);
|
||||
identityProviderModel.setTrustEmail(false);
|
||||
identityProviderModel.setAuthenticateByDefault(false);
|
||||
|
||||
|
@ -118,7 +115,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
|
||||
assertFalse(identityProviderModel.getConfig().containsKey("config-added"));
|
||||
assertTrue(identityProviderModel.isEnabled());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_MISSING, identityProviderModel.getUpdateProfileFirstLoginMode());
|
||||
assertFalse(identityProviderModel.isTrustEmail());
|
||||
assertFalse(identityProviderModel.isAuthenticateByDefault());
|
||||
this.realmManager.removeRealm(realm);
|
||||
|
@ -167,7 +163,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
assertEquals("model-google", config.getAlias());
|
||||
assertEquals(GoogleIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||
assertEquals(true, config.isEnabled());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_ON, config.getUpdateProfileFirstLoginMode());
|
||||
assertEquals(true, config.isTrustEmail());
|
||||
assertEquals(false, config.isAuthenticateByDefault());
|
||||
assertEquals(true, config.isStoreToken());
|
||||
|
@ -186,7 +181,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
assertEquals("model-saml-signed-idp", config.getAlias());
|
||||
assertEquals(SAMLIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||
assertEquals(true, config.isEnabled());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_ON, config.getUpdateProfileFirstLoginMode());
|
||||
assertEquals(false, config.isAuthenticateByDefault());
|
||||
assertEquals(false, config.isTrustEmail());
|
||||
assertEquals(false, config.isStoreToken());
|
||||
|
@ -207,7 +201,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
assertEquals("model-oidc-idp", config.getAlias());
|
||||
assertEquals(OIDCIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||
assertEquals(false, config.isEnabled());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
|
||||
assertEquals(false, config.isTrustEmail());
|
||||
assertEquals(false, config.isAuthenticateByDefault());
|
||||
assertEquals(false, config.isStoreToken());
|
||||
|
@ -222,7 +215,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
assertEquals("model-facebook", config.getAlias());
|
||||
assertEquals(FacebookIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||
assertEquals(true, config.isEnabled());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
|
||||
assertEquals(false, config.isTrustEmail());
|
||||
assertEquals(false, config.isAuthenticateByDefault());
|
||||
assertEquals(false, config.isStoreToken());
|
||||
|
@ -241,7 +233,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
assertEquals("model-github", config.getAlias());
|
||||
assertEquals(GitHubIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||
assertEquals(true, config.isEnabled());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_ON, config.getUpdateProfileFirstLoginMode());
|
||||
assertEquals(false, config.isTrustEmail());
|
||||
assertEquals(false, config.isAuthenticateByDefault());
|
||||
assertEquals(false, config.isStoreToken());
|
||||
|
@ -258,17 +249,16 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
OAuth2IdentityProviderConfig config = liIdentityProvider.getConfig();
|
||||
|
||||
assertEquals("model-linkedin", config.getAlias());
|
||||
assertEquals(LinkedInIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||
assertEquals(true, config.isEnabled());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_MISSING, config.getUpdateProfileFirstLoginMode());
|
||||
assertEquals(LinkedInIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||
assertEquals(true, config.isEnabled());
|
||||
assertEquals(false, config.isTrustEmail());
|
||||
assertEquals(false, config.isAuthenticateByDefault());
|
||||
assertEquals(false, config.isStoreToken());
|
||||
assertEquals("clientId", config.getClientId());
|
||||
assertEquals("clientSecret", config.getClientSecret());
|
||||
assertEquals(LinkedInIdentityProvider.AUTH_URL, config.getAuthorizationUrl());
|
||||
assertEquals(LinkedInIdentityProvider.TOKEN_URL, config.getTokenUrl());
|
||||
assertEquals(LinkedInIdentityProvider.PROFILE_URL, config.getUserInfoUrl());
|
||||
assertEquals(false, config.isAuthenticateByDefault());
|
||||
assertEquals(false, config.isStoreToken());
|
||||
assertEquals("clientId", config.getClientId());
|
||||
assertEquals("clientSecret", config.getClientSecret());
|
||||
assertEquals(LinkedInIdentityProvider.AUTH_URL, config.getAuthorizationUrl());
|
||||
assertEquals(LinkedInIdentityProvider.TOKEN_URL, config.getTokenUrl());
|
||||
assertEquals(LinkedInIdentityProvider.PROFILE_URL, config.getUserInfoUrl());
|
||||
}
|
||||
|
||||
private void assertStackoverflowIdentityProviderConfig(IdentityProviderModel identityProvider) {
|
||||
|
@ -278,7 +268,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
assertEquals("model-stackoverflow", config.getAlias());
|
||||
assertEquals(StackoverflowIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||
assertEquals(true, config.isEnabled());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
|
||||
assertEquals(false, config.isTrustEmail());
|
||||
assertEquals(false, config.isAuthenticateByDefault());
|
||||
assertEquals(false, config.isStoreToken());
|
||||
|
@ -297,7 +286,6 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
|
|||
assertEquals("model-twitter", config.getAlias());
|
||||
assertEquals(TwitterIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
|
||||
assertEquals(true, config.isEnabled());
|
||||
assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
|
||||
assertEquals(false, config.isTrustEmail());
|
||||
assertEquals(false, config.isAuthenticateByDefault());
|
||||
assertEquals(true, config.isStoreToken());
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
"alias" : "model-google",
|
||||
"providerId" : "google",
|
||||
"enabled": true,
|
||||
"updateProfileFirstLogin" : "true",
|
||||
"trustEmail" : "true",
|
||||
"storeToken": "true",
|
||||
"config": {
|
||||
|
@ -29,7 +28,6 @@
|
|||
"alias" : "model-facebook",
|
||||
"providerId" : "facebook",
|
||||
"enabled": true,
|
||||
"updateProfileFirstLogin" : "false",
|
||||
"firstBrokerLoginFlowAlias" : "browser",
|
||||
"config": {
|
||||
"authorizationUrl": "authorizationUrl",
|
||||
|
@ -43,7 +41,6 @@
|
|||
"alias" : "model-github",
|
||||
"providerId" : "github",
|
||||
"enabled": true,
|
||||
"updateProfileFirstLoginMode" : "on",
|
||||
"storeToken": "false",
|
||||
"config": {
|
||||
"authorizationUrl": "authorizationUrl",
|
||||
|
@ -57,7 +54,6 @@
|
|||
"alias" : "model-twitter",
|
||||
"providerId" : "twitter",
|
||||
"enabled": true,
|
||||
"updateProfileFirstLoginMode" : "off",
|
||||
"storeToken": true,
|
||||
"config": {
|
||||
"authorizationUrl": "authorizationUrl",
|
||||
|
@ -71,7 +67,6 @@
|
|||
"alias" : "model-linkedin",
|
||||
"providerId" : "linkedin",
|
||||
"enabled": true,
|
||||
"updateProfileFirstLoginMode" : "missing",
|
||||
"storeToken": false,
|
||||
"config": {
|
||||
"authorizationUrl": "authorizationUrl",
|
||||
|
@ -85,7 +80,6 @@
|
|||
"alias" : "model-stackoverflow",
|
||||
"providerId" : "stackoverflow",
|
||||
"enabled": true,
|
||||
"updateProfileFirstLoginMode" : "off",
|
||||
"storeToken": false,
|
||||
"config": {
|
||||
"key": "keyValue",
|
||||
|
@ -100,7 +94,6 @@
|
|||
"alias" : "model-saml-signed-idp",
|
||||
"providerId" : "saml",
|
||||
"enabled": true,
|
||||
"updateProfileFirstLoginMode" : "on",
|
||||
"config": {
|
||||
"singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-identity-provider/protocol/saml",
|
||||
"nameIDPolicyFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
|
||||
|
@ -116,7 +109,6 @@
|
|||
"alias" : "kc-saml-signed-idp",
|
||||
"providerId" : "saml",
|
||||
"enabled": true,
|
||||
"updateProfileFirstLoginMode" : "on",
|
||||
"addReadTokenRoleOnCreate": true,
|
||||
"config": {
|
||||
"singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-signed-idp/protocol/saml",
|
||||
|
@ -135,7 +127,6 @@
|
|||
"alias" : "kc-saml-idp-basic",
|
||||
"providerId" : "saml",
|
||||
"enabled": true,
|
||||
"updateProfileFirstLoginMode" : "on",
|
||||
"trustEmail" : false,
|
||||
"addReadTokenRoleOnCreate": true,
|
||||
"config": {
|
||||
|
@ -151,7 +142,6 @@
|
|||
"alias" : "model-oidc-idp",
|
||||
"providerId" : "oidc",
|
||||
"enabled": false,
|
||||
"updateProfileFirstLoginMode" : "off",
|
||||
"authenticateByDefault" : "false",
|
||||
"config": {
|
||||
"clientId": "clientId",
|
||||
|
@ -167,7 +157,6 @@
|
|||
"alias" : "kc-oidc-idp",
|
||||
"providerId" : "keycloak-oidc",
|
||||
"enabled": true,
|
||||
"updateProfileFirstLoginMode" : "off",
|
||||
"storeToken" : true,
|
||||
"addReadTokenRoleOnCreate": true,
|
||||
"config": {
|
||||
|
|
Loading…
Reference in a new issue