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

公開メンバ関数

 GitLabIdentityProvider (KeycloakSession session, OIDCIdentityProviderConfig config)
 
boolean isIssuer (String issuer, MultivaluedMap< String, String > params)
 
Object callback (RealmModel realm, AuthenticationCallback callback, EventBuilder event)
 
void backchannelLogout (KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm)
 
Response keycloakInitiatedBrowserLogout (KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm)
 
String refreshTokenForLogout (KeycloakSession session, UserSessionModel userSession)
 
BrokeredIdentityContext getFederatedIdentity (String response)
 
void authenticationFinished (AuthenticationSessionModel authSession, BrokeredIdentityContext context)
 
Response performLogin (AuthenticationRequest request)
 
Response retrieveToken (KeycloakSession session, FederatedIdentityModel identity)
 
getConfig ()
 
Response exchangeFromToken (UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject, MultivaluedMap< String, String > params)
 
String getJsonProperty (JsonNode jsonNode, String name)
 
JsonNode asJsonNode (String json) throws IOException
 
final BrokeredIdentityContext exchangeExternal (EventBuilder event, MultivaluedMap< String, String > params)
 
void exchangeExternalComplete (UserSessionModel userSession, BrokeredIdentityContext context, MultivaluedMap< String, String > params)
 

静的公開変数類

static final String AUTH_URL = "https://gitlab.com/oauth/authorize"
 
static final String TOKEN_URL = "https://gitlab.com/oauth/token"
 
static final String USER_INFO = "https://gitlab.com/api/v4/user"
 
static final String API_SCOPE = "api"
 
static final String SCOPE_OPENID = "openid"
 
static final String FEDERATED_ID_TOKEN = "FEDERATED_ID_TOKEN"
 
static final String FEDERATED_ACCESS_TOKEN_RESPONSE = "FEDERATED_ACCESS_TOKEN_RESPONSE"
 
static final String VALIDATED_ID_TOKEN = "VALIDATED_ID_TOKEN"
 
static final String ACCESS_TOKEN_EXPIRATION = "accessTokenExpiration"
 
static final String EXCHANGE_PROVIDER = "EXCHANGE_PROVIDER"
 
static final String OAUTH2_GRANT_TYPE_REFRESH_TOKEN
 
static final String OAUTH2_GRANT_TYPE_AUTHORIZATION_CODE
 
static final String FEDERATED_REFRESH_TOKEN
 
static final String FEDERATED_TOKEN_EXPIRATION
 
static final String ACCESS_DENIED
 
static final String OAUTH2_PARAMETER_ACCESS_TOKEN
 
static final String OAUTH2_PARAMETER_SCOPE
 
static final String OAUTH2_PARAMETER_STATE
 
static final String OAUTH2_PARAMETER_RESPONSE_TYPE
 
static final String OAUTH2_PARAMETER_REDIRECT_URI
 
static final String OAUTH2_PARAMETER_CODE
 
static final String OAUTH2_PARAMETER_CLIENT_ID
 
static final String OAUTH2_PARAMETER_CLIENT_SECRET
 
static final String OAUTH2_PARAMETER_GRANT_TYPE
 

限定公開メンバ関数

String getUsernameFromUserInfo (JsonNode userInfo)
 
String getusernameClaimNameForIdToken ()
 
boolean supportsExternalExchange ()
 
String getProfileEndpointForValidation (EventBuilder event)
 
BrokeredIdentityContext exchangeExternalImpl (EventBuilder event, MultivaluedMap< String, String > params)
 
BrokeredIdentityContext extractIdentityFromProfile (EventBuilder event, JsonNode profile)
 
BrokeredIdentityContext extractIdentity (AccessTokenResponse tokenResponse, String accessToken, JsonWebToken idToken) throws IOException
 
void backchannelLogout (UserSessionModel userSession, String idToken)
 
void processAccessTokenResponse (BrokeredIdentityContext context, AccessTokenResponse response)
 
Response exchangeStoredToken (UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject)
 
Response exchangeSessionToken (UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject)
 
String getUserInfoUrl ()
 
boolean verify (JWSInput jws)
 
JsonWebToken validateToken (String encodedToken)
 
JsonWebToken validateToken (String encodedToken, boolean ignoreAudience)
 
String getDefaultScopes ()
 
final BrokeredIdentityContext validateJwt (EventBuilder event, String subjectToken, String subjectTokenType)
 
String extractTokenFromResponse (String response, String tokenName)
 
Response hasExternalExchangeToken (EventBuilder event, UserSessionModel tokenUserSession, MultivaluedMap< String, String > params)
 
String getAccessTokenResponseParameter ()
 
BrokeredIdentityContext doGetFederatedIdentity (String accessToken)
 
UriBuilder createAuthorizationUrl (AuthenticationRequest request)
 
BrokeredIdentityContext validateExternalTokenThroughUserInfo (EventBuilder event, String subjectToken, String subjectTokenType)
 
SimpleHttp buildUserInfoRequest (String subjectToken, String userInfoUrl)
 
BrokeredIdentityContext exchangeExternalUserInfoValidationOnly (EventBuilder event, MultivaluedMap< String, String > params)
 

静的限定公開変数類

static final Logger logger = Logger.getLogger(OIDCIdentityProvider.class)
 
static ObjectMapper mapper
 

非公開メンバ関数

BrokeredIdentityContext gitlabExtractFromProfile (JsonNode profile)
 

詳解

著者
Stian Thorgersen

構築子と解体子

◆ GitLabIdentityProvider()

org.keycloak.social.gitlab.GitLabIdentityProvider.GitLabIdentityProvider ( KeycloakSession  session,
OIDCIdentityProviderConfig  config 
)
inline
53  {
54  super(session, config);
55  config.setAuthorizationUrl(AUTH_URL);
56  config.setTokenUrl(TOKEN_URL);
57  config.setUserInfoUrl(USER_INFO);
58 
59  String defaultScope = config.getDefaultScope();
60 
61  if (defaultScope.equals(SCOPE_OPENID)) {
62  config.setDefaultScope((API_SCOPE + " " + defaultScope).trim());
63  }
64  }
static final String SCOPE_OPENID
Definition: OIDCIdentityProvider.java:73
static final String USER_INFO
Definition: GitLabIdentityProvider.java:50
static final String API_SCOPE
Definition: GitLabIdentityProvider.java:51
static final String AUTH_URL
Definition: GitLabIdentityProvider.java:48
static final String TOKEN_URL
Definition: GitLabIdentityProvider.java:49

関数詳解

◆ asJsonNode()

JsonNode org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.asJsonNode ( String  json) throws IOException
inlineinherited
370  {
371  return mapper.readTree(json);
372  }
static ObjectMapper mapper
Definition: AbstractOAuth2IdentityProvider.java:83

◆ authenticationFinished()

void org.keycloak.broker.oidc.OIDCIdentityProvider.authenticationFinished ( AuthenticationSessionModel  authSession,
BrokeredIdentityContext  context 
)
inlineinherited
505  {
506  AccessTokenResponse tokenResponse = (AccessTokenResponse) context.getContextData().get(FEDERATED_ACCESS_TOKEN_RESPONSE);
507  int currentTime = Time.currentTime();
508  long expiration = tokenResponse.getExpiresIn() > 0 ? tokenResponse.getExpiresIn() + currentTime : 0;
509  authSession.setUserSessionNote(FEDERATED_TOKEN_EXPIRATION, Long.toString(expiration));
510  authSession.setUserSessionNote(FEDERATED_REFRESH_TOKEN, tokenResponse.getRefreshToken());
511  authSession.setUserSessionNote(FEDERATED_ACCESS_TOKEN, tokenResponse.getToken());
512  authSession.setUserSessionNote(FEDERATED_ID_TOKEN, tokenResponse.getIdToken());
513  }
static final String FEDERATED_REFRESH_TOKEN
Definition: AbstractOAuth2IdentityProvider.java:80
static final String FEDERATED_ACCESS_TOKEN_RESPONSE
Definition: OIDCIdentityProvider.java:76
static final String FEDERATED_ID_TOKEN
Definition: OIDCIdentityProvider.java:74
static final String FEDERATED_TOKEN_EXPIRATION
Definition: AbstractOAuth2IdentityProvider.java:81

◆ backchannelLogout() [1/2]

void org.keycloak.broker.oidc.OIDCIdentityProvider.backchannelLogout ( KeycloakSession  session,
UserSessionModel  userSession,
UriInfo  uriInfo,
RealmModel  realm 
)
inlineinherited
126  {
127  if (getConfig().getLogoutUrl() == null || getConfig().getLogoutUrl().trim().equals("") || !getConfig().isBackchannelSupported())
128  return;
129  String idToken = getIDTokenForLogout(session, userSession);
130  if (idToken == null) return;
131  backchannelLogout(userSession, idToken);
132  }
void backchannelLogout(KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm)
Definition: OIDCIdentityProvider.java:126
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
String getIDTokenForLogout(KeycloakSession session, UserSessionModel userSession)
Definition: OIDCIdentityProvider.java:194

◆ backchannelLogout() [2/2]

void org.keycloak.broker.oidc.OIDCIdentityProvider.backchannelLogout ( UserSessionModel  userSession,
String  idToken 
)
inlineprotectedinherited
134  {
135  String sessionId = userSession.getId();
136  UriBuilder logoutUri = UriBuilder.fromUri(getConfig().getLogoutUrl())
137  .queryParam("state", sessionId);
138  logoutUri.queryParam("id_token_hint", idToken);
139  String url = logoutUri.build().toString();
140  try {
141  int status = SimpleHttp.doGet(url, session).asStatus();
142  boolean success = status >= 200 && status < 400;
143  if (!success) {
144  logger.warn("Failed backchannel broker logout to: " + url);
145  }
146  } catch (Exception e) {
147  logger.warn("Failed backchannel broker logout to: " + url, e);
148  }
149  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
static final Logger logger
Definition: OIDCIdentityProvider.java:71

◆ buildUserInfoRequest()

SimpleHttp org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.buildUserInfoRequest ( String  subjectToken,
String  userInfoUrl 
)
inlineprotectedinherited
500  {
501  return SimpleHttp.doGet(userInfoUrl, session)
502  .header("Authorization", "Bearer " + subjectToken);
503  }

◆ callback()

Object org.keycloak.broker.oidc.OIDCIdentityProvider.callback ( RealmModel  realm,
AuthenticationCallback  callback,
EventBuilder  event 
)
inlineinherited
92  {
93  return new OIDCEndpoint(callback, realm, event);
94  }
Object callback(RealmModel realm, AuthenticationCallback callback, EventBuilder event)
Definition: OIDCIdentityProvider.java:92

◆ createAuthorizationUrl()

UriBuilder org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.createAuthorizationUrl ( AuthenticationRequest  request)
inlineprotectedinherited
303  {
304  final UriBuilder uriBuilder = UriBuilder.fromUri(getConfig().getAuthorizationUrl())
305  .queryParam(OAUTH2_PARAMETER_SCOPE, getConfig().getDefaultScope())
306  .queryParam(OAUTH2_PARAMETER_STATE, request.getState().getEncoded())
307  .queryParam(OAUTH2_PARAMETER_RESPONSE_TYPE, "code")
308  .queryParam(OAUTH2_PARAMETER_CLIENT_ID, getConfig().getClientId())
309  .queryParam(OAUTH2_PARAMETER_REDIRECT_URI, request.getRedirectUri());
310 
311  String loginHint = request.getAuthenticationSession().getClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM);
312  if (getConfig().isLoginHint() && loginHint != null) {
313  uriBuilder.queryParam(OIDCLoginProtocol.LOGIN_HINT_PARAM, loginHint);
314  }
315 
316  if (getConfig().isUiLocales()) {
317  uriBuilder.queryParam(OIDCLoginProtocol.UI_LOCALES_PARAM, session.getContext().resolveLocale(null).toLanguageTag());
318  }
319 
320  String prompt = getConfig().getPrompt();
321  if (prompt == null || prompt.isEmpty()) {
322  prompt = request.getAuthenticationSession().getClientNote(OAuth2Constants.PROMPT);
323  }
324  if (prompt != null) {
325  uriBuilder.queryParam(OAuth2Constants.PROMPT, prompt);
326  }
327 
328  String nonce = request.getAuthenticationSession().getClientNote(OIDCLoginProtocol.NONCE_PARAM);
329  if (nonce == null || nonce.isEmpty()) {
330  nonce = UUID.randomUUID().toString();
331  request.getAuthenticationSession().setClientNote(OIDCLoginProtocol.NONCE_PARAM, nonce);
332  }
333  uriBuilder.queryParam(OIDCLoginProtocol.NONCE_PARAM, nonce);
334 
335  String acr = request.getAuthenticationSession().getClientNote(OAuth2Constants.ACR_VALUES);
336  if (acr != null) {
337  uriBuilder.queryParam(OAuth2Constants.ACR_VALUES, acr);
338  }
339  String forwardParameterConfig = getConfig().getForwardParameters() != null ? getConfig().getForwardParameters(): "";
340  List<String> forwardParameters = Arrays.asList(forwardParameterConfig.split("\\s*,\\s*"));
341  for(String forwardParameter: forwardParameters) {
342  String name = AuthorizationEndpoint.LOGIN_SESSION_NOTE_ADDITIONAL_REQ_PARAMS_PREFIX + forwardParameter.trim();
343  String parameter = request.getAuthenticationSession().getClientNote(name);
344  if(parameter != null && !parameter.isEmpty()) {
345  uriBuilder.queryParam(forwardParameter, parameter);
346  }
347  }
348  return uriBuilder;
349  }
static final String OAUTH2_PARAMETER_RESPONSE_TYPE
Definition: AbstractOAuth2IdentityProvider.java:88
static final String OAUTH2_PARAMETER_STATE
Definition: AbstractOAuth2IdentityProvider.java:87
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
static final String OAUTH2_PARAMETER_SCOPE
Definition: AbstractOAuth2IdentityProvider.java:86
static final String OAUTH2_PARAMETER_CLIENT_ID
Definition: AbstractOAuth2IdentityProvider.java:91
static final String OAUTH2_PARAMETER_REDIRECT_URI
Definition: AbstractOAuth2IdentityProvider.java:89

◆ doGetFederatedIdentity()

BrokeredIdentityContext org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.doGetFederatedIdentity ( String  accessToken)
inlineprotectedinherited
298  {
299  return null;
300  }

◆ exchangeExternal()

final BrokeredIdentityContext org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.exchangeExternal ( EventBuilder  event,
MultivaluedMap< String, String >  params 
)
inlineinherited
519  {
520  if (!supportsExternalExchange()) return null;
521  BrokeredIdentityContext context = exchangeExternalImpl(event, params);
522  if (context != null) {
523  context.setIdp(this);
524  context.setIdpConfig(getConfig());
525  }
526  return context;
527  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
boolean supportsExternalExchange()
Definition: AbstractOAuth2IdentityProvider.java:506
BrokeredIdentityContext exchangeExternalImpl(EventBuilder event, MultivaluedMap< String, String > params)
Definition: AbstractOAuth2IdentityProvider.java:529

◆ exchangeExternalComplete()

void org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.exchangeExternalComplete ( UserSessionModel  userSession,
BrokeredIdentityContext  context,
MultivaluedMap< String, String >  params 
)
inlineinherited
554  {
555  if (context.getContextData().containsKey(OIDCIdentityProvider.VALIDATED_ID_TOKEN))
556  userSession.setNote(FEDERATED_ACCESS_TOKEN, params.getFirst(OAuth2Constants.SUBJECT_TOKEN));
557  if (context.getContextData().containsKey(OIDCIdentityProvider.VALIDATED_ID_TOKEN))
558  userSession.setNote(OIDCIdentityProvider.FEDERATED_ID_TOKEN, params.getFirst(OAuth2Constants.SUBJECT_TOKEN));
559  userSession.setNote(OIDCIdentityProvider.EXCHANGE_PROVIDER, getConfig().getAlias());
560 
561  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126

◆ exchangeExternalImpl()

BrokeredIdentityContext org.keycloak.social.gitlab.GitLabIdentityProvider.exchangeExternalImpl ( EventBuilder  event,
MultivaluedMap< String, String >  params 
)
inlineprotected
93  {
94  return exchangeExternalUserInfoValidationOnly(event, params);
95  }
BrokeredIdentityContext exchangeExternalUserInfoValidationOnly(EventBuilder event, MultivaluedMap< String, String > params)
Definition: AbstractOAuth2IdentityProvider.java:534

◆ exchangeExternalUserInfoValidationOnly()

BrokeredIdentityContext org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.exchangeExternalUserInfoValidationOnly ( EventBuilder  event,
MultivaluedMap< String, String >  params 
)
inlineprotectedinherited
534  {
535  String subjectToken = params.getFirst(OAuth2Constants.SUBJECT_TOKEN);
536  if (subjectToken == null) {
537  event.detail(Details.REASON, OAuth2Constants.SUBJECT_TOKEN + " param unset");
538  event.error(Errors.INVALID_TOKEN);
539  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "token not set", Response.Status.BAD_REQUEST);
540  }
541  String subjectTokenType = params.getFirst(OAuth2Constants.SUBJECT_TOKEN_TYPE);
542  if (subjectTokenType == null) {
543  subjectTokenType = OAuth2Constants.ACCESS_TOKEN_TYPE;
544  }
545  if (!OAuth2Constants.ACCESS_TOKEN_TYPE.equals(subjectTokenType)) {
546  event.detail(Details.REASON, OAuth2Constants.SUBJECT_TOKEN_TYPE + " invalid");
547  event.error(Errors.INVALID_TOKEN_TYPE);
548  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token type", Response.Status.BAD_REQUEST);
549  }
550  return validateExternalTokenThroughUserInfo(event, subjectToken, subjectTokenType);
551  }
BrokeredIdentityContext validateExternalTokenThroughUserInfo(EventBuilder event, String subjectToken, String subjectTokenType)
Definition: AbstractOAuth2IdentityProvider.java:466

◆ exchangeFromToken()

Response org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.exchangeFromToken ( UriInfo  uriInfo,
EventBuilder  event,
ClientModel  authorizedClient,
UserSessionModel  tokenUserSession,
UserModel  tokenSubject,
MultivaluedMap< String, String >  params 
)
inlineinherited
160  {
161  // check to see if we have a token exchange in session
162  // in other words check to see if this session was created by an external exchange
163  Response tokenResponse = hasExternalExchangeToken(event, tokenUserSession, params);
164  if (tokenResponse != null) return tokenResponse;
165 
166  // going further we only support access token type? Why?
167  String requestedType = params.getFirst(OAuth2Constants.REQUESTED_TOKEN_TYPE);
168  if (requestedType != null && !requestedType.equals(OAuth2Constants.ACCESS_TOKEN_TYPE)) {
169  event.detail(Details.REASON, "requested_token_type unsupported");
170  event.error(Errors.INVALID_REQUEST);
171  return exchangeUnsupportedRequiredType();
172  }
173  if (!getConfig().isStoreToken()) {
174  // if token isn't stored, we need to see if this session has been linked
175  String brokerId = tokenUserSession.getNote(Details.IDENTITY_PROVIDER);
176  brokerId = brokerId == null ? tokenUserSession.getNote(IdentityProvider.EXTERNAL_IDENTITY_PROVIDER) : brokerId;
177  if (brokerId == null || !brokerId.equals(getConfig().getAlias())) {
178  event.detail(Details.REASON, "requested_issuer has not linked");
179  event.error(Errors.INVALID_REQUEST);
180  return exchangeNotLinkedNoStore(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
181  }
182  return exchangeSessionToken(uriInfo, event, authorizedClient, tokenUserSession, tokenSubject);
183  } else {
184  return exchangeStoredToken(uriInfo, event, authorizedClient, tokenUserSession, tokenSubject);
185  }
186  }
Response exchangeStoredToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject)
Definition: AbstractOAuth2IdentityProvider.java:234
Response hasExternalExchangeToken(EventBuilder event, UserSessionModel tokenUserSession, MultivaluedMap< String, String > params)
Definition: AbstractOAuth2IdentityProvider.java:195
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
Response exchangeSessionToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject)
Definition: AbstractOAuth2IdentityProvider.java:261

◆ exchangeSessionToken()

Response org.keycloak.broker.oidc.OIDCIdentityProvider.exchangeSessionToken ( UriInfo  uriInfo,
EventBuilder  event,
ClientModel  authorizedClient,
UserSessionModel  tokenUserSession,
UserModel  tokenSubject 
)
inlineprotectedinherited
281  {
282  String refreshToken = tokenUserSession.getNote(FEDERATED_REFRESH_TOKEN);
283  String accessToken = tokenUserSession.getNote(FEDERATED_ACCESS_TOKEN);
284  String idToken = tokenUserSession.getNote(FEDERATED_ID_TOKEN);
285 
286  if (accessToken == null) {
287  event.detail(Details.REASON, "requested_issuer is not linked");
288  event.error(Errors.INVALID_TOKEN);
289  return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
290  }
291  try {
292  long expiration = Long.parseLong(tokenUserSession.getNote(FEDERATED_TOKEN_EXPIRATION));
293  if (expiration == 0 || expiration > Time.currentTime()) {
294  AccessTokenResponse tokenResponse = new AccessTokenResponse();
295  tokenResponse.setExpiresIn(expiration);
296  tokenResponse.setToken(accessToken);
297  tokenResponse.setIdToken(null);
298  tokenResponse.setRefreshToken(null);
299  tokenResponse.setRefreshExpiresIn(0);
300  tokenResponse.getOtherClaims().put(OAuth2Constants.ISSUED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE);
301  tokenResponse.getOtherClaims().put(ACCOUNT_LINK_URL, getLinkingUrl(uriInfo, authorizedClient, tokenUserSession));
302  event.success();
303  return Response.ok(tokenResponse).type(MediaType.APPLICATION_JSON_TYPE).build();
304  }
305  String response = SimpleHttp.doPost(getConfig().getTokenUrl(), session)
306  .param("refresh_token", refreshToken)
308  .param(OAUTH2_PARAMETER_CLIENT_ID, getConfig().getClientId())
309  .param(OAUTH2_PARAMETER_CLIENT_SECRET, getConfig().getClientSecret()).asString();
310  if (response.contains("error")) {
311  logger.debugv("Error refreshing token, refresh token expiration?: {0}", response);
312  event.detail(Details.REASON, "requested_issuer token expired");
313  event.error(Errors.INVALID_TOKEN);
314  return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
315  }
316  AccessTokenResponse newResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
317  long accessTokenExpiration = newResponse.getExpiresIn() > 0 ? Time.currentTime() + newResponse.getExpiresIn() : 0;
318  tokenUserSession.setNote(FEDERATED_TOKEN_EXPIRATION, Long.toString(accessTokenExpiration));
319  tokenUserSession.setNote(FEDERATED_REFRESH_TOKEN, newResponse.getRefreshToken());
320  tokenUserSession.setNote(FEDERATED_ACCESS_TOKEN, newResponse.getToken());
321  tokenUserSession.setNote(FEDERATED_ID_TOKEN, newResponse.getIdToken());
322  newResponse.setIdToken(null);
323  newResponse.setRefreshToken(null);
324  newResponse.setRefreshExpiresIn(0);
325  newResponse.getOtherClaims().clear();
326  newResponse.getOtherClaims().put(OAuth2Constants.ISSUED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE);
327  newResponse.getOtherClaims().put(ACCOUNT_LINK_URL, getLinkingUrl(uriInfo, authorizedClient, tokenUserSession));
328  event.success();
329  return Response.ok(newResponse).type(MediaType.APPLICATION_JSON_TYPE).build();
330  } catch (IOException e) {
331  throw new RuntimeException(e);
332  }
333  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
static final String OAUTH2_PARAMETER_GRANT_TYPE
Definition: AbstractOAuth2IdentityProvider.java:93
static final Logger logger
Definition: OIDCIdentityProvider.java:71
static final String FEDERATED_REFRESH_TOKEN
Definition: AbstractOAuth2IdentityProvider.java:80
static final String OAUTH2_GRANT_TYPE_REFRESH_TOKEN
Definition: AbstractOAuth2IdentityProvider.java:77
static final String OAUTH2_PARAMETER_CLIENT_ID
Definition: AbstractOAuth2IdentityProvider.java:91
static final String FEDERATED_ID_TOKEN
Definition: OIDCIdentityProvider.java:74
static final String FEDERATED_TOKEN_EXPIRATION
Definition: AbstractOAuth2IdentityProvider.java:81
static final String OAUTH2_PARAMETER_CLIENT_SECRET
Definition: AbstractOAuth2IdentityProvider.java:92

◆ exchangeStoredToken()

Response org.keycloak.broker.oidc.OIDCIdentityProvider.exchangeStoredToken ( UriInfo  uriInfo,
EventBuilder  event,
ClientModel  authorizedClient,
UserSessionModel  tokenUserSession,
UserModel  tokenSubject 
)
inlineprotectedinherited
219  {
220  FederatedIdentityModel model = session.users().getFederatedIdentity(tokenSubject, getConfig().getAlias(), authorizedClient.getRealm());
221  if (model == null || model.getToken() == null) {
222  event.detail(Details.REASON, "requested_issuer is not linked");
223  event.error(Errors.INVALID_TOKEN);
224  return exchangeNotLinked(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
225  }
226  try {
227  String modelTokenString = model.getToken();
228  AccessTokenResponse tokenResponse = JsonSerialization.readValue(modelTokenString, AccessTokenResponse.class);
229  Integer exp = (Integer) tokenResponse.getOtherClaims().get(ACCESS_TOKEN_EXPIRATION);
230  if (exp != null && exp < Time.currentTime()) {
231  if (tokenResponse.getRefreshToken() == null) {
232  return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
233  }
234  String response = SimpleHttp.doPost(getConfig().getTokenUrl(), session)
235  .param("refresh_token", tokenResponse.getRefreshToken())
237  .param(OAUTH2_PARAMETER_CLIENT_ID, getConfig().getClientId())
238  .param(OAUTH2_PARAMETER_CLIENT_SECRET, getConfig().getClientSecret()).asString();
239  if (response.contains("error")) {
240  logger.debugv("Error refreshing token, refresh token expiration?: {0}", response);
241  model.setToken(null);
242  session.users().updateFederatedIdentity(authorizedClient.getRealm(), tokenSubject, model);
243  event.detail(Details.REASON, "requested_issuer token expired");
244  event.error(Errors.INVALID_TOKEN);
245  return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
246  }
247  AccessTokenResponse newResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
248  if (newResponse.getExpiresIn() > 0) {
249  int accessTokenExpiration = Time.currentTime() + (int) newResponse.getExpiresIn();
250  newResponse.getOtherClaims().put(ACCESS_TOKEN_EXPIRATION, accessTokenExpiration);
251  response = JsonSerialization.writeValueAsString(newResponse);
252  }
253  String oldToken = tokenUserSession.getNote(FEDERATED_ACCESS_TOKEN);
254  if (oldToken != null && oldToken.equals(tokenResponse.getToken())) {
255  int accessTokenExpiration = newResponse.getExpiresIn() > 0 ? Time.currentTime() + (int) newResponse.getExpiresIn() : 0;
256  tokenUserSession.setNote(FEDERATED_TOKEN_EXPIRATION, Long.toString(accessTokenExpiration));
257  tokenUserSession.setNote(FEDERATED_REFRESH_TOKEN, newResponse.getRefreshToken());
258  tokenUserSession.setNote(FEDERATED_ACCESS_TOKEN, newResponse.getToken());
259  tokenUserSession.setNote(FEDERATED_ID_TOKEN, newResponse.getIdToken());
260 
261  }
262  model.setToken(response);
263  tokenResponse = newResponse;
264  } else if (exp != null) {
265  tokenResponse.setExpiresIn(exp - Time.currentTime());
266  }
267  tokenResponse.setIdToken(null);
268  tokenResponse.setRefreshToken(null);
269  tokenResponse.setRefreshExpiresIn(0);
270  tokenResponse.getOtherClaims().clear();
271  tokenResponse.getOtherClaims().put(OAuth2Constants.ISSUED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE);
272  tokenResponse.getOtherClaims().put(ACCOUNT_LINK_URL, getLinkingUrl(uriInfo, authorizedClient, tokenUserSession));
273  event.success();
274  return Response.ok(tokenResponse).type(MediaType.APPLICATION_JSON_TYPE).build();
275  } catch (IOException e) {
276  throw new RuntimeException(e);
277  }
278  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
static final String OAUTH2_PARAMETER_GRANT_TYPE
Definition: AbstractOAuth2IdentityProvider.java:93
static final String ACCESS_TOKEN_EXPIRATION
Definition: OIDCIdentityProvider.java:78
static final Logger logger
Definition: OIDCIdentityProvider.java:71
static final String FEDERATED_REFRESH_TOKEN
Definition: AbstractOAuth2IdentityProvider.java:80
static final String OAUTH2_GRANT_TYPE_REFRESH_TOKEN
Definition: AbstractOAuth2IdentityProvider.java:77
static final String OAUTH2_PARAMETER_CLIENT_ID
Definition: AbstractOAuth2IdentityProvider.java:91
static final String FEDERATED_ID_TOKEN
Definition: OIDCIdentityProvider.java:74
static final String FEDERATED_TOKEN_EXPIRATION
Definition: AbstractOAuth2IdentityProvider.java:81
static final String OAUTH2_PARAMETER_CLIENT_SECRET
Definition: AbstractOAuth2IdentityProvider.java:92

◆ extractIdentity()

BrokeredIdentityContext org.keycloak.social.gitlab.GitLabIdentityProvider.extractIdentity ( AccessTokenResponse  tokenResponse,
String  accessToken,
JsonWebToken  idToken 
) throws IOException
inlineprotected
136  {
137 
138  SimpleHttp.Response response = null;
139  int status = 0;
140 
141  for (int i = 0; i < 10; i++) {
142  try {
143  String userInfoUrl = getUserInfoUrl();
144  response = SimpleHttp.doGet(userInfoUrl, session)
145  .header("Authorization", "Bearer " + accessToken).asResponse();
146  status = response.getStatus();
147  } catch (IOException e) {
148  logger.debug("Failed to invoke user info for external exchange", e);
149  }
150  if (status == 200) break;
151  response.close();
152  try {
153  Thread.sleep(200);
154  } catch (InterruptedException e) {
155  throw new RuntimeException(e);
156  }
157  }
158  if (status != 200) {
159  logger.debug("Failed to invoke user info status: " + status);
160  throw new IdentityBrokerException("Gitlab user info call failure");
161  }
162  JsonNode profile = null;
163  try {
164  profile = response.asJson();
165  } catch (IOException e) {
166  throw new IdentityBrokerException("Gitlab user info call failure");
167  }
168  String id = getJsonProperty(profile, "id");
169  if (id == null) {
170  throw new IdentityBrokerException("Gitlab id claim is null from user info json");
171  }
172  BrokeredIdentityContext identity = gitlabExtractFromProfile(profile);
173  identity.getContextData().put(FEDERATED_ACCESS_TOKEN_RESPONSE, tokenResponse);
174  identity.getContextData().put(VALIDATED_ID_TOKEN, idToken);
175  processAccessTokenResponse(identity, tokenResponse);
176 
177  return identity;
178  }
static final String VALIDATED_ID_TOKEN
Definition: OIDCIdentityProvider.java:77
BrokeredIdentityContext gitlabExtractFromProfile(JsonNode profile)
Definition: GitLabIdentityProvider.java:108
static final Logger logger
Definition: OIDCIdentityProvider.java:71
void processAccessTokenResponse(BrokeredIdentityContext context, AccessTokenResponse response)
Definition: OIDCIdentityProvider.java:213
static final String FEDERATED_ACCESS_TOKEN_RESPONSE
Definition: OIDCIdentityProvider.java:76
String getJsonProperty(JsonNode jsonNode, String name)
Definition: AbstractOAuth2IdentityProvider.java:358
String getUserInfoUrl()
Definition: OIDCIdentityProvider.java:433

◆ extractIdentityFromProfile()

BrokeredIdentityContext org.keycloak.social.gitlab.GitLabIdentityProvider.extractIdentityFromProfile ( EventBuilder  event,
JsonNode  profile 
)
inlineprotected
98  {
99  String id = getJsonProperty(profile, "id");
100  if (id == null) {
101  event.detail(Details.REASON, "id claim is null from user info json");
102  event.error(Errors.INVALID_TOKEN);
103  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token", Response.Status.BAD_REQUEST);
104  }
105  return gitlabExtractFromProfile(profile);
106  }
BrokeredIdentityContext gitlabExtractFromProfile(JsonNode profile)
Definition: GitLabIdentityProvider.java:108
String getJsonProperty(JsonNode jsonNode, String name)
Definition: AbstractOAuth2IdentityProvider.java:358

◆ extractTokenFromResponse()

String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.extractTokenFromResponse ( String  response,
String  tokenName 
)
inlineprotectedinherited
130  {
131  if(response == null)
132  return null;
133 
134  if (response.startsWith("{")) {
135  try {
136  JsonNode node = mapper.readTree(response);
137  if(node.has(tokenName)){
138  String s = node.get(tokenName).textValue();
139  if(s == null || s.trim().isEmpty())
140  return null;
141  return s;
142  } else {
143  return null;
144  }
145  } catch (IOException e) {
146  throw new IdentityBrokerException("Could not extract token [" + tokenName + "] from response [" + response + "] due: " + e.getMessage(), e);
147  }
148  } else {
149  Matcher matcher = Pattern.compile(tokenName + "=([^&]+)").matcher(response);
150 
151  if (matcher.find()) {
152  return matcher.group(1);
153  }
154  }
155 
156  return null;
157  }
static ObjectMapper mapper
Definition: AbstractOAuth2IdentityProvider.java:83

◆ getAccessTokenResponseParameter()

String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.getAccessTokenResponseParameter ( )
inlineprotectedinherited
293  {
295  }
static final String OAUTH2_PARAMETER_ACCESS_TOKEN
Definition: AbstractOAuth2IdentityProvider.java:85

◆ getConfig()

126  {
127  return super.getConfig();
128  }

◆ getDefaultScopes()

String org.keycloak.broker.oidc.OIDCIdentityProvider.getDefaultScopes ( )
inlineprotectedinherited
516  {
517  return "openid";
518  }

◆ getFederatedIdentity()

BrokeredIdentityContext org.keycloak.broker.oidc.OIDCIdentityProvider.getFederatedIdentity ( String  response)
inlineinherited
337  {
338  AccessTokenResponse tokenResponse = null;
339  try {
340  tokenResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
341  } catch (IOException e) {
342  throw new IdentityBrokerException("Could not decode access token response.", e);
343  }
344  String accessToken = verifyAccessToken(tokenResponse);
345 
346  String encodedIdToken = tokenResponse.getIdToken();
347 
348  JsonWebToken idToken = validateToken(encodedIdToken);
349 
350  try {
351  BrokeredIdentityContext identity = extractIdentity(tokenResponse, accessToken, idToken);
352 
353  if (getConfig().isStoreToken()) {
354  if (tokenResponse.getExpiresIn() > 0) {
355  long accessTokenExpiration = Time.currentTime() + tokenResponse.getExpiresIn();
356  tokenResponse.getOtherClaims().put(ACCESS_TOKEN_EXPIRATION, accessTokenExpiration);
357  response = JsonSerialization.writeValueAsString(tokenResponse);
358  }
359  identity.setToken(response);
360  }
361 
362  return identity;
363  } catch (Exception e) {
364  throw new IdentityBrokerException("Could not fetch attributes from userinfo endpoint.", e);
365  }
366  }
JsonWebToken validateToken(String encodedToken)
Definition: OIDCIdentityProvider.java:455
String verifyAccessToken(AccessTokenResponse tokenResponse)
Definition: OIDCIdentityProvider.java:438
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
static final String ACCESS_TOKEN_EXPIRATION
Definition: OIDCIdentityProvider.java:78
BrokeredIdentityContext extractIdentity(AccessTokenResponse tokenResponse, String accessToken, JsonWebToken idToken)
Definition: OIDCIdentityProvider.java:369

◆ getJsonProperty()

String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.getJsonProperty ( JsonNode  jsonNode,
String  name 
)
inlineinherited

Get JSON property as text. JSON numbers and booleans are converted to text. Empty string is converted to null.

引数
jsonNodeto get property from
nameof property to get
戻り値
string value of the property or null.
358  {
359  if (jsonNode.has(name) && !jsonNode.get(name).isNull()) {
360  String s = jsonNode.get(name).asText();
361  if(s != null && !s.isEmpty())
362  return s;
363  else
364  return null;
365  }
366 
367  return null;
368  }

◆ getProfileEndpointForValidation()

String org.keycloak.social.gitlab.GitLabIdentityProvider.getProfileEndpointForValidation ( EventBuilder  event)
inlineprotected
80  {
81  return getUserInfoUrl();
82  }
String getUserInfoUrl()
Definition: OIDCIdentityProvider.java:433

◆ getUserInfoUrl()

String org.keycloak.broker.oidc.OIDCIdentityProvider.getUserInfoUrl ( )
inlineprotectedinherited
433  {
434  return getConfig().getUserInfoUrl();
435  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126

◆ getusernameClaimNameForIdToken()

String org.keycloak.social.gitlab.GitLabIdentityProvider.getusernameClaimNameForIdToken ( )
inlineprotected
70  {
71  return IDToken.NICKNAME;
72  }

◆ getUsernameFromUserInfo()

String org.keycloak.social.gitlab.GitLabIdentityProvider.getUsernameFromUserInfo ( JsonNode  userInfo)
inlineprotected
66  {
67  return getJsonProperty(userInfo, "username");
68  }
String getJsonProperty(JsonNode jsonNode, String name)
Definition: AbstractOAuth2IdentityProvider.java:358

◆ gitlabExtractFromProfile()

BrokeredIdentityContext org.keycloak.social.gitlab.GitLabIdentityProvider.gitlabExtractFromProfile ( JsonNode  profile)
inlineprivate
108  {
109  String id = getJsonProperty(profile, "id");
110  BrokeredIdentityContext identity = new BrokeredIdentityContext(id);
111 
112  String name = getJsonProperty(profile, "name");
113  String preferredUsername = getJsonProperty(profile, "username");
114  String email = getJsonProperty(profile, "email");
115  AbstractJsonUserAttributeMapper.storeUserProfileForMapper(identity, profile, getConfig().getAlias());
116 
117  identity.setId(id);
118  identity.setName(name);
119  identity.setEmail(email);
120 
121  identity.setBrokerUserId(getConfig().getAlias() + "." + id);
122 
123  if (preferredUsername == null) {
124  preferredUsername = email;
125  }
126 
127  if (preferredUsername == null) {
128  preferredUsername = id;
129  }
130 
131  identity.setUsername(preferredUsername);
132  return identity;
133  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
String getJsonProperty(JsonNode jsonNode, String name)
Definition: AbstractOAuth2IdentityProvider.java:358

◆ hasExternalExchangeToken()

Response org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.hasExternalExchangeToken ( EventBuilder  event,
UserSessionModel  tokenUserSession,
MultivaluedMap< String, String >  params 
)
inlineprotectedinherited

check to see if we have a token exchange in session in other words check to see if this session was created by an external exchange

引数
tokenUserSession
params
戻り値
195  {
196  if (getConfig().getAlias().equals(tokenUserSession.getNote(OIDCIdentityProvider.EXCHANGE_PROVIDER))) {
197 
198  String requestedType = params.getFirst(OAuth2Constants.REQUESTED_TOKEN_TYPE);
199  if ((requestedType == null || requestedType.equals(OAuth2Constants.ACCESS_TOKEN_TYPE))) {
200  String accessToken = tokenUserSession.getNote(FEDERATED_ACCESS_TOKEN);
201  if (accessToken != null) {
202  AccessTokenResponse tokenResponse = new AccessTokenResponse();
203  tokenResponse.setToken(accessToken);
204  tokenResponse.setIdToken(null);
205  tokenResponse.setRefreshToken(null);
206  tokenResponse.setRefreshExpiresIn(0);
207  tokenResponse.setExpiresIn(0);
208  tokenResponse.getOtherClaims().clear();
209  tokenResponse.getOtherClaims().put(OAuth2Constants.ISSUED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE);
210  event.success();
211  return Response.ok(tokenResponse).type(MediaType.APPLICATION_JSON_TYPE).build();
212  }
213  } else if (OAuth2Constants.ID_TOKEN_TYPE.equals(requestedType)) {
214  String idToken = tokenUserSession.getNote(OIDCIdentityProvider.FEDERATED_ID_TOKEN);
215  if (idToken != null) {
216  AccessTokenResponse tokenResponse = new AccessTokenResponse();
217  tokenResponse.setToken(null);
218  tokenResponse.setIdToken(idToken);
219  tokenResponse.setRefreshToken(null);
220  tokenResponse.setRefreshExpiresIn(0);
221  tokenResponse.setExpiresIn(0);
222  tokenResponse.getOtherClaims().clear();
223  tokenResponse.getOtherClaims().put(OAuth2Constants.ISSUED_TOKEN_TYPE, OAuth2Constants.ID_TOKEN_TYPE);
224  event.success();
225  return Response.ok(tokenResponse).type(MediaType.APPLICATION_JSON_TYPE).build();
226  }
227 
228  }
229 
230  }
231  return null;
232  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126

◆ isIssuer()

boolean org.keycloak.social.gitlab.GitLabIdentityProvider.isIssuer ( String  issuer,
MultivaluedMap< String, String >  params 
)
inline
85  {
86  String requestedIssuer = params.getFirst(OAuth2Constants.SUBJECT_ISSUER);
87  if (requestedIssuer == null) requestedIssuer = issuer;
88  return requestedIssuer.equals(getConfig().getAlias());
89  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126

◆ keycloakInitiatedBrowserLogout()

Response org.keycloak.broker.oidc.OIDCIdentityProvider.keycloakInitiatedBrowserLogout ( KeycloakSession  session,
UserSessionModel  userSession,
UriInfo  uriInfo,
RealmModel  realm 
)
inlineinherited
153  {
154  if (getConfig().getLogoutUrl() == null || getConfig().getLogoutUrl().trim().equals("")) return null;
155  String idToken = getIDTokenForLogout(session, userSession);
156  if (idToken != null && getConfig().isBackchannelSupported()) {
157  backchannelLogout(userSession, idToken);
158  return null;
159  } else {
160  String sessionId = userSession.getId();
161  UriBuilder logoutUri = UriBuilder.fromUri(getConfig().getLogoutUrl())
162  .queryParam("state", sessionId);
163  if (idToken != null) logoutUri.queryParam("id_token_hint", idToken);
164  String redirect = RealmsResource.brokerUrl(uriInfo)
165  .path(IdentityBrokerService.class, "getEndpoint")
166  .path(OIDCEndpoint.class, "logoutResponse")
167  .build(realm.getName(), getConfig().getAlias()).toString();
168  logoutUri.queryParam("post_logout_redirect_uri", redirect);
169  Response response = Response.status(302).location(logoutUri.build()).build();
170  return response;
171  }
172  }
void backchannelLogout(KeycloakSession session, UserSessionModel userSession, UriInfo uriInfo, RealmModel realm)
Definition: OIDCIdentityProvider.java:126
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
String getIDTokenForLogout(KeycloakSession session, UserSessionModel userSession)
Definition: OIDCIdentityProvider.java:194

◆ performLogin()

Response org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.performLogin ( AuthenticationRequest  request)
inlineinherited
110  {
111  try {
112  URI authorizationUrl = createAuthorizationUrl(request).build();
113 
114  return Response.seeOther(authorizationUrl).build();
115  } catch (Exception e) {
116  throw new IdentityBrokerException("Could not create authentication request.", e);
117  }
118  }
UriBuilder createAuthorizationUrl(AuthenticationRequest request)
Definition: AbstractOAuth2IdentityProvider.java:303

◆ processAccessTokenResponse()

void org.keycloak.broker.oidc.OIDCIdentityProvider.processAccessTokenResponse ( BrokeredIdentityContext  context,
AccessTokenResponse  response 
)
inlineprotectedinherited
213  {
214 
215 
216  }

◆ refreshTokenForLogout()

String org.keycloak.broker.oidc.OIDCIdentityProvider.refreshTokenForLogout ( KeycloakSession  session,
UserSessionModel  userSession 
)
inlineinherited

Returns access token response as a string from a refresh token invocation on the remote OIDC broker

引数
session
userSession
戻り値
181  {
182  String refreshToken = userSession.getNote(FEDERATED_REFRESH_TOKEN);
183  try {
184  return SimpleHttp.doPost(getConfig().getTokenUrl(), session)
185  .param("refresh_token", refreshToken)
187  .param(OAUTH2_PARAMETER_CLIENT_ID, getConfig().getClientId())
188  .param(OAUTH2_PARAMETER_CLIENT_SECRET, getConfig().getClientSecret()).asString();
189  } catch (IOException e) {
190  throw new RuntimeException(e);
191  }
192  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
static final String OAUTH2_PARAMETER_GRANT_TYPE
Definition: AbstractOAuth2IdentityProvider.java:93
static final String FEDERATED_REFRESH_TOKEN
Definition: AbstractOAuth2IdentityProvider.java:80
static final String OAUTH2_GRANT_TYPE_REFRESH_TOKEN
Definition: AbstractOAuth2IdentityProvider.java:77
static final String OAUTH2_PARAMETER_CLIENT_ID
Definition: AbstractOAuth2IdentityProvider.java:91
static final String OAUTH2_PARAMETER_CLIENT_SECRET
Definition: AbstractOAuth2IdentityProvider.java:92

◆ retrieveToken()

Response org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.retrieveToken ( KeycloakSession  session,
FederatedIdentityModel  identity 
)
inlineinherited
121  {
122  return Response.ok(identity.getToken()).build();
123  }

◆ supportsExternalExchange()

boolean org.keycloak.social.gitlab.GitLabIdentityProvider.supportsExternalExchange ( )
inlineprotected
75  {
76  return true;
77  }

◆ validateExternalTokenThroughUserInfo()

BrokeredIdentityContext org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.validateExternalTokenThroughUserInfo ( EventBuilder  event,
String  subjectToken,
String  subjectTokenType 
)
inlineprotectedinherited
466  {
467  event.detail("validation_method", "user info");
468  SimpleHttp.Response response = null;
469  int status = 0;
470  try {
471  String userInfoUrl = getProfileEndpointForValidation(event);
472  response = buildUserInfoRequest(subjectToken, userInfoUrl).asResponse();
473  status = response.getStatus();
474  } catch (IOException e) {
475  logger.debug("Failed to invoke user info for external exchange", e);
476  }
477  if (status != 200) {
478  logger.debug("Failed to invoke user info status: " + status);
479  event.detail(Details.REASON, "user info call failure");
480  event.error(Errors.INVALID_TOKEN);
481  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token", Response.Status.BAD_REQUEST);
482  }
483  JsonNode profile = null;
484  try {
485  profile = response.asJson();
486  } catch (IOException e) {
487  event.detail(Details.REASON, "user info call failure");
488  event.error(Errors.INVALID_TOKEN);
489  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token", Response.Status.BAD_REQUEST);
490  }
491  BrokeredIdentityContext context = extractIdentityFromProfile(event, profile);
492  if (context.getId() == null) {
493  event.detail(Details.REASON, "user info call failure");
494  event.error(Errors.INVALID_TOKEN);
495  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token", Response.Status.BAD_REQUEST);
496  }
497  return context;
498  }
String getProfileEndpointForValidation(EventBuilder event)
Definition: AbstractOAuth2IdentityProvider.java:456
static final Logger logger
Definition: AbstractOAuth2IdentityProvider.java:75
BrokeredIdentityContext extractIdentityFromProfile(EventBuilder event, JsonNode node)
Definition: AbstractOAuth2IdentityProvider.java:462
SimpleHttp buildUserInfoRequest(String subjectToken, String userInfoUrl)
Definition: AbstractOAuth2IdentityProvider.java:500

◆ validateJwt()

final BrokeredIdentityContext org.keycloak.broker.oidc.OIDCIdentityProvider.validateJwt ( EventBuilder  event,
String  subjectToken,
String  subjectTokenType 
)
inlineprotectedinherited
591  {
592  if (!getConfig().isValidateSignature()) {
593  return validateExternalTokenThroughUserInfo(event, subjectToken, subjectTokenType);
594  }
595  event.detail("validation_method", "signature");
596  if (getConfig().isUseJwksUrl()) {
597  if (getConfig().getJwksUrl() == null) {
598  event.detail(Details.REASON, "jwks url unset");
599  event.error(Errors.INVALID_CONFIG);
600  throw new ErrorResponseException(Errors.INVALID_CONFIG, "Invalid server config", Response.Status.BAD_REQUEST);
601  }
602  } else if (getConfig().getPublicKeySignatureVerifier() == null) {
603  event.detail(Details.REASON, "public key unset");
604  event.error(Errors.INVALID_CONFIG);
605  throw new ErrorResponseException(Errors.INVALID_CONFIG, "Invalid server config", Response.Status.BAD_REQUEST);
606  }
607 
608  JsonWebToken parsedToken = null;
609  try {
610  parsedToken = validateToken(subjectToken, true);
611  } catch (IdentityBrokerException e) {
612  logger.debug("Unable to validate token for exchange", e);
613  event.detail(Details.REASON, "token validation failure");
614  event.error(Errors.INVALID_TOKEN);
615  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token", Response.Status.BAD_REQUEST);
616  }
617 
618  try {
619 
620  boolean idTokenType = OAuth2Constants.ID_TOKEN_TYPE.equals(subjectTokenType);
621  BrokeredIdentityContext context = extractIdentity(null, idTokenType ? null : subjectToken, parsedToken);
622  if (context == null) {
623  event.detail(Details.REASON, "Failed to extract identity from token");
624  event.error(Errors.INVALID_TOKEN);
625  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token", Response.Status.BAD_REQUEST);
626 
627  }
628  if (idTokenType) {
629  context.getContextData().put(VALIDATED_ID_TOKEN, subjectToken);
630  } else {
631  context.getContextData().put(KeycloakOIDCIdentityProvider.VALIDATED_ACCESS_TOKEN, parsedToken);
632  }
633  context.getContextData().put(EXCHANGE_PROVIDER, getConfig().getAlias());
634  context.setIdp(this);
635  context.setIdpConfig(getConfig());
636  return context;
637  } catch (IOException e) {
638  logger.debug("Unable to extract identity from identity token", e);
639  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token", Response.Status.BAD_REQUEST);
640  }
641 
642 
643  }
static final String VALIDATED_ID_TOKEN
Definition: OIDCIdentityProvider.java:77
JsonWebToken validateToken(String encodedToken)
Definition: OIDCIdentityProvider.java:455
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
static final Logger logger
Definition: OIDCIdentityProvider.java:71
static final String EXCHANGE_PROVIDER
Definition: OIDCIdentityProvider.java:79
BrokeredIdentityContext extractIdentity(AccessTokenResponse tokenResponse, String accessToken, JsonWebToken idToken)
Definition: OIDCIdentityProvider.java:369
BrokeredIdentityContext validateExternalTokenThroughUserInfo(EventBuilder event, String subjectToken, String subjectTokenType)
Definition: AbstractOAuth2IdentityProvider.java:466

◆ validateToken() [1/2]

JsonWebToken org.keycloak.broker.oidc.OIDCIdentityProvider.validateToken ( String  encodedToken)
inlineprotectedinherited
455  {
456  boolean ignoreAudience = false;
457 
458  return validateToken(encodedToken, ignoreAudience);
459  }
JsonWebToken validateToken(String encodedToken)
Definition: OIDCIdentityProvider.java:455

◆ validateToken() [2/2]

JsonWebToken org.keycloak.broker.oidc.OIDCIdentityProvider.validateToken ( String  encodedToken,
boolean  ignoreAudience 
)
inlineprotectedinherited
461  {
462  if (encodedToken == null) {
463  throw new IdentityBrokerException("No token from server.");
464  }
465 
466  JsonWebToken token;
467  try {
468  JWSInput jws = new JWSInput(encodedToken);
469  if (!verify(jws)) {
470  throw new IdentityBrokerException("token signature validation failed");
471  }
472  token = jws.readJsonContent(JsonWebToken.class);
473  } catch (JWSInputException e) {
474  throw new IdentityBrokerException("Invalid token", e);
475  }
476 
477  String iss = token.getIssuer();
478 
479  if (!token.isActive(getConfig().getAllowedClockSkew())) {
480  throw new IdentityBrokerException("Token is no longer valid");
481  }
482 
483  if (!ignoreAudience && !token.hasAudience(getConfig().getClientId())) {
484  throw new IdentityBrokerException("Wrong audience from token.");
485  }
486 
487  String trustedIssuers = getConfig().getIssuer();
488 
489  if (trustedIssuers != null && trustedIssuers.length() > 0) {
490  String[] issuers = trustedIssuers.split(",");
491 
492  for (String trustedIssuer : issuers) {
493  if (iss != null && iss.equals(trustedIssuer.trim())) {
494  return token;
495  }
496  }
497 
498  throw new IdentityBrokerException("Wrong issuer from token. Got: " + iss + " expected: " + getConfig().getIssuer());
499  }
500 
501  return token;
502  }
boolean verify(JWSInput jws)
Definition: OIDCIdentityProvider.java:447
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126

◆ verify()

boolean org.keycloak.broker.oidc.OIDCIdentityProvider.verify ( JWSInput  jws)
inlineprotectedinherited
447  {
448  if (!getConfig().isValidateSignature()) return true;
449 
450  PublicKey publicKey = PublicKeyStorageManager.getIdentityProviderPublicKey(session, session.getContext().getRealm(), getConfig(), jws);
451 
452  return publicKey != null && RSAProvider.verify(jws, publicKey);
453  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126

メンバ詳解

◆ ACCESS_DENIED

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.ACCESS_DENIED
staticinherited

◆ ACCESS_TOKEN_EXPIRATION

final String org.keycloak.broker.oidc.OIDCIdentityProvider.ACCESS_TOKEN_EXPIRATION = "accessTokenExpiration"
staticinherited

◆ API_SCOPE

final String org.keycloak.social.gitlab.GitLabIdentityProvider.API_SCOPE = "api"
static

◆ AUTH_URL

final String org.keycloak.social.gitlab.GitLabIdentityProvider.AUTH_URL = "https://gitlab.com/oauth/authorize"
static

◆ EXCHANGE_PROVIDER

final String org.keycloak.broker.oidc.OIDCIdentityProvider.EXCHANGE_PROVIDER = "EXCHANGE_PROVIDER"
staticinherited

◆ FEDERATED_ACCESS_TOKEN_RESPONSE

final String org.keycloak.broker.oidc.OIDCIdentityProvider.FEDERATED_ACCESS_TOKEN_RESPONSE = "FEDERATED_ACCESS_TOKEN_RESPONSE"
staticinherited

◆ FEDERATED_ID_TOKEN

final String org.keycloak.broker.oidc.OIDCIdentityProvider.FEDERATED_ID_TOKEN = "FEDERATED_ID_TOKEN"
staticinherited

◆ FEDERATED_REFRESH_TOKEN

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.FEDERATED_REFRESH_TOKEN
staticinherited

◆ FEDERATED_TOKEN_EXPIRATION

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.FEDERATED_TOKEN_EXPIRATION
staticinherited

◆ logger

final Logger org.keycloak.broker.oidc.OIDCIdentityProvider.logger = Logger.getLogger(OIDCIdentityProvider.class)
staticprotectedinherited

◆ mapper

ObjectMapper org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.mapper
staticprotectedinherited

◆ OAUTH2_GRANT_TYPE_AUTHORIZATION_CODE

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_GRANT_TYPE_AUTHORIZATION_CODE
staticinherited

◆ OAUTH2_GRANT_TYPE_REFRESH_TOKEN

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_GRANT_TYPE_REFRESH_TOKEN
staticinherited

◆ OAUTH2_PARAMETER_ACCESS_TOKEN

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_PARAMETER_ACCESS_TOKEN
staticinherited

◆ OAUTH2_PARAMETER_CLIENT_ID

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_PARAMETER_CLIENT_ID
staticinherited

◆ OAUTH2_PARAMETER_CLIENT_SECRET

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_PARAMETER_CLIENT_SECRET
staticinherited

◆ OAUTH2_PARAMETER_CODE

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_PARAMETER_CODE
staticinherited

◆ OAUTH2_PARAMETER_GRANT_TYPE

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_PARAMETER_GRANT_TYPE
staticinherited

◆ OAUTH2_PARAMETER_REDIRECT_URI

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_PARAMETER_REDIRECT_URI
staticinherited

◆ OAUTH2_PARAMETER_RESPONSE_TYPE

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_PARAMETER_RESPONSE_TYPE
staticinherited

◆ OAUTH2_PARAMETER_SCOPE

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_PARAMETER_SCOPE
staticinherited

◆ OAUTH2_PARAMETER_STATE

final String org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider< C extends OAuth2IdentityProviderConfig >.OAUTH2_PARAMETER_STATE
staticinherited

◆ SCOPE_OPENID

final String org.keycloak.broker.oidc.OIDCIdentityProvider.SCOPE_OPENID = "openid"
staticinherited

◆ TOKEN_URL

final String org.keycloak.social.gitlab.GitLabIdentityProvider.TOKEN_URL = "https://gitlab.com/oauth/token"
static

◆ USER_INFO

final String org.keycloak.social.gitlab.GitLabIdentityProvider.USER_INFO = "https://gitlab.com/api/v4/user"
static

◆ VALIDATED_ID_TOKEN

final String org.keycloak.broker.oidc.OIDCIdentityProvider.VALIDATED_ID_TOKEN = "VALIDATED_ID_TOKEN"
staticinherited

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