keycloak-service
公開メンバ関数 | 非公開メンバ関数 | 非公開変数類 | 全メンバ一覧
org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint クラス
org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint 連携図
Collaboration graph

公開メンバ関数

 UserInfoEndpoint (org.keycloak.protocol.oidc.TokenManager tokenManager, RealmModel realm)
 
Response issueUserInfoPreflight ()
 
Response issueUserInfoGet (@Context final HttpHeaders headers)
 
Response issueUserInfoPost ()
 

非公開メンバ関数

Response issueUserInfo (String tokenString)
 
UserSessionModel findValidSession (AccessToken token, EventBuilder event, ClientModel client)
 

非公開変数類

HttpRequest request
 
HttpResponse response
 
KeycloakSession session
 
ClientConnection clientConnection
 
final org.keycloak.protocol.oidc.TokenManager tokenManager
 
final AppAuthManager appAuthManager
 
final RealmModel realm
 

詳解

著者
pedroigor

構築子と解体子

◆ UserInfoEndpoint()

org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.UserInfoEndpoint ( org.keycloak.protocol.oidc.TokenManager  tokenManager,
RealmModel  realm 
)
inline
86  {
87  this.realm = realm;
89  this.appAuthManager = new AppAuthManager();
90  }
final org.keycloak.protocol.oidc.TokenManager tokenManager
Definition: UserInfoEndpoint.java:82
final RealmModel realm
Definition: UserInfoEndpoint.java:84
final AppAuthManager appAuthManager
Definition: UserInfoEndpoint.java:83

関数詳解

◆ findValidSession()

UserSessionModel org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.findValidSession ( AccessToken  token,
EventBuilder  event,
ClientModel  client 
)
inlineprivate
226  {
227  UserSessionModel userSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, token.getSessionState(), false, client.getId());
228  UserSessionModel offlineUserSession = null;
229  if (AuthenticationManager.isSessionValid(realm, userSession)) {
230  event.session(userSession);
231  return userSession;
232  } else {
233  offlineUserSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, token.getSessionState(), true, client.getId());
234  if (AuthenticationManager.isOfflineSessionValid(realm, offlineUserSession)) {
235  event.session(offlineUserSession);
236  return offlineUserSession;
237  }
238  }
239 
240  if (userSession == null && offlineUserSession == null) {
241  event.error(Errors.USER_SESSION_NOT_FOUND);
242  throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "User session not found or doesn't have client attached on it", Response.Status.UNAUTHORIZED);
243  }
244 
245  if (userSession != null) {
246  event.session(userSession);
247  } else {
248  event.session(offlineUserSession);
249  }
250 
251  event.error(Errors.SESSION_EXPIRED);
252  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "Session expired", Response.Status.UNAUTHORIZED);
253  }
final RealmModel realm
Definition: UserInfoEndpoint.java:84
KeycloakSession session
Definition: UserInfoEndpoint.java:77

◆ issueUserInfo()

Response org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.issueUserInfo ( String  tokenString)
inlineprivate
122  {
123  EventBuilder event = new EventBuilder(realm, session, clientConnection)
124  .event(EventType.USER_INFO_REQUEST)
125  .detail(Details.AUTH_METHOD, Details.VALIDATE_ACCESS_TOKEN);
126 
127  if (tokenString == null) {
128  event.error(Errors.INVALID_TOKEN);
129  throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Token not provided", Response.Status.BAD_REQUEST);
130  }
131 
132  AccessToken token;
133  try {
134  TokenVerifier<AccessToken> verifier = TokenVerifier.create(tokenString, AccessToken.class)
135  .realmUrl(Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName()));
136 
137  SignatureVerifierContext verifierContext = session.getProvider(SignatureProvider.class, verifier.getHeader().getAlgorithm().name()).verifier(verifier.getHeader().getKeyId());
138  verifier.verifierContext(verifierContext);
139 
140  token = verifier.verify().getToken();
141  } catch (VerificationException e) {
142  event.error(Errors.INVALID_TOKEN);
143  throw new ErrorResponseException(OAuthErrorException.INVALID_TOKEN, "Token invalid: " + e.getMessage(), Response.Status.UNAUTHORIZED);
144  }
145 
146  ClientModel clientModel = realm.getClientByClientId(token.getIssuedFor());
147  if (clientModel == null) {
148  event.error(Errors.CLIENT_NOT_FOUND);
149  throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Client not found", Response.Status.BAD_REQUEST);
150  }
151 
152  session.getContext().setClient(clientModel);
153 
154  event.client(clientModel);
155 
156  if (!clientModel.isEnabled()) {
157  event.error(Errors.CLIENT_DISABLED);
158  throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Client disabled", Response.Status.BAD_REQUEST);
159  }
160 
161  UserSessionModel userSession = findValidSession(token, event, clientModel);
162 
163  UserModel userModel = userSession.getUser();
164  if (userModel == null) {
165  event.error(Errors.USER_NOT_FOUND);
166  throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "User not found", Response.Status.BAD_REQUEST);
167  }
168 
169  event.user(userModel)
170  .detail(Details.USERNAME, userModel.getUsername());
171 
172  // KEYCLOAK-6771 Certificate Bound Token
173  // https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-3
174  if (OIDCAdvancedConfigWrapper.fromClientModel(clientModel).isUseMtlsHokToken()) {
175  if (!MtlsHoKTokenUtil.verifyTokenBindingWithClientCertificate(token, request, session)) {
176  event.error(Errors.NOT_ALLOWED);
177  throw new ErrorResponseException(OAuthErrorException.UNAUTHORIZED_CLIENT, "Client certificate missing, or its thumbprint and one in the refresh token did NOT match", Response.Status.UNAUTHORIZED);
178  }
179  }
180 
181  // Existence of authenticatedClientSession for our client already handled before
182  AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(clientModel.getId());
183 
184  // Retrieve by latest scope parameter
185  ClientSessionContext clientSessionCtx = DefaultClientSessionContext.fromClientSessionScopeParameter(clientSession);
186 
187  AccessToken userInfo = new AccessToken();
188  tokenManager.transformUserInfoAccessToken(session, userInfo, userSession, clientSessionCtx);
189 
190  Map<String, Object> claims = new HashMap<String, Object>();
191  claims.put("sub", userModel.getId());
192  claims.putAll(userInfo.getOtherClaims());
193 
194  Response.ResponseBuilder responseBuilder;
195  OIDCAdvancedConfigWrapper cfg = OIDCAdvancedConfigWrapper.fromClientModel(clientModel);
196 
197  if (cfg.isUserInfoSignatureRequired()) {
198  String issuerUrl = Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName());
199  String audience = clientModel.getClientId();
200  claims.put("iss", issuerUrl);
201  claims.put("aud", audience);
202 
203  String signatureAlgorithm = session.tokens().signatureAlgorithm(TokenCategory.USERINFO);
204 
205  SignatureProvider signatureProvider = session.getProvider(SignatureProvider.class, signatureAlgorithm);
206  SignatureSignerContext signer = signatureProvider.signer();
207 
208  String signedUserInfo = new JWSBuilder().type("JWT").jsonContent(claims).sign(signer);
209 
210  responseBuilder = Response.ok(signedUserInfo).header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JWT);
211 
212  event.detail(Details.SIGNATURE_REQUIRED, "true");
213  event.detail(Details.SIGNATURE_ALGORITHM, cfg.getUserInfoSignedResponseAlg().toString());
214  } else {
215  responseBuilder = Response.ok(claims).header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
216 
217  event.detail(Details.SIGNATURE_REQUIRED, "false");
218  }
219 
220  event.success();
221 
222  return Cors.add(request, responseBuilder).auth().allowedOrigins(token).build();
223  }
final org.keycloak.protocol.oidc.TokenManager tokenManager
Definition: UserInfoEndpoint.java:82
final RealmModel realm
Definition: UserInfoEndpoint.java:84
KeycloakSession session
Definition: UserInfoEndpoint.java:77
ClientConnection clientConnection
Definition: UserInfoEndpoint.java:80
UserSessionModel findValidSession(AccessToken token, EventBuilder event, ClientModel client)
Definition: UserInfoEndpoint.java:226
HttpRequest request
Definition: UserInfoEndpoint.java:71
AccessToken transformUserInfoAccessToken(KeycloakSession session, AccessToken token, UserSessionModel userSession, ClientSessionContext clientSessionCtx)
Definition: TokenManager.java:613

◆ issueUserInfoGet()

Response org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.issueUserInfoGet ( @Context final HttpHeaders  headers)
inline
101  {
102  String accessToken = this.appAuthManager.extractAuthorizationHeaderToken(headers);
103  return issueUserInfo(accessToken);
104  }
final AppAuthManager appAuthManager
Definition: UserInfoEndpoint.java:83
String extractAuthorizationHeaderToken(HttpHeaders headers)
Definition: AppAuthManager.java:44
Response issueUserInfo(String tokenString)
Definition: UserInfoEndpoint.java:122

◆ issueUserInfoPost()

Response org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.issueUserInfoPost ( )
inline
109  {
110  // Try header first
111  HttpHeaders headers = request.getHttpHeaders();
112  String accessToken = this.appAuthManager.extractAuthorizationHeaderToken(headers);
113 
114  // Fallback to form parameter
115  if (accessToken == null) {
116  accessToken = request.getDecodedFormParameters().getFirst("access_token");
117  }
118 
119  return issueUserInfo(accessToken);
120  }
final AppAuthManager appAuthManager
Definition: UserInfoEndpoint.java:83
String extractAuthorizationHeaderToken(HttpHeaders headers)
Definition: AppAuthManager.java:44
Response issueUserInfo(String tokenString)
Definition: UserInfoEndpoint.java:122
HttpRequest request
Definition: UserInfoEndpoint.java:71

◆ issueUserInfoPreflight()

Response org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.issueUserInfoPreflight ( )
inline
94  {
95  return Cors.add(this.request, Response.ok()).auth().preflight().build();
96  }
HttpRequest request
Definition: UserInfoEndpoint.java:71

メンバ詳解

◆ appAuthManager

final AppAuthManager org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.appAuthManager
private

◆ clientConnection

ClientConnection org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.clientConnection
private

◆ realm

final RealmModel org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.realm
private

◆ request

HttpRequest org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.request
private

◆ response

HttpResponse org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.response
private

◆ session

KeycloakSession org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.session
private

◆ tokenManager

final org.keycloak.protocol.oidc.TokenManager org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint.tokenManager
private

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