keycloak-service
公開メンバ関数 | 静的公開メンバ関数 | 静的公開変数類 | 限定公開メンバ関数 | 非公開メンバ関数 | 静的非公開変数類 | 全メンバ一覧
org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticator クラス
org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticator の継承関係図
Inheritance graph
org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticator 連携図
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 VERIFY_ACCOUNT_IDP_USERNAME = "VERIFY_ACCOUNT_IDP_USERNAME"
 
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 authenticateImpl (AuthenticationFlowContext context, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
 
void actionImpl (AuthenticationFlowContext context, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
 
void showEmailSentPage (AuthenticationFlowContext context, BrokeredIdentityContext brokerContext)
 
void sendFailureChallenge (AuthenticationFlowContext context, Response.Status status, String eventError, String errorMessage, AuthenticationFlowError flowError)
 

非公開メンバ関数

void sendVerifyEmail (KeycloakSession session, AuthenticationFlowContext context, UserModel existingUser, BrokeredIdentityContext brokerContext) throws UriBuilderException, IllegalArgumentException
 

静的非公開変数類

static Logger logger = Logger.getLogger(IdpEmailVerificationAuthenticator.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.IdpEmailVerificationAuthenticator.actionImpl ( AuthenticationFlowContext  context,
SerializedBrokeredIdentityContext  serializedCtx,
BrokeredIdentityContext  brokerContext 
)
inlineprotected
96  {
97  logger.debugf("Re-sending email requested for user, details follow");
98 
99  // This will allow user to re-send email again
100  context.getAuthenticationSession().removeAuthNote(Constants.VERIFY_EMAIL_KEY);
101 
102  authenticateImpl(context, serializedCtx, brokerContext);
103  }
void authenticateImpl(AuthenticationFlowContext context, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext)
Definition: IdpEmailVerificationAuthenticator.java:62
static Logger logger
Definition: IdpEmailVerificationAuthenticator.java:57

◆ 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.IdpEmailVerificationAuthenticator.authenticateImpl ( AuthenticationFlowContext  context,
SerializedBrokeredIdentityContext  serializedCtx,
BrokeredIdentityContext  brokerContext 
)
inlineprotected
62  {
63  KeycloakSession session = context.getSession();
64  RealmModel realm = context.getRealm();
65  AuthenticationSessionModel authSession = context.getAuthenticationSession();
66 
67  if (realm.getSmtpConfig().isEmpty()) {
68  ServicesLogger.LOGGER.smtpNotConfigured();
69  context.attempted();
70  return;
71  }
72 
73  if (Objects.equals(authSession.getAuthNote(VERIFY_ACCOUNT_IDP_USERNAME), brokerContext.getUsername())) {
74  UserModel existingUser = getExistingUser(session, realm, authSession);
75 
76  logger.debugf("User '%s' confirmed that wants to link with identity provider '%s' . Identity provider username is '%s' ", existingUser.getUsername(),
77  brokerContext.getIdpConfig().getAlias(), brokerContext.getUsername());
78 
79  context.setUser(existingUser);
80  context.success();
81  return;
82  }
83 
84  UserModel existingUser = getExistingUser(session, realm, authSession);
85 
86  // Do not allow resending e-mail by simple page refresh
87  if (! Objects.equals(authSession.getAuthNote(Constants.VERIFY_EMAIL_KEY), existingUser.getEmail())) {
88  authSession.setAuthNote(Constants.VERIFY_EMAIL_KEY, existingUser.getEmail());
89  sendVerifyEmail(session, context, existingUser, brokerContext);
90  } else {
91  showEmailSentPage(context, brokerContext);
92  }
93  }
static final String VERIFY_ACCOUNT_IDP_USERNAME
Definition: IdpEmailVerificationAuthenticator.java:59
static UserModel getExistingUser(KeycloakSession session, RealmModel realm, AuthenticationSessionModel authSession)
Definition: AbstractIdpAuthenticator.java:115
void sendVerifyEmail(KeycloakSession session, AuthenticationFlowContext context, UserModel existingUser, BrokeredIdentityContext brokerContext)
Definition: IdpEmailVerificationAuthenticator.java:115
static Logger logger
Definition: IdpEmailVerificationAuthenticator.java:57
void showEmailSentPage(AuthenticationFlowContext context, BrokeredIdentityContext brokerContext)
Definition: IdpEmailVerificationAuthenticator.java:167

◆ close()

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

◆ configuredFor()

boolean org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticator.configuredFor ( KeycloakSession  session,
RealmModel  realm,
UserModel  user 
)
inline
111  {
112  return false;
113  }

◆ 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

◆ requiresUser()

boolean org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticator.requiresUser ( )
inline
106  {
107  return false;
108  }

◆ 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  }

◆ sendVerifyEmail()

void org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticator.sendVerifyEmail ( KeycloakSession  session,
AuthenticationFlowContext  context,
UserModel  existingUser,
BrokeredIdentityContext  brokerContext 
) throws UriBuilderException, IllegalArgumentException
inlineprivate
115  {
116  RealmModel realm = session.getContext().getRealm();
117  UriInfo uriInfo = session.getContext().getUri();
118  AuthenticationSessionModel authSession = context.getAuthenticationSession();
119 
120  int validityInSecs = realm.getActionTokenGeneratedByUserLifespan(IdpVerifyAccountLinkActionToken.TOKEN_TYPE);
121  int absoluteExpirationInSecs = Time.currentTime() + validityInSecs;
122 
123  EventBuilder event = context.getEvent().clone().event(EventType.SEND_IDENTITY_PROVIDER_LINK)
124  .user(existingUser)
125  .detail(Details.USERNAME, existingUser.getUsername())
126  .detail(Details.EMAIL, existingUser.getEmail())
127  .detail(Details.CODE_ID, authSession.getParentSession().getId())
128  .removeDetail(Details.AUTH_METHOD)
129  .removeDetail(Details.AUTH_TYPE);
130 
131  String authSessionEncodedId = AuthenticationSessionCompoundId.fromAuthSession(authSession).getEncodedId();
132  IdpVerifyAccountLinkActionToken token = new IdpVerifyAccountLinkActionToken(
133  existingUser.getId(), absoluteExpirationInSecs, authSessionEncodedId,
134  brokerContext.getUsername(), brokerContext.getIdpConfig().getAlias(), authSession.getClient().getClientId()
135  );
136  UriBuilder builder = Urls.actionTokenBuilder(uriInfo.getBaseUri(), token.serialize(session, realm, uriInfo),
137  authSession.getClient().getClientId(), authSession.getTabId());
138  String link = builder
139  .queryParam(Constants.EXECUTION, context.getExecution().getId())
140  .build(realm.getName()).toString();
141  long expirationInMinutes = TimeUnit.SECONDS.toMinutes(validityInSecs);
142 
143  try {
144  context.getSession().getProvider(EmailTemplateProvider.class)
145  .setRealm(realm)
146  .setAuthenticationSession(authSession)
147  .setUser(existingUser)
148  .setAttribute(EmailTemplateProvider.IDENTITY_PROVIDER_BROKER_CONTEXT, brokerContext)
149  .sendConfirmIdentityBrokerLink(link, expirationInMinutes);
150 
151  event.success();
152  } catch (EmailException e) {
153  event.error(Errors.EMAIL_SEND_FAILED);
154 
155  ServicesLogger.LOGGER.confirmBrokerEmailFailed(e);
156  Response challenge = context.form()
157  .setError(Messages.EMAIL_SENT_ERROR)
158  .createErrorPage(Response.Status.INTERNAL_SERVER_ERROR);
159  context.failure(AuthenticationFlowError.INTERNAL_ERROR, challenge);
160  return;
161  }
162 
163  showEmailSentPage(context, brokerContext);
164  }
void showEmailSentPage(AuthenticationFlowContext context, BrokeredIdentityContext brokerContext)
Definition: IdpEmailVerificationAuthenticator.java:167

◆ setRequiredActions()

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

◆ showEmailSentPage()

void org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticator.showEmailSentPage ( AuthenticationFlowContext  context,
BrokeredIdentityContext  brokerContext 
)
inlineprotected
167  {
168  String accessCode = context.generateAccessCode();
169  URI action = context.getActionUrl(accessCode);
170 
171  Response challenge = context.form()
172  .setStatus(Response.Status.OK)
173  .setAttribute(LoginFormsProvider.IDENTITY_PROVIDER_BROKER_CONTEXT, brokerContext)
174  .setActionUri(action)
175  .setExecution(context.getExecution().getId())
176  .createIdpLinkEmailPage();
177  context.forceChallenge(challenge);
178  }
void action(AuthenticationFlowContext context)
Definition: AbstractIdpAuthenticator.java:78

メンバ詳解

◆ 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.IdpEmailVerificationAuthenticator.logger = Logger.getLogger(IdpEmailVerificationAuthenticator.class)
staticprivate

◆ UPDATE_PROFILE_EMAIL_CHANGED

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

◆ VERIFY_ACCOUNT_IDP_USERNAME

final String org.keycloak.authentication.authenticators.broker.IdpEmailVerificationAuthenticator.VERIFY_ACCOUNT_IDP_USERNAME = "VERIFY_ACCOUNT_IDP_USERNAME"
static

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