keycloak-service
公開メンバ関数 | 静的公開メンバ関数 | 静的公開変数類 | 限定公開メンバ関数 | 静的非公開変数類 | 全メンバ一覧
org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator クラス
org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator の継承関係図
Inheritance graph
org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator 連携図
Collaboration graph

公開メンバ関数

boolean requiresUser ()
 
boolean configuredFor (KeycloakSession session, RealmModel realm, UserModel user)
 
void authenticate (AuthenticationFlowContext context)
 
void action (AuthenticationFlowContext context)
 
void setRequiredActions (KeycloakSession session, RealmModel realm, UserModel user)
 
void close ()
 

静的公開メンバ関数

static UserModel getExistingUser (KeycloakSession session, RealmModel realm, AuthenticationSessionModel authSession)
 

静的公開変数類

static final String BROKERED_CONTEXT_NOTE = "BROKERED_CONTEXT"
 
static final String EXISTING_USER_INFO = "EXISTING_USER_INFO"
 
static final String UPDATE_PROFILE_EMAIL_CHANGED = "UPDATE_PROFILE_EMAIL_CHANGED"
 
static final String ENFORCE_UPDATE_PROFILE = "ENFORCE_UPDATE_PROFILE"
 
static final String BROKER_REGISTERED_NEW_USER = "BROKER_REGISTERED_NEW_USER"
 
static final String FIRST_BROKER_LOGIN_SUCCESS = "FIRST_BROKER_LOGIN_SUCCESS"
 

限定公開メンバ関数

void actionImpl (AuthenticationFlowContext context, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
 
void authenticateImpl (AuthenticationFlowContext context, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
 
ExistingUserInfo checkExistingUser (AuthenticationFlowContext context, String username, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
 
String getUsername (AuthenticationFlowContext context, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
 
void userRegisteredSuccess (AuthenticationFlowContext context, UserModel registeredUser, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
 
void sendFailureChallenge (AuthenticationFlowContext context, Response.Status status, String eventError, String errorMessage, AuthenticationFlowError flowError)
 

静的非公開変数類

static Logger logger = Logger.getLogger(IdpCreateUserIfUniqueAuthenticator.class)
 

詳解

著者
Marek Posolda

関数詳解

◆ action()

void org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.action ( AuthenticationFlowContext  context)
inlineinherited
78  {
79  AuthenticationSessionModel clientSession = context.getAuthenticationSession();
80 
81  SerializedBrokeredIdentityContext serializedCtx = SerializedBrokeredIdentityContext.readFromAuthenticationSession(clientSession, BROKERED_CONTEXT_NOTE);
82  if (serializedCtx == null) {
83  throw new AuthenticationFlowException("Not found serialized context in clientSession", AuthenticationFlowError.IDENTITY_PROVIDER_ERROR);
84  }
85  BrokeredIdentityContext brokerContext = serializedCtx.deserialize(context.getSession(), clientSession);
86 
87  if (!brokerContext.getIdpConfig().isEnabled()) {
88  sendFailureChallenge(context, Response.Status.BAD_REQUEST, Errors.IDENTITY_PROVIDER_ERROR, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR, AuthenticationFlowError.IDENTITY_PROVIDER_ERROR);
89  }
90 
91  actionImpl(context, serializedCtx, brokerContext);
92  }
static final String BROKERED_CONTEXT_NOTE
Definition: AbstractIdpAuthenticator.java:42
void sendFailureChallenge(AuthenticationFlowContext context, Response.Status status, String eventError, String errorMessage, AuthenticationFlowError flowError)
Definition: AbstractIdpAuthenticator.java:97
abstract void actionImpl(AuthenticationFlowContext context, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)

◆ actionImpl()

void org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator.actionImpl ( AuthenticationFlowContext  context,
SerializedBrokeredIdentityContext  serializedCtx,
BrokeredIdentityContext  brokerContext 
)
inlineprotected
47  {
48  }

◆ authenticate()

void org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.authenticate ( AuthenticationFlowContext  context)
inlineinherited
61  {
62  AuthenticationSessionModel authSession = context.getAuthenticationSession();
63 
64  SerializedBrokeredIdentityContext serializedCtx = SerializedBrokeredIdentityContext.readFromAuthenticationSession(authSession, BROKERED_CONTEXT_NOTE);
65  if (serializedCtx == null) {
66  throw new AuthenticationFlowException("Not found serialized context in clientSession", AuthenticationFlowError.IDENTITY_PROVIDER_ERROR);
67  }
68  BrokeredIdentityContext brokerContext = serializedCtx.deserialize(context.getSession(), authSession);
69 
70  if (!brokerContext.getIdpConfig().isEnabled()) {
71  sendFailureChallenge(context, Response.Status.BAD_REQUEST, Errors.IDENTITY_PROVIDER_ERROR, Messages.IDENTITY_PROVIDER_UNEXPECTED_ERROR, AuthenticationFlowError.IDENTITY_PROVIDER_ERROR);
72  }
73 
74  authenticateImpl(context, serializedCtx, brokerContext);
75  }
static final String BROKERED_CONTEXT_NOTE
Definition: AbstractIdpAuthenticator.java:42
void sendFailureChallenge(AuthenticationFlowContext context, Response.Status status, String eventError, String errorMessage, AuthenticationFlowError flowError)
Definition: AbstractIdpAuthenticator.java:97
abstract void authenticateImpl(AuthenticationFlowContext context, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)

◆ authenticateImpl()

void org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator.authenticateImpl ( AuthenticationFlowContext  context,
SerializedBrokeredIdentityContext  serializedCtx,
BrokeredIdentityContext  brokerContext 
)
inlineprotected
51  {
52 
53  KeycloakSession session = context.getSession();
54  RealmModel realm = context.getRealm();
55 
56  if (context.getAuthenticationSession().getAuthNote(EXISTING_USER_INFO) != null) {
57  context.attempted();
58  return;
59  }
60 
61  String username = getUsername(context, serializedCtx, brokerContext);
62  if (username == null) {
63  ServicesLogger.LOGGER.resetFlow(realm.isRegistrationEmailAsUsername() ? "Email" : "Username");
64  context.getAuthenticationSession().setAuthNote(ENFORCE_UPDATE_PROFILE, "true");
65  context.resetFlow();
66  return;
67  }
68 
69  ExistingUserInfo duplication = checkExistingUser(context, username, serializedCtx, brokerContext);
70 
71  if (duplication == null) {
72  logger.debugf("No duplication detected. Creating account for user '%s' and linking with identity provider '%s' .",
73  username, brokerContext.getIdpConfig().getAlias());
74 
75  UserModel federatedUser = session.users().addUser(realm, username);
76  federatedUser.setEnabled(true);
77  federatedUser.setEmail(brokerContext.getEmail());
78  federatedUser.setFirstName(brokerContext.getFirstName());
79  federatedUser.setLastName(brokerContext.getLastName());
80 
81  for (Map.Entry<String, List<String>> attr : serializedCtx.getAttributes().entrySet()) {
82  federatedUser.setAttribute(attr.getKey(), attr.getValue());
83  }
84 
85  AuthenticatorConfigModel config = context.getAuthenticatorConfig();
86  if (config != null && Boolean.parseBoolean(config.getConfig().get(IdpCreateUserIfUniqueAuthenticatorFactory.REQUIRE_PASSWORD_UPDATE_AFTER_REGISTRATION))) {
87  logger.debugf("User '%s' required to update password", federatedUser.getUsername());
88  federatedUser.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
89  }
90 
91  userRegisteredSuccess(context, federatedUser, serializedCtx, brokerContext);
92 
93  context.setUser(federatedUser);
94  context.getAuthenticationSession().setAuthNote(BROKER_REGISTERED_NEW_USER, "true");
95  context.success();
96  } else {
97  logger.debugf("Duplication detected. There is already existing user with %s '%s' .",
98  duplication.getDuplicateAttributeName(), duplication.getDuplicateAttributeValue());
99 
100  // Set duplicated user, so next authenticators can deal with it
101  context.getAuthenticationSession().setAuthNote(EXISTING_USER_INFO, duplication.serialize());
102 
103  Response challengeResponse = context.form()
104  .setError(Messages.FEDERATED_IDENTITY_EXISTS, duplication.getDuplicateAttributeName(), duplication.getDuplicateAttributeValue())
105  .createErrorPage(Response.Status.CONFLICT);
106  context.challenge(challengeResponse);
107 
108  if (context.getExecution().isRequired()) {
109  context.getEvent()
110  .user(duplication.getExistingUserId())
111  .detail("existing_" + duplication.getDuplicateAttributeName(), duplication.getDuplicateAttributeValue())
112  .removeDetail(Details.AUTH_METHOD)
113  .removeDetail(Details.AUTH_TYPE)
114  .error(Errors.FEDERATED_IDENTITY_EXISTS);
115  }
116  }
117  }
static final String BROKER_REGISTERED_NEW_USER
Definition: AbstractIdpAuthenticator.java:54
static final String EXISTING_USER_INFO
Definition: AbstractIdpAuthenticator.java:45
ExistingUserInfo checkExistingUser(AuthenticationFlowContext context, String username, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
Definition: IdpCreateUserIfUniqueAuthenticator.java:120
void userRegisteredSuccess(AuthenticationFlowContext context, UserModel registeredUser, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
Definition: IdpCreateUserIfUniqueAuthenticator.java:144
String getUsername(AuthenticationFlowContext context, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
Definition: IdpCreateUserIfUniqueAuthenticator.java:137
static final String ENFORCE_UPDATE_PROFILE
Definition: AbstractIdpAuthenticator.java:51
static Logger logger
Definition: IdpCreateUserIfUniqueAuthenticator.java:43

◆ checkExistingUser()

ExistingUserInfo org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator.checkExistingUser ( AuthenticationFlowContext  context,
String  username,
SerializedBrokeredIdentityContext  serializedCtx,
BrokeredIdentityContext  brokerContext 
)
inlineprotected
120  {
121 
122  if (brokerContext.getEmail() != null && !context.getRealm().isDuplicateEmailsAllowed()) {
123  UserModel existingUser = context.getSession().users().getUserByEmail(brokerContext.getEmail(), context.getRealm());
124  if (existingUser != null) {
125  return new ExistingUserInfo(existingUser.getId(), UserModel.EMAIL, existingUser.getEmail());
126  }
127  }
128 
129  UserModel existingUser = context.getSession().users().getUserByUsername(username, context.getRealm());
130  if (existingUser != null) {
131  return new ExistingUserInfo(existingUser.getId(), UserModel.USERNAME, existingUser.getUsername());
132  }
133 
134  return null;
135  }

◆ close()

void org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.close ( )
inlineinherited
111  {
112 
113  }

◆ configuredFor()

boolean org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator.configuredFor ( KeycloakSession  session,
RealmModel  realm,
UserModel  user 
)
inline
155  {
156  return true;
157  }

◆ getExistingUser()

static UserModel org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.getExistingUser ( KeycloakSession  session,
RealmModel  realm,
AuthenticationSessionModel  authSession 
)
inlinestaticinherited
115  {
116  String existingUserId = authSession.getAuthNote(EXISTING_USER_INFO);
117  if (existingUserId == null) {
118  throw new AuthenticationFlowException("Unexpected state. There is no existing duplicated user identified in ClientSession",
119  AuthenticationFlowError.INTERNAL_ERROR);
120  }
121 
122  ExistingUserInfo duplication = ExistingUserInfo.deserialize(existingUserId);
123 
124  UserModel existingUser = session.users().getUserById(duplication.getExistingUserId(), realm);
125  if (existingUser == null) {
126  throw new AuthenticationFlowException("User with ID '" + existingUserId + "' not found.", AuthenticationFlowError.INVALID_USER);
127  }
128 
129  if (!existingUser.isEnabled()) {
130  throw new AuthenticationFlowException("User with ID '" + existingUserId + "', username '" + existingUser.getUsername() + "' disabled.", AuthenticationFlowError.USER_DISABLED);
131  }
132 
133  return existingUser;
134  }
static final String EXISTING_USER_INFO
Definition: AbstractIdpAuthenticator.java:45

◆ getUsername()

String org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator.getUsername ( AuthenticationFlowContext  context,
SerializedBrokeredIdentityContext  serializedCtx,
BrokeredIdentityContext  brokerContext 
)
inlineprotected
137  {
138  RealmModel realm = context.getRealm();
139  return realm.isRegistrationEmailAsUsername() ? brokerContext.getEmail() : brokerContext.getModelUsername();
140  }

◆ requiresUser()

boolean org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator.requiresUser ( )
inline
150  {
151  return false;
152  }

◆ sendFailureChallenge()

void org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.sendFailureChallenge ( AuthenticationFlowContext  context,
Response.Status  status,
String  eventError,
String  errorMessage,
AuthenticationFlowError  flowError 
)
inlineprotectedinherited
97  {
98  context.getEvent().user(context.getUser())
99  .error(eventError);
100  Response challengeResponse = context.form()
101  .setError(errorMessage)
102  .createErrorPage(status);
103  context.failureChallenge(flowError, challengeResponse);
104  }

◆ setRequiredActions()

void org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.setRequiredActions ( KeycloakSession  session,
RealmModel  realm,
UserModel  user 
)
inlineinherited
107  {
108  }

◆ userRegisteredSuccess()

void org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator.userRegisteredSuccess ( AuthenticationFlowContext  context,
UserModel  registeredUser,
SerializedBrokeredIdentityContext  serializedCtx,
BrokeredIdentityContext  brokerContext 
)
inlineprotected
144  {
145 
146  }

メンバ詳解

◆ BROKER_REGISTERED_NEW_USER

final String org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.BROKER_REGISTERED_NEW_USER = "BROKER_REGISTERED_NEW_USER"
staticinherited

◆ BROKERED_CONTEXT_NOTE

final String org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE = "BROKERED_CONTEXT"
staticinherited

◆ ENFORCE_UPDATE_PROFILE

final String org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.ENFORCE_UPDATE_PROFILE = "ENFORCE_UPDATE_PROFILE"
staticinherited

◆ EXISTING_USER_INFO

final String org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.EXISTING_USER_INFO = "EXISTING_USER_INFO"
staticinherited

◆ FIRST_BROKER_LOGIN_SUCCESS

final String org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.FIRST_BROKER_LOGIN_SUCCESS = "FIRST_BROKER_LOGIN_SUCCESS"
staticinherited

◆ logger

Logger org.keycloak.authentication.authenticators.broker.IdpCreateUserIfUniqueAuthenticator.logger = Logger.getLogger(IdpCreateUserIfUniqueAuthenticator.class)
staticprivate

◆ UPDATE_PROFILE_EMAIL_CHANGED

final String org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator.UPDATE_PROFILE_EMAIL_CHANGED = "UPDATE_PROFILE_EMAIL_CHANGED"
staticinherited

このクラス詳解は次のファイルから抽出されました: