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

クラス

class  OIDCEndpoint
 

公開メンバ関数

 OIDCIdentityProvider (KeycloakSession session, OIDCIdentityProviderConfig config)
 
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)
 
boolean isIssuer (String issuer, MultivaluedMap< String, String > params)
 
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 SCOPE_OPENID = "openid"
 
static final String FEDERATED_ID_TOKEN = "FEDERATED_ID_TOKEN"
 
static final String USER_INFO = "UserInfo"
 
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
 

限定公開メンバ関数

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)
 
BrokeredIdentityContext extractIdentity (AccessTokenResponse tokenResponse, String accessToken, JsonWebToken idToken) throws IOException
 
String getusernameClaimNameForIdToken ()
 
String getUserInfoUrl ()
 
boolean verify (JWSInput jws)
 
JsonWebToken validateToken (String encodedToken)
 
JsonWebToken validateToken (String encodedToken, boolean ignoreAudience)
 
String getDefaultScopes ()
 
boolean supportsExternalExchange ()
 
String getProfileEndpointForValidation (EventBuilder event)
 
BrokeredIdentityContext extractIdentityFromProfile (EventBuilder event, JsonNode userInfo)
 
String getUsernameFromUserInfo (JsonNode userInfo)
 
final BrokeredIdentityContext validateJwt (EventBuilder event, String subjectToken, String subjectTokenType)
 
BrokeredIdentityContext exchangeExternalImpl (EventBuilder event, MultivaluedMap< String, String > params)
 
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
 

非公開メンバ関数

String getIDTokenForLogout (KeycloakSession session, UserSessionModel userSession)
 
String verifyAccessToken (AccessTokenResponse tokenResponse)
 

詳解

著者
Pedro Igor

構築子と解体子

◆ OIDCIdentityProvider()

org.keycloak.broker.oidc.OIDCIdentityProvider.OIDCIdentityProvider ( KeycloakSession  session,
OIDCIdentityProviderConfig  config 
)
inline
81  {
82  super(session, config);
83 
84  String defaultScope = config.getDefaultScope();
85 
86  if (!defaultScope.contains(SCOPE_OPENID)) {
87  config.setDefaultScope((SCOPE_OPENID + " " + defaultScope).trim());
88  }
89  }
static final String SCOPE_OPENID
Definition: OIDCIdentityProvider.java:73

関数詳解

◆ 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 
)
inline
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 
)
inline
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 
)
inlineprotected
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 
)
inline
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.broker.oidc.OIDCIdentityProvider.exchangeExternalImpl ( EventBuilder  event,
MultivaluedMap< String, String >  params 
)
inlineprotected
646  {
647  if (!supportsExternalExchange()) return null;
648  String subjectToken = params.getFirst(OAuth2Constants.SUBJECT_TOKEN);
649  if (subjectToken == null) {
650  event.detail(Details.REASON, OAuth2Constants.SUBJECT_TOKEN + " param unset");
651  event.error(Errors.INVALID_TOKEN);
652  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "token not set", Response.Status.BAD_REQUEST);
653  }
654  String subjectTokenType = params.getFirst(OAuth2Constants.SUBJECT_TOKEN_TYPE);
655  if (subjectTokenType == null) {
656  subjectTokenType = OAuth2Constants.ACCESS_TOKEN_TYPE;
657  }
658  if (OAuth2Constants.JWT_TOKEN_TYPE.equals(subjectTokenType) || OAuth2Constants.ID_TOKEN_TYPE.equals(subjectTokenType)) {
659  return validateJwt(event, subjectToken, subjectTokenType);
660  } else if (OAuth2Constants.ACCESS_TOKEN_TYPE.equals(subjectTokenType)) {
661  return validateExternalTokenThroughUserInfo(event, subjectToken, subjectTokenType);
662  } else {
663  event.detail(Details.REASON, OAuth2Constants.SUBJECT_TOKEN_TYPE + " invalid");
664  event.error(Errors.INVALID_TOKEN_TYPE);
665  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token type", Response.Status.BAD_REQUEST);
666  }
667  }
final BrokeredIdentityContext validateJwt(EventBuilder event, String subjectToken, String subjectTokenType)
Definition: OIDCIdentityProvider.java:591
BrokeredIdentityContext validateExternalTokenThroughUserInfo(EventBuilder event, String subjectToken, String subjectTokenType)
Definition: AbstractOAuth2IdentityProvider.java:466
boolean supportsExternalExchange()
Definition: OIDCIdentityProvider.java:538

◆ 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 
)
inlineprotected
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 
)
inlineprotected
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.broker.oidc.OIDCIdentityProvider.extractIdentity ( AccessTokenResponse  tokenResponse,
String  accessToken,
JsonWebToken  idToken 
) throws IOException
inlineprotected
369  {
370  String id = idToken.getSubject();
371  BrokeredIdentityContext identity = new BrokeredIdentityContext(id);
372  String name = (String) idToken.getOtherClaims().get(IDToken.NAME);
373  String preferredUsername = (String) idToken.getOtherClaims().get(getusernameClaimNameForIdToken());
374  String email = (String) idToken.getOtherClaims().get(IDToken.EMAIL);
375 
376  if (!getConfig().isDisableUserInfoService()) {
377  String userInfoUrl = getUserInfoUrl();
378  if (userInfoUrl != null && !userInfoUrl.isEmpty() && (id == null || name == null || preferredUsername == null || email == null)) {
379 
380  if (accessToken != null) {
381  SimpleHttp.Response response = SimpleHttp.doGet(userInfoUrl, session)
382  .header("Authorization", "Bearer " + accessToken).asResponse();
383  if (response.getStatus() != 200) {
384  String msg = "failed to invoke user info url";
385  try {
386  String tmp = response.asString();
387  if (tmp != null) msg = tmp;
388 
389  } catch (IOException e) {
390 
391  }
392  throw new IdentityBrokerException("Failed to invoke on user info url: " + msg);
393  }
394  JsonNode userInfo = response.asJson();
395 
396  id = getJsonProperty(userInfo, "sub");
397  name = getJsonProperty(userInfo, "name");
398  preferredUsername = getUsernameFromUserInfo(userInfo);
399  email = getJsonProperty(userInfo, "email");
400  AbstractJsonUserAttributeMapper.storeUserProfileForMapper(identity, userInfo, getConfig().getAlias());
401  }
402  }
403  }
404  identity.getContextData().put(VALIDATED_ID_TOKEN, idToken);
405 
406  identity.setId(id);
407  identity.setName(name);
408  identity.setEmail(email);
409 
410  identity.setBrokerUserId(getConfig().getAlias() + "." + id);
411 
412  if (preferredUsername == null) {
413  preferredUsername = email;
414  }
415 
416  if (preferredUsername == null) {
417  preferredUsername = id;
418  }
419 
420  identity.setUsername(preferredUsername);
421  if (tokenResponse != null && tokenResponse.getSessionState() != null) {
422  identity.setBrokerSessionId(getConfig().getAlias() + "." + tokenResponse.getSessionState());
423  }
424  if (tokenResponse != null) identity.getContextData().put(FEDERATED_ACCESS_TOKEN_RESPONSE, tokenResponse);
425  if (tokenResponse != null) processAccessTokenResponse(identity, tokenResponse);
426  return identity;
427  }
static final String VALIDATED_ID_TOKEN
Definition: OIDCIdentityProvider.java:77
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
void processAccessTokenResponse(BrokeredIdentityContext context, AccessTokenResponse response)
Definition: OIDCIdentityProvider.java:213
static final String FEDERATED_ACCESS_TOKEN_RESPONSE
Definition: OIDCIdentityProvider.java:76
String getusernameClaimNameForIdToken()
Definition: OIDCIdentityProvider.java:429
String getJsonProperty(JsonNode jsonNode, String name)
Definition: AbstractOAuth2IdentityProvider.java:358
String getUserInfoUrl()
Definition: OIDCIdentityProvider.java:433
String getUsernameFromUserInfo(JsonNode userInfo)
Definition: OIDCIdentityProvider.java:587

◆ extractIdentityFromProfile()

BrokeredIdentityContext org.keycloak.broker.oidc.OIDCIdentityProvider.extractIdentityFromProfile ( EventBuilder  event,
JsonNode  userInfo 
)
inlineprotected
555  {
556  String id = getJsonProperty(userInfo, "sub");
557  if (id == null) {
558  event.detail(Details.REASON, "sub claim is null from user info json");
559  event.error(Errors.INVALID_TOKEN);
560  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token", Response.Status.BAD_REQUEST);
561  }
562  BrokeredIdentityContext identity = new BrokeredIdentityContext(id);
563 
564  String name = getJsonProperty(userInfo, "name");
565  String preferredUsername = getUsernameFromUserInfo(userInfo);
566  String email = getJsonProperty(userInfo, "email");
567  AbstractJsonUserAttributeMapper.storeUserProfileForMapper(identity, userInfo, getConfig().getAlias());
568 
569  identity.setId(id);
570  identity.setName(name);
571  identity.setEmail(email);
572 
573  identity.setBrokerUserId(getConfig().getAlias() + "." + id);
574 
575  if (preferredUsername == null) {
576  preferredUsername = email;
577  }
578 
579  if (preferredUsername == null) {
580  preferredUsername = id;
581  }
582 
583  identity.setUsername(preferredUsername);
584  return identity;
585  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
String getJsonProperty(JsonNode jsonNode, String name)
Definition: AbstractOAuth2IdentityProvider.java:358
String getUsernameFromUserInfo(JsonNode userInfo)
Definition: OIDCIdentityProvider.java:587

◆ 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 ( )
inlineprotected
516  {
517  return "openid";
518  }

◆ getFederatedIdentity()

BrokeredIdentityContext org.keycloak.broker.oidc.OIDCIdentityProvider.getFederatedIdentity ( String  response)
inline
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

◆ getIDTokenForLogout()

String org.keycloak.broker.oidc.OIDCIdentityProvider.getIDTokenForLogout ( KeycloakSession  session,
UserSessionModel  userSession 
)
inlineprivate
194  {
195  String tokenExpirationString = userSession.getNote(FEDERATED_TOKEN_EXPIRATION);
196  long exp = tokenExpirationString == null ? 0 : Long.parseLong(tokenExpirationString);
197  int currentTime = Time.currentTime();
198  if (exp > 0 && currentTime > exp) {
199  String response = refreshTokenForLogout(session, userSession);
200  AccessTokenResponse tokenResponse = null;
201  try {
202  tokenResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
203  } catch (IOException e) {
204  throw new RuntimeException(e);
205  }
206  return tokenResponse.getIdToken();
207  } else {
208  return userSession.getNote(FEDERATED_ID_TOKEN);
209 
210  }
211  }
String refreshTokenForLogout(KeycloakSession session, UserSessionModel userSession)
Definition: OIDCIdentityProvider.java:181
static final String FEDERATED_ID_TOKEN
Definition: OIDCIdentityProvider.java:74
static final String FEDERATED_TOKEN_EXPIRATION
Definition: AbstractOAuth2IdentityProvider.java:81

◆ 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.broker.oidc.OIDCIdentityProvider.getProfileEndpointForValidation ( EventBuilder  event)
inlineprotected
543  {
544  String userInfoUrl = getUserInfoUrl();
545  if (getConfig().isDisableUserInfoService() || userInfoUrl == null || userInfoUrl.isEmpty()) {
546  event.detail(Details.REASON, "user info service disabled");
547  event.error(Errors.INVALID_TOKEN);
548  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "invalid token", Response.Status.BAD_REQUEST);
549 
550  }
551  return userInfoUrl;
552  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
String getUserInfoUrl()
Definition: OIDCIdentityProvider.java:433

◆ getUserInfoUrl()

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

◆ getusernameClaimNameForIdToken()

String org.keycloak.broker.oidc.OIDCIdentityProvider.getusernameClaimNameForIdToken ( )
inlineprotected
429  {
430  return IDToken.PREFERRED_USERNAME;
431  }

◆ getUsernameFromUserInfo()

String org.keycloak.broker.oidc.OIDCIdentityProvider.getUsernameFromUserInfo ( JsonNode  userInfo)
inlineprotected
587  {
588  return getJsonProperty(userInfo, "preferred_username");
589  }
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.broker.oidc.OIDCIdentityProvider.isIssuer ( String  issuer,
MultivaluedMap< String, String >  params 
)
inline
521  {
522  if (!supportsExternalExchange()) return false;
523  String requestedIssuer = params.getFirst(OAuth2Constants.SUBJECT_ISSUER);
524  if (requestedIssuer == null) requestedIssuer = issuer;
525  if (requestedIssuer.equals(getConfig().getAlias())) return true;
526 
527  String[] issuers = getConfig().getIssuer().split(",");
528 
529  for (String trustedIssuer : issuers) {
530  if (requestedIssuer.equals(trustedIssuer.trim())) {
531  return true;
532  }
533  }
534  return false;
535 
536  }
C getConfig()
Definition: AbstractOAuth2IdentityProvider.java:126
boolean supportsExternalExchange()
Definition: OIDCIdentityProvider.java:538

◆ keycloakInitiatedBrowserLogout()

Response org.keycloak.broker.oidc.OIDCIdentityProvider.keycloakInitiatedBrowserLogout ( KeycloakSession  session,
UserSessionModel  userSession,
UriInfo  uriInfo,
RealmModel  realm 
)
inline
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 
)
inlineprotected
213  {
214 
215 
216  }

◆ refreshTokenForLogout()

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

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.broker.oidc.OIDCIdentityProvider.supportsExternalExchange ( )
inlineprotected
538  {
539  return true;
540  }

◆ 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 
)
inlineprotected
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)
inlineprotected
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 
)
inlineprotected
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)
inlineprotected
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

◆ verifyAccessToken()

String org.keycloak.broker.oidc.OIDCIdentityProvider.verifyAccessToken ( AccessTokenResponse  tokenResponse)
inlineprivate
438  {
439  String accessToken = tokenResponse.getToken();
440 
441  if (accessToken == null) {
442  throw new IdentityBrokerException("No access_token from server.");
443  }
444  return accessToken;
445  }

メンバ詳解

◆ 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"
static

◆ EXCHANGE_PROVIDER

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

◆ FEDERATED_ACCESS_TOKEN_RESPONSE

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

◆ FEDERATED_ID_TOKEN

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

◆ 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)
staticprotected

◆ 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"
static

◆ USER_INFO

final String org.keycloak.broker.oidc.OIDCIdentityProvider.USER_INFO = "UserInfo"
static

◆ VALIDATED_ID_TOKEN

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

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