mitreid-connect
クラス | 公開メンバ関数 | 静的公開変数類 | 限定公開メンバ関数 | 静的限定公開メンバ関数 | 限定公開変数類 | 静的限定公開変数類 | 静的非公開メンバ関数 | 非公開変数類 | 全メンバ一覧
org.mitre.openid.connect.client.OIDCAuthenticationFilter クラス
org.mitre.openid.connect.client.OIDCAuthenticationFilter の継承関係図
Inheritance graph
org.mitre.openid.connect.client.OIDCAuthenticationFilter 連携図
Collaboration graph

クラス

class  TargetLinkURIAuthenticationSuccessHandler
 

公開メンバ関数

 OIDCAuthenticationFilter ()
 
void afterPropertiesSet ()
 
Authentication attemptAuthentication (HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException
 
void setAuthenticationSuccessHandler (AuthenticationSuccessHandler successHandler)
 
int getTimeSkewAllowance ()
 
void setTimeSkewAllowance (int timeSkewAllowance)
 
JWKSetCacheService getValidationServices ()
 
void setValidationServices (JWKSetCacheService validationServices)
 
ServerConfigurationService getServerConfigurationService ()
 
void setServerConfigurationService (ServerConfigurationService servers)
 
ClientConfigurationService getClientConfigurationService ()
 
void setClientConfigurationService (ClientConfigurationService clients)
 
IssuerService getIssuerService ()
 
void setIssuerService (IssuerService issuerService)
 
AuthRequestUrlBuilder getAuthRequestUrlBuilder ()
 
void setAuthRequestUrlBuilder (AuthRequestUrlBuilder authRequestBuilder)
 
AuthRequestOptionsService getAuthRequestOptionsService ()
 
void setAuthRequestOptionsService (AuthRequestOptionsService authOptions)
 
SymmetricKeyJWTValidatorCacheService getSymmetricCacheService ()
 
void setSymmetricCacheService (SymmetricKeyJWTValidatorCacheService symmetricCacheService)
 
TargetLinkURIAuthenticationSuccessHandler getTargetLinkURIAuthenticationSuccessHandler ()
 
void setTargetLinkURIAuthenticationSuccessHandler (TargetLinkURIAuthenticationSuccessHandler targetSuccessHandler)
 
TargetLinkURIChecker targetLinkURIChecker ()
 
void setTargetLinkURIChecker (TargetLinkURIChecker deepLinkFilter)
 

静的公開変数類

static final String FILTER_PROCESSES_URL = "/openid_connect_login"
 

限定公開メンバ関数

void handleAuthorizationRequest (HttpServletRequest request, HttpServletResponse response) throws IOException
 
Authentication handleAuthorizationCodeResponse (HttpServletRequest request, HttpServletResponse response)
 
void handleError (HttpServletRequest request, HttpServletResponse response) throws IOException
 

静的限定公開メンバ関数

static String createNonce (HttpSession session)
 
static String getStoredNonce (HttpSession session)
 
static String createState (HttpSession session)
 
static String getStoredState (HttpSession session)
 
static String createCodeVerifier (HttpSession session)
 
static String getStoredCodeVerifier (HttpSession session)
 

限定公開変数類

int httpSocketTimeout = HTTP_SOCKET_TIMEOUT
 

静的限定公開変数類

static final String REDIRECT_URI_SESION_VARIABLE = "redirect_uri"
 
static final String CODE_VERIFIER_SESSION_VARIABLE = "code_verifier"
 
static final String STATE_SESSION_VARIABLE = "state"
 
static final String NONCE_SESSION_VARIABLE = "nonce"
 
static final String ISSUER_SESSION_VARIABLE = "issuer"
 
static final String TARGET_SESSION_VARIABLE = "target"
 
static final int HTTP_SOCKET_TIMEOUT = 30000
 

静的非公開メンバ関数

static String getStoredSessionString (HttpSession session, String key)
 

非公開変数類

int timeSkewAllowance = 300
 
JWKSetCacheService validationServices
 
SymmetricKeyJWTValidatorCacheService symmetricCacheService
 
JWTSigningAndValidationService authenticationSignerService
 
HttpClient httpClient
 
IssuerService issuerService
 
ServerConfigurationService servers
 
ClientConfigurationService clients
 
AuthRequestOptionsService authOptions = new StaticAuthRequestOptionsService()
 
AuthRequestUrlBuilder authRequestBuilder
 
TargetLinkURIAuthenticationSuccessHandler targetSuccessHandler = new TargetLinkURIAuthenticationSuccessHandler()
 
TargetLinkURIChecker deepLinkFilter
 

詳解

OpenID Connect Authentication Filter class

著者
nemonik, jricher

構築子と解体子

◆ OIDCAuthenticationFilter()

org.mitre.openid.connect.client.OIDCAuthenticationFilter.OIDCAuthenticationFilter ( )
inline

OpenIdConnectAuthenticationFilter constructor

149  {
150  super(FILTER_PROCESSES_URL);
151  targetSuccessHandler.passthrough = super.getSuccessHandler();
152  super.setAuthenticationSuccessHandler(targetSuccessHandler);
153  }
static final String FILTER_PROCESSES_URL
Definition: OIDCAuthenticationFilter.java:106
TargetLinkURIAuthenticationSuccessHandler targetSuccessHandler
Definition: OIDCAuthenticationFilter.java:141
AuthenticationSuccessHandler passthrough
Definition: OIDCAuthenticationFilter.java:750

関数詳解

◆ afterPropertiesSet()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.afterPropertiesSet ( )
inline
156  {
157  super.afterPropertiesSet();
158 
159  // if our JOSE validators don't get wired in, drop defaults into place
160 
161  if (validationServices == null) {
162  validationServices = new JWKSetCacheService();
163  }
164 
165  if (symmetricCacheService == null) {
166  symmetricCacheService = new SymmetricKeyJWTValidatorCacheService();
167  }
168 
169  }
JWKSetCacheService validationServices
Definition: OIDCAuthenticationFilter.java:113
SymmetricKeyJWTValidatorCacheService symmetricCacheService
Definition: OIDCAuthenticationFilter.java:117

◆ attemptAuthentication()

Authentication org.mitre.openid.connect.client.OIDCAuthenticationFilter.attemptAuthentication ( HttpServletRequest  request,
HttpServletResponse  response 
) throws AuthenticationException, IOException, ServletException
inline
182  {
183 
184  if (!Strings.isNullOrEmpty(request.getParameter("error"))) {
185 
186  // there's an error coming back from the server, need to handle this
187  handleError(request, response);
188  return null; // no auth, response is sent to display page or something
189 
190  } else if (!Strings.isNullOrEmpty(request.getParameter("code"))) {
191 
192  // we got back the code, need to process this to get our tokens
193  Authentication auth = handleAuthorizationCodeResponse(request, response);
194  return auth;
195 
196  } else {
197 
198  // not an error, not a code, must be an initial login of some type
199  handleAuthorizationRequest(request, response);
200 
201  return null; // no auth, response redirected to the server's Auth Endpoint (or possibly to the account chooser)
202  }
203 
204  }
void handleAuthorizationRequest(HttpServletRequest request, HttpServletResponse response)
Definition: OIDCAuthenticationFilter.java:216
void handleError(HttpServletRequest request, HttpServletResponse response)
Definition: OIDCAuthenticationFilter.java:647
Authentication handleAuthorizationCodeResponse(HttpServletRequest request, HttpServletResponse response)
Definition: OIDCAuthenticationFilter.java:310

◆ createCodeVerifier()

static String org.mitre.openid.connect.client.OIDCAuthenticationFilter.createCodeVerifier ( HttpSession  session)
inlinestaticprotected

Create a random code challenge and store it in the session

引数
session
戻り値
718  {
719  String challenge = new BigInteger(50, new SecureRandom()).toString(16);
720  session.setAttribute(CODE_VERIFIER_SESSION_VARIABLE, challenge);
721  return challenge;
722  }
static final String CODE_VERIFIER_SESSION_VARIABLE
Definition: OIDCAuthenticationFilter.java:99

◆ createNonce()

static String org.mitre.openid.connect.client.OIDCAuthenticationFilter.createNonce ( HttpSession  session)
inlinestaticprotected

Create a cryptographically random nonce and store it in the session

引数
session
戻り値
676  {
677  String nonce = new BigInteger(50, new SecureRandom()).toString(16);
678  session.setAttribute(NONCE_SESSION_VARIABLE, nonce);
679 
680  return nonce;
681  }
static final String NONCE_SESSION_VARIABLE
Definition: OIDCAuthenticationFilter.java:101

◆ createState()

static String org.mitre.openid.connect.client.OIDCAuthenticationFilter.createState ( HttpSession  session)
inlinestaticprotected

Create a cryptographically random state and store it in the session

引数
session
戻り値
697  {
698  String state = new BigInteger(50, new SecureRandom()).toString(16);
699  session.setAttribute(STATE_SESSION_VARIABLE, state);
700 
701  return state;
702  }
static final String STATE_SESSION_VARIABLE
Definition: OIDCAuthenticationFilter.java:100

◆ getAuthRequestOptionsService()

AuthRequestOptionsService org.mitre.openid.connect.client.OIDCAuthenticationFilter.getAuthRequestOptionsService ( )
inline
戻り値
the authOptions
866  {
867  return authOptions;
868  }
AuthRequestOptionsService authOptions
Definition: OIDCAuthenticationFilter.java:136

◆ getAuthRequestUrlBuilder()

AuthRequestUrlBuilder org.mitre.openid.connect.client.OIDCAuthenticationFilter.getAuthRequestUrlBuilder ( )
inline
戻り値
the authRequestBuilder
852  {
853  return authRequestBuilder;
854  }
AuthRequestUrlBuilder authRequestBuilder
Definition: OIDCAuthenticationFilter.java:138

◆ getClientConfigurationService()

ClientConfigurationService org.mitre.openid.connect.client.OIDCAuthenticationFilter.getClientConfigurationService ( )
inline
戻り値
the clients
824  {
825  return clients;
826  }
ClientConfigurationService clients
Definition: OIDCAuthenticationFilter.java:134

◆ getIssuerService()

IssuerService org.mitre.openid.connect.client.OIDCAuthenticationFilter.getIssuerService ( )
inline
戻り値
the issuerService
838  {
839  return issuerService;
840  }
IssuerService issuerService
Definition: OIDCAuthenticationFilter.java:130

◆ getServerConfigurationService()

ServerConfigurationService org.mitre.openid.connect.client.OIDCAuthenticationFilter.getServerConfigurationService ( )
inline
戻り値
the servers
810  {
811  return servers;
812  }
ServerConfigurationService servers
Definition: OIDCAuthenticationFilter.java:132

◆ getStoredCodeVerifier()

static String org.mitre.openid.connect.client.OIDCAuthenticationFilter.getStoredCodeVerifier ( HttpSession  session)
inlinestaticprotected

Retrieve the stored challenge from our session

引数
session
戻り値
729  {
731  }
static final String CODE_VERIFIER_SESSION_VARIABLE
Definition: OIDCAuthenticationFilter.java:99
static String getStoredSessionString(HttpSession session, String key)
Definition: OIDCAuthenticationFilter.java:662

◆ getStoredNonce()

static String org.mitre.openid.connect.client.OIDCAuthenticationFilter.getStoredNonce ( HttpSession  session)
inlinestaticprotected

Get the nonce we stored in the session

引数
session
戻り値
688  {
690  }
static final String NONCE_SESSION_VARIABLE
Definition: OIDCAuthenticationFilter.java:101
static String getStoredSessionString(HttpSession session, String key)
Definition: OIDCAuthenticationFilter.java:662

◆ getStoredSessionString()

static String org.mitre.openid.connect.client.OIDCAuthenticationFilter.getStoredSessionString ( HttpSession  session,
String  key 
)
inlinestaticprivate

Get the named stored session variable as a string. Return null if not found or not a string.

引数
session
key
戻り値
662  {
663  Object o = session.getAttribute(key);
664  if (o != null && o instanceof String) {
665  return o.toString();
666  } else {
667  return null;
668  }
669  }

◆ getStoredState()

static String org.mitre.openid.connect.client.OIDCAuthenticationFilter.getStoredState ( HttpSession  session)
inlinestaticprotected

Get the state we stored in the session

引数
session
戻り値
709  {
711  }
static final String STATE_SESSION_VARIABLE
Definition: OIDCAuthenticationFilter.java:100
static String getStoredSessionString(HttpSession session, String key)
Definition: OIDCAuthenticationFilter.java:662

◆ getSymmetricCacheService()

SymmetricKeyJWTValidatorCacheService org.mitre.openid.connect.client.OIDCAuthenticationFilter.getSymmetricCacheService ( )
inline
877  {
878  return symmetricCacheService;
879  }
SymmetricKeyJWTValidatorCacheService symmetricCacheService
Definition: OIDCAuthenticationFilter.java:117

◆ getTargetLinkURIAuthenticationSuccessHandler()

TargetLinkURIAuthenticationSuccessHandler org.mitre.openid.connect.client.OIDCAuthenticationFilter.getTargetLinkURIAuthenticationSuccessHandler ( )
inline
885  {
886  return targetSuccessHandler;
887  }
TargetLinkURIAuthenticationSuccessHandler targetSuccessHandler
Definition: OIDCAuthenticationFilter.java:141

◆ getTimeSkewAllowance()

int org.mitre.openid.connect.client.OIDCAuthenticationFilter.getTimeSkewAllowance ( )
inline
785  {
786  return timeSkewAllowance;
787  }
int timeSkewAllowance
Definition: OIDCAuthenticationFilter.java:109

◆ getValidationServices()

JWKSetCacheService org.mitre.openid.connect.client.OIDCAuthenticationFilter.getValidationServices ( )
inline
戻り値
the validationServices
796  {
797  return validationServices;
798  }
JWKSetCacheService validationServices
Definition: OIDCAuthenticationFilter.java:113

◆ handleAuthorizationCodeResponse()

Authentication org.mitre.openid.connect.client.OIDCAuthenticationFilter.handleAuthorizationCodeResponse ( HttpServletRequest  request,
HttpServletResponse  response 
)
inlineprotected
引数
requestThe request from which to extract parameters and perform the authentication
戻り値
The authenticated user token, or null if authentication is incomplete.
310  {
311 
312  String authorizationCode = request.getParameter("code");
313 
314  HttpSession session = request.getSession();
315 
316  // check for state, if it doesn't match we bail early
317  String storedState = getStoredState(session);
318  String requestState = request.getParameter("state");
319  if (storedState == null || !storedState.equals(requestState)) {
320  throw new AuthenticationServiceException("State parameter mismatch on return. Expected " + storedState + " got " + requestState);
321  }
322 
323  // look up the issuer that we set out to talk to
324  String issuer = getStoredSessionString(session, ISSUER_SESSION_VARIABLE);
325 
326  // pull the configurations based on that issuer
327  ServerConfiguration serverConfig = servers.getServerConfiguration(issuer);
328  final RegisteredClient clientConfig = clients.getClientConfiguration(serverConfig);
329 
330  MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
331  form.add("grant_type", "authorization_code");
332  form.add("code", authorizationCode);
333  form.setAll(authOptions.getTokenOptions(serverConfig, clientConfig, request));
334 
335  String codeVerifier = getStoredCodeVerifier(session);
336  if (codeVerifier != null) {
337  form.add("code_verifier", codeVerifier);
338  }
339 
340  String redirectUri = getStoredSessionString(session, REDIRECT_URI_SESION_VARIABLE);
341  if (redirectUri != null) {
342  form.add("redirect_uri", redirectUri);
343  }
344 
345  // Handle Token Endpoint interaction
346 
347  if(httpClient == null) {
348  httpClient = HttpClientBuilder.create()
349  .useSystemProperties()
350  .setDefaultRequestConfig(RequestConfig.custom()
351  .setSocketTimeout(httpSocketTimeout)
352  .build())
353  .build();
354  }
355 
356  HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
357 
358  RestTemplate restTemplate;
359 
360  if (SECRET_BASIC.equals(clientConfig.getTokenEndpointAuthMethod())){
361  // use BASIC auth if configured to do so
362  restTemplate = new RestTemplate(factory) {
363 
364  @Override
365  protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
366  ClientHttpRequest httpRequest = super.createRequest(url, method);
367  httpRequest.getHeaders().add("Authorization",
368  String.format("Basic %s", Base64.encode(String.format("%s:%s",
369  UriUtils.encodePathSegment(clientConfig.getClientId(), "UTF-8"),
370  UriUtils.encodePathSegment(clientConfig.getClientSecret(), "UTF-8")))));
371 
372  return httpRequest;
373  }
374  };
375  } else {
376  // we're not doing basic auth, figure out what other flavor we have
377  restTemplate = new RestTemplate(factory);
378 
379  if (SECRET_JWT.equals(clientConfig.getTokenEndpointAuthMethod()) || PRIVATE_KEY.equals(clientConfig.getTokenEndpointAuthMethod())) {
380  // do a symmetric secret signed JWT for auth
381 
382 
383  JWTSigningAndValidationService signer = null;
384  JWSAlgorithm alg = clientConfig.getTokenEndpointAuthSigningAlg();
385 
386  if (SECRET_JWT.equals(clientConfig.getTokenEndpointAuthMethod()) &&
387  (JWSAlgorithm.HS256.equals(alg)
388  || JWSAlgorithm.HS384.equals(alg)
389  || JWSAlgorithm.HS512.equals(alg))) {
390 
391  // generate one based on client secret
392  signer = symmetricCacheService.getSymmetricValidtor(clientConfig.getClient());
393 
394  } else if (PRIVATE_KEY.equals(clientConfig.getTokenEndpointAuthMethod())) {
395 
396  // needs to be wired in to the bean
398 
399  if (alg == null) {
401  }
402  }
403 
404  if (signer == null) {
405  throw new AuthenticationServiceException("Couldn't find required signer service for use with private key auth.");
406  }
407 
408  JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder();
409 
410  claimsSet.issuer(clientConfig.getClientId());
411  claimsSet.subject(clientConfig.getClientId());
412  claimsSet.audience(Lists.newArrayList(serverConfig.getTokenEndpointUri()));
413  claimsSet.jwtID(UUID.randomUUID().toString());
414 
415  // TODO: make this configurable
416  Date exp = new Date(System.currentTimeMillis() + (60 * 1000)); // auth good for 60 seconds
417  claimsSet.expirationTime(exp);
418 
419  Date now = new Date(System.currentTimeMillis());
420  claimsSet.issueTime(now);
421  claimsSet.notBeforeTime(now);
422 
423  JWSHeader header = new JWSHeader(alg, null, null, null, null, null, null, null, null, null,
424  signer.getDefaultSignerKeyId(),
425  null, null);
426  SignedJWT jwt = new SignedJWT(header, claimsSet.build());
427 
428  signer.signJwt(jwt, alg);
429 
430  form.add("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
431  form.add("client_assertion", jwt.serialize());
432  } else {
433  //Alternatively use form based auth
434  form.add("client_id", clientConfig.getClientId());
435  form.add("client_secret", clientConfig.getClientSecret());
436  }
437 
438  }
439 
440  logger.debug("tokenEndpointURI = " + serverConfig.getTokenEndpointUri());
441  logger.debug("form = " + form);
442 
443  String jsonString = null;
444 
445  try {
446  jsonString = restTemplate.postForObject(serverConfig.getTokenEndpointUri(), form, String.class);
447  } catch (RestClientException e) {
448 
449  // Handle error
450 
451  logger.error("Token Endpoint error response: " + e.getMessage());
452 
453  throw new AuthenticationServiceException("Unable to obtain Access Token: " + e.getMessage());
454  }
455 
456  logger.debug("from TokenEndpoint jsonString = " + jsonString);
457 
458  JsonElement jsonRoot = new JsonParser().parse(jsonString);
459  if (!jsonRoot.isJsonObject()) {
460  throw new AuthenticationServiceException("Token Endpoint did not return a JSON object: " + jsonRoot);
461  }
462 
463  JsonObject tokenResponse = jsonRoot.getAsJsonObject();
464 
465  if (tokenResponse.get("error") != null) {
466 
467  // Handle error
468 
469  String error = tokenResponse.get("error").getAsString();
470 
471  logger.error("Token Endpoint returned: " + error);
472 
473  throw new AuthenticationServiceException("Unable to obtain Access Token. Token Endpoint returned: " + error);
474 
475  } else {
476 
477  // Extract the id_token to insert into the
478  // OIDCAuthenticationToken
479 
480  // get out all the token strings
481  String accessTokenValue = null;
482  String idTokenValue = null;
483  String refreshTokenValue = null;
484 
485  if (tokenResponse.has("access_token")) {
486  accessTokenValue = tokenResponse.get("access_token").getAsString();
487  } else {
488  throw new AuthenticationServiceException("Token Endpoint did not return an access_token: " + jsonString);
489  }
490 
491  if (tokenResponse.has("id_token")) {
492  idTokenValue = tokenResponse.get("id_token").getAsString();
493  } else {
494  logger.error("Token Endpoint did not return an id_token");
495  throw new AuthenticationServiceException("Token Endpoint did not return an id_token");
496  }
497 
498  if (tokenResponse.has("refresh_token")) {
499  refreshTokenValue = tokenResponse.get("refresh_token").getAsString();
500  }
501 
502  try {
503  JWT idToken = JWTParser.parse(idTokenValue);
504 
505  // validate our ID Token over a number of tests
506  JWTClaimsSet idClaims = idToken.getJWTClaimsSet();
507 
508  // check the signature
509  JWTSigningAndValidationService jwtValidator = null;
510 
511  Algorithm tokenAlg = idToken.getHeader().getAlgorithm();
512 
513  Algorithm clientAlg = clientConfig.getIdTokenSignedResponseAlg();
514 
515  if (clientAlg != null) {
516  if (!clientAlg.equals(tokenAlg)) {
517  throw new AuthenticationServiceException("Token algorithm " + tokenAlg + " does not match expected algorithm " + clientAlg);
518  }
519  }
520 
521  if (idToken instanceof PlainJWT) {
522 
523  if (clientAlg == null) {
524  throw new AuthenticationServiceException("Unsigned ID tokens can only be used if explicitly configured in client.");
525  }
526 
527  if (tokenAlg != null && !tokenAlg.equals(Algorithm.NONE)) {
528  throw new AuthenticationServiceException("Unsigned token received, expected signature with " + tokenAlg);
529  }
530  } else if (idToken instanceof SignedJWT) {
531 
532  SignedJWT signedIdToken = (SignedJWT)idToken;
533 
534  if (tokenAlg.equals(JWSAlgorithm.HS256)
535  || tokenAlg.equals(JWSAlgorithm.HS384)
536  || tokenAlg.equals(JWSAlgorithm.HS512)) {
537 
538  // generate one based on client secret
539  jwtValidator = symmetricCacheService.getSymmetricValidtor(clientConfig.getClient());
540  } else {
541  // otherwise load from the server's public key
542  jwtValidator = validationServices.getValidator(serverConfig.getJwksUri());
543  }
544 
545  if (jwtValidator != null) {
546  if(!jwtValidator.validateSignature(signedIdToken)) {
547  throw new AuthenticationServiceException("Signature validation failed");
548  }
549  } else {
550  logger.error("No validation service found. Skipping signature validation");
551  throw new AuthenticationServiceException("Unable to find an appropriate signature validator for ID Token.");
552  }
553  } // TODO: encrypted id tokens
554 
555  // check the issuer
556  if (idClaims.getIssuer() == null) {
557  throw new AuthenticationServiceException("Id Token Issuer is null");
558  } else if (!idClaims.getIssuer().equals(serverConfig.getIssuer())){
559  throw new AuthenticationServiceException("Issuers do not match, expected " + serverConfig.getIssuer() + " got " + idClaims.getIssuer());
560  }
561 
562  // check expiration
563  if (idClaims.getExpirationTime() == null) {
564  throw new AuthenticationServiceException("Id Token does not have required expiration claim");
565  } else {
566  // it's not null, see if it's expired
567  Date now = new Date(System.currentTimeMillis() - (timeSkewAllowance * 1000));
568  if (now.after(idClaims.getExpirationTime())) {
569  throw new AuthenticationServiceException("Id Token is expired: " + idClaims.getExpirationTime());
570  }
571  }
572 
573  // check not before
574  if (idClaims.getNotBeforeTime() != null) {
575  Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000));
576  if (now.before(idClaims.getNotBeforeTime())){
577  throw new AuthenticationServiceException("Id Token not valid untill: " + idClaims.getNotBeforeTime());
578  }
579  }
580 
581  // check issued at
582  if (idClaims.getIssueTime() == null) {
583  throw new AuthenticationServiceException("Id Token does not have required issued-at claim");
584  } else {
585  // since it's not null, see if it was issued in the future
586  Date now = new Date(System.currentTimeMillis() + (timeSkewAllowance * 1000));
587  if (now.before(idClaims.getIssueTime())) {
588  throw new AuthenticationServiceException("Id Token was issued in the future: " + idClaims.getIssueTime());
589  }
590  }
591 
592  // check audience
593  if (idClaims.getAudience() == null) {
594  throw new AuthenticationServiceException("Id token audience is null");
595  } else if (!idClaims.getAudience().contains(clientConfig.getClientId())) {
596  throw new AuthenticationServiceException("Audience does not match, expected " + clientConfig.getClientId() + " got " + idClaims.getAudience());
597  }
598 
599  // compare the nonce to our stored claim
600  String nonce = idClaims.getStringClaim("nonce");
601  if (Strings.isNullOrEmpty(nonce)) {
602 
603  logger.error("ID token did not contain a nonce claim.");
604 
605  throw new AuthenticationServiceException("ID token did not contain a nonce claim.");
606  }
607 
608  String storedNonce = getStoredNonce(session);
609  if (!nonce.equals(storedNonce)) {
610  logger.error("Possible replay attack detected! The comparison of the nonce in the returned "
611  + "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + ".");
612 
613  throw new AuthenticationServiceException(
614  "Possible replay attack detected! The comparison of the nonce in the returned "
615  + "ID Token to the session " + NONCE_SESSION_VARIABLE + " failed. Expected " + storedNonce + " got " + nonce + ".");
616  }
617 
618  // construct an PendingOIDCAuthenticationToken and return a Authentication object w/the userId and the idToken
619 
620  PendingOIDCAuthenticationToken token = new PendingOIDCAuthenticationToken(idClaims.getSubject(), idClaims.getIssuer(),
621  serverConfig,
622  idToken, accessTokenValue, refreshTokenValue);
623 
624  Authentication authentication = this.getAuthenticationManager().authenticate(token);
625 
626  return authentication;
627  } catch (ParseException e) {
628  throw new AuthenticationServiceException("Couldn't parse idToken: ", e);
629  }
630 
631 
632 
633  }
634  }
JWKSetCacheService validationServices
Definition: OIDCAuthenticationFilter.java:113
Map< String, String > getTokenOptions(ServerConfiguration server, RegisteredClient client, HttpServletRequest request)
static String getStoredState(HttpSession session)
Definition: OIDCAuthenticationFilter.java:709
int timeSkewAllowance
Definition: OIDCAuthenticationFilter.java:109
JWTSigningAndValidationService authenticationSignerService
Definition: OIDCAuthenticationFilter.java:121
static final String REDIRECT_URI_SESION_VARIABLE
Definition: OIDCAuthenticationFilter.java:98
ClientConfigurationService clients
Definition: OIDCAuthenticationFilter.java:134
JWTSigningAndValidationService getSymmetricValidtor(ClientDetailsEntity client)
Definition: SymmetricKeyJWTValidatorCacheService.java:72
static final String ISSUER_SESSION_VARIABLE
Definition: OIDCAuthenticationFilter.java:102
ServerConfigurationService servers
Definition: OIDCAuthenticationFilter.java:132
HttpClient httpClient
Definition: OIDCAuthenticationFilter.java:124
RegisteredClient getClientConfiguration(ServerConfiguration issuer)
JWTSigningAndValidationService getValidator(String jwksUri)
Definition: JWKSetCacheService.java:85
static final String NONCE_SESSION_VARIABLE
Definition: OIDCAuthenticationFilter.java:101
static String getStoredSessionString(HttpSession session, String key)
Definition: OIDCAuthenticationFilter.java:662
static String getStoredCodeVerifier(HttpSession session)
Definition: OIDCAuthenticationFilter.java:729
static String getStoredNonce(HttpSession session)
Definition: OIDCAuthenticationFilter.java:688
SymmetricKeyJWTValidatorCacheService symmetricCacheService
Definition: OIDCAuthenticationFilter.java:117
AuthRequestOptionsService authOptions
Definition: OIDCAuthenticationFilter.java:136
int httpSocketTimeout
Definition: OIDCAuthenticationFilter.java:144

◆ handleAuthorizationRequest()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.handleAuthorizationRequest ( HttpServletRequest  request,
HttpServletResponse  response 
) throws IOException
inlineprotected

Initiate an Authorization request

引数
requestThe request from which to extract parameters and perform the authentication
response
例外
IOExceptionIf an input or output exception occurs
216  {
217 
218  HttpSession session = request.getSession();
219 
220  IssuerServiceResponse issResp = issuerService.getIssuer(request);
221 
222  if (issResp == null) {
223  logger.error("Null issuer response returned from service.");
224  throw new AuthenticationServiceException("No issuer found.");
225  }
226 
227  if (issResp.shouldRedirect()) {
228  response.sendRedirect(issResp.getRedirectUrl());
229  } else {
230  String issuer = issResp.getIssuer();
231 
232  if (!Strings.isNullOrEmpty(issResp.getTargetLinkUri())) {
233  // there's a target URL in the response, we should save this so we can forward to it later
234  session.setAttribute(TARGET_SESSION_VARIABLE, issResp.getTargetLinkUri());
235  }
236 
237  if (Strings.isNullOrEmpty(issuer)) {
238  logger.error("No issuer found: " + issuer);
239  throw new AuthenticationServiceException("No issuer found: " + issuer);
240  }
241 
242  ServerConfiguration serverConfig = servers.getServerConfiguration(issuer);
243  if (serverConfig == null) {
244  logger.error("No server configuration found for issuer: " + issuer);
245  throw new AuthenticationServiceException("No server configuration found for issuer: " + issuer);
246  }
247 
248 
249  session.setAttribute(ISSUER_SESSION_VARIABLE, serverConfig.getIssuer());
250 
251  RegisteredClient clientConfig = clients.getClientConfiguration(serverConfig);
252  if (clientConfig == null) {
253  logger.error("No client configuration found for issuer: " + issuer);
254  throw new AuthenticationServiceException("No client configuration found for issuer: " + issuer);
255  }
256 
257  String redirectUri = null;
258  if (clientConfig.getRegisteredRedirectUri() != null && clientConfig.getRegisteredRedirectUri().size() == 1) {
259  // if there's a redirect uri configured (and only one), use that
260  redirectUri = Iterables.getOnlyElement(clientConfig.getRegisteredRedirectUri());
261  } else {
262  // otherwise our redirect URI is this current URL, with no query parameters
263  redirectUri = request.getRequestURL().toString();
264  }
265  session.setAttribute(REDIRECT_URI_SESION_VARIABLE, redirectUri);
266 
267  // this value comes back in the id token and is checked there
268  String nonce = createNonce(session);
269 
270  // this value comes back in the auth code response
271  String state = createState(session);
272 
273  Map<String, String> options = authOptions.getOptions(serverConfig, clientConfig, request);
274 
275  // if we're using PKCE, handle the challenge here
276  if (clientConfig.getCodeChallengeMethod() != null) {
277  String codeVerifier = createCodeVerifier(session);
278  options.put("code_challenge_method", clientConfig.getCodeChallengeMethod().getName());
279  if (clientConfig.getCodeChallengeMethod().equals(PKCEAlgorithm.plain)) {
280  options.put("code_challenge", codeVerifier);
281  } else if (clientConfig.getCodeChallengeMethod().equals(PKCEAlgorithm.S256)) {
282  try {
283  MessageDigest digest = MessageDigest.getInstance("SHA-256");
284  String hash = Base64URL.encode(digest.digest(codeVerifier.getBytes(StandardCharsets.US_ASCII))).toString();
285  options.put("code_challenge", hash);
286  } catch (NoSuchAlgorithmException e) {
287  // TODO Auto-generated catch block
288  e.printStackTrace();
289  }
290 
291 
292  }
293  }
294 
295  String authRequest = authRequestBuilder.buildAuthRequestUrl(serverConfig, clientConfig, redirectUri, nonce, state, options, issResp.getLoginHint());
296 
297  logger.debug("Auth Request: " + authRequest);
298 
299  response.sendRedirect(authRequest);
300  }
301  }
AuthRequestUrlBuilder authRequestBuilder
Definition: OIDCAuthenticationFilter.java:138
IssuerService issuerService
Definition: OIDCAuthenticationFilter.java:130
static final String REDIRECT_URI_SESION_VARIABLE
Definition: OIDCAuthenticationFilter.java:98
ClientConfigurationService clients
Definition: OIDCAuthenticationFilter.java:134
static final String TARGET_SESSION_VARIABLE
Definition: OIDCAuthenticationFilter.java:103
String buildAuthRequestUrl(ServerConfiguration serverConfig, RegisteredClient clientConfig, String redirectUri, String nonce, String state, Map< String, String > options, String loginHint)
static final String ISSUER_SESSION_VARIABLE
Definition: OIDCAuthenticationFilter.java:102
Map< String, String > getOptions(ServerConfiguration server, RegisteredClient client, HttpServletRequest request)
ServerConfigurationService servers
Definition: OIDCAuthenticationFilter.java:132
static String createNonce(HttpSession session)
Definition: OIDCAuthenticationFilter.java:676
IssuerServiceResponse getIssuer(HttpServletRequest request)
RegisteredClient getClientConfiguration(ServerConfiguration issuer)
static String createState(HttpSession session)
Definition: OIDCAuthenticationFilter.java:697
static String createCodeVerifier(HttpSession session)
Definition: OIDCAuthenticationFilter.java:718
AuthRequestOptionsService authOptions
Definition: OIDCAuthenticationFilter.java:136

◆ handleError()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.handleError ( HttpServletRequest  request,
HttpServletResponse  response 
) throws IOException
inlineprotected

Handle Authorization Endpoint error

引数
requestThe request from which to extract parameters and handle the error
responseThe response, needed to do a redirect to display the error
例外
IOExceptionIf an input or output exception occurs
647  {
648 
649  String error = request.getParameter("error");
650  String errorDescription = request.getParameter("error_description");
651  String errorURI = request.getParameter("error_uri");
652 
653  throw new AuthorizationEndpointException(error, errorDescription, errorURI);
654  }

◆ setAuthenticationSuccessHandler()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setAuthenticationSuccessHandler ( AuthenticationSuccessHandler  successHandler)
inline
735  {
736  targetSuccessHandler.passthrough = successHandler;
737  super.setAuthenticationSuccessHandler(targetSuccessHandler);
738  }
TargetLinkURIAuthenticationSuccessHandler targetSuccessHandler
Definition: OIDCAuthenticationFilter.java:141
AuthenticationSuccessHandler passthrough
Definition: OIDCAuthenticationFilter.java:750

◆ setAuthRequestOptionsService()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setAuthRequestOptionsService ( AuthRequestOptionsService  authOptions)
inline
引数
authOptionsthe authOptions to set
873  {
874  this.authOptions = authOptions;
875  }
AuthRequestOptionsService authOptions
Definition: OIDCAuthenticationFilter.java:136

◆ setAuthRequestUrlBuilder()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setAuthRequestUrlBuilder ( AuthRequestUrlBuilder  authRequestBuilder)
inline
引数
authRequestBuilderthe authRequestBuilder to set
859  {
861  }
AuthRequestUrlBuilder authRequestBuilder
Definition: OIDCAuthenticationFilter.java:138

◆ setClientConfigurationService()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setClientConfigurationService ( ClientConfigurationService  clients)
inline
引数
clientsthe clients to set
831  {
832  this.clients = clients;
833  }
ClientConfigurationService clients
Definition: OIDCAuthenticationFilter.java:134

◆ setIssuerService()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setIssuerService ( IssuerService  issuerService)
inline
引数
issuerServicethe issuerService to set
845  {
847  }
IssuerService issuerService
Definition: OIDCAuthenticationFilter.java:130

◆ setServerConfigurationService()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setServerConfigurationService ( ServerConfigurationService  servers)
inline
引数
serversthe servers to set
817  {
818  this.servers = servers;
819  }
ServerConfigurationService servers
Definition: OIDCAuthenticationFilter.java:132

◆ setSymmetricCacheService()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setSymmetricCacheService ( SymmetricKeyJWTValidatorCacheService  symmetricCacheService)
inline
881  {
883  }
SymmetricKeyJWTValidatorCacheService symmetricCacheService
Definition: OIDCAuthenticationFilter.java:117

◆ setTargetLinkURIAuthenticationSuccessHandler()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setTargetLinkURIAuthenticationSuccessHandler ( TargetLinkURIAuthenticationSuccessHandler  targetSuccessHandler)
inline
890  {
892  }
TargetLinkURIAuthenticationSuccessHandler targetSuccessHandler
Definition: OIDCAuthenticationFilter.java:141

◆ setTargetLinkURIChecker()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setTargetLinkURIChecker ( TargetLinkURIChecker  deepLinkFilter)
inline
898  {
900  }
TargetLinkURIChecker deepLinkFilter
Definition: OIDCAuthenticationFilter.java:142

◆ setTimeSkewAllowance()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setTimeSkewAllowance ( int  timeSkewAllowance)
inline
789  {
791  }
int timeSkewAllowance
Definition: OIDCAuthenticationFilter.java:109

◆ setValidationServices()

void org.mitre.openid.connect.client.OIDCAuthenticationFilter.setValidationServices ( JWKSetCacheService  validationServices)
inline
引数
validationServicesthe validationServices to set
803  {
805  }
JWKSetCacheService validationServices
Definition: OIDCAuthenticationFilter.java:113

◆ targetLinkURIChecker()

TargetLinkURIChecker org.mitre.openid.connect.client.OIDCAuthenticationFilter.targetLinkURIChecker ( )
inline
894  {
895  return deepLinkFilter;
896  }
TargetLinkURIChecker deepLinkFilter
Definition: OIDCAuthenticationFilter.java:142

メンバ詳解

◆ authenticationSignerService

JWTSigningAndValidationService org.mitre.openid.connect.client.OIDCAuthenticationFilter.authenticationSignerService
private

◆ authOptions

AuthRequestOptionsService org.mitre.openid.connect.client.OIDCAuthenticationFilter.authOptions = new StaticAuthRequestOptionsService()
private

◆ authRequestBuilder

AuthRequestUrlBuilder org.mitre.openid.connect.client.OIDCAuthenticationFilter.authRequestBuilder
private

◆ clients

ClientConfigurationService org.mitre.openid.connect.client.OIDCAuthenticationFilter.clients
private

◆ CODE_VERIFIER_SESSION_VARIABLE

final String org.mitre.openid.connect.client.OIDCAuthenticationFilter.CODE_VERIFIER_SESSION_VARIABLE = "code_verifier"
staticprotected

◆ deepLinkFilter

TargetLinkURIChecker org.mitre.openid.connect.client.OIDCAuthenticationFilter.deepLinkFilter
private

◆ FILTER_PROCESSES_URL

final String org.mitre.openid.connect.client.OIDCAuthenticationFilter.FILTER_PROCESSES_URL = "/openid_connect_login"
static

◆ HTTP_SOCKET_TIMEOUT

final int org.mitre.openid.connect.client.OIDCAuthenticationFilter.HTTP_SOCKET_TIMEOUT = 30000
staticprotected

◆ httpClient

HttpClient org.mitre.openid.connect.client.OIDCAuthenticationFilter.httpClient
private

◆ httpSocketTimeout

int org.mitre.openid.connect.client.OIDCAuthenticationFilter.httpSocketTimeout = HTTP_SOCKET_TIMEOUT
protected

◆ ISSUER_SESSION_VARIABLE

final String org.mitre.openid.connect.client.OIDCAuthenticationFilter.ISSUER_SESSION_VARIABLE = "issuer"
staticprotected

◆ issuerService

IssuerService org.mitre.openid.connect.client.OIDCAuthenticationFilter.issuerService
private

◆ NONCE_SESSION_VARIABLE

final String org.mitre.openid.connect.client.OIDCAuthenticationFilter.NONCE_SESSION_VARIABLE = "nonce"
staticprotected

◆ REDIRECT_URI_SESION_VARIABLE

final String org.mitre.openid.connect.client.OIDCAuthenticationFilter.REDIRECT_URI_SESION_VARIABLE = "redirect_uri"
staticprotected

◆ servers

ServerConfigurationService org.mitre.openid.connect.client.OIDCAuthenticationFilter.servers
private

◆ STATE_SESSION_VARIABLE

final String org.mitre.openid.connect.client.OIDCAuthenticationFilter.STATE_SESSION_VARIABLE = "state"
staticprotected

◆ symmetricCacheService

SymmetricKeyJWTValidatorCacheService org.mitre.openid.connect.client.OIDCAuthenticationFilter.symmetricCacheService
private

◆ TARGET_SESSION_VARIABLE

final String org.mitre.openid.connect.client.OIDCAuthenticationFilter.TARGET_SESSION_VARIABLE = "target"
staticprotected

◆ targetSuccessHandler

TargetLinkURIAuthenticationSuccessHandler org.mitre.openid.connect.client.OIDCAuthenticationFilter.targetSuccessHandler = new TargetLinkURIAuthenticationSuccessHandler()
private

◆ timeSkewAllowance

int org.mitre.openid.connect.client.OIDCAuthenticationFilter.timeSkewAllowance = 300
private

◆ validationServices

JWKSetCacheService org.mitre.openid.connect.client.OIDCAuthenticationFilter.validationServices
private

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