/** {@inheritDoc} */ @Override @Nonnull @NotEmpty public String getName() { return authnResult.getAuthenticationFlowId(); }
/** {@inheritDoc} */ @Override public boolean equals(final Object obj) { if (obj == null) { return false; } if (this == obj) { return true; } if (obj instanceof AuthenticationResult) { return Objects.equals(getAuthenticationFlowId(), ((AuthenticationResult) obj).getAuthenticationFlowId()) && getAuthenticationInstant() == ((AuthenticationResult) obj).getAuthenticationInstant(); } return false; }
/** * Disassociate an {@link AuthenticationResult} from this IdP session. * * <p>This manipulates only the internal state of the object. The * {@link #removeAuthenticationResult(AuthenticationResult)} method must be implemented to support * other persistence requirements.</p> * * @param result the result to disassociate * * @return true iff the given result had been associated with this IdP session and now is not */ public boolean doRemoveAuthenticationResult(@Nonnull final AuthenticationResult result) { Constraint.isNotNull(result, "Authentication event can not be null"); // Record may be actually present, or not yet loaded. if (authenticationResults.remove(result.getAuthenticationFlowId(), Optional.of(result))) { return true; } else { return authenticationResults.remove(result.getAuthenticationFlowId(), Optional.absent()); } }
/** * Add a new {@link AuthenticationResult} to this IdP session, replacing any * existing result of the same flow ID. * * <p>This manipulates only the internal state of the object. The * {@link #addAuthenticationResult(AuthenticationResult)} method must be implemented to support * other persistence requirements.</p> * * @param result the result to add * * @return a previously existing result replaced by the new one, if any */ @Nullable public AuthenticationResult doAddAuthenticationResult(@Nonnull final AuthenticationResult result) { Constraint.isNotNull(result, "AuthenticationResult cannot be null"); final Optional<AuthenticationResult> prev = authenticationResults.put(result.getAuthenticationFlowId(), Optional.of(result)); if (prev != null && prev.isPresent()) { log.debug("IdPSession {}: replaced old AuthenticationResult for flow ID {}", id, prev.get().getAuthenticationFlowId()); return prev.get(); } return null; }
/** * Set the authentication results currently active for the subject. * * @param results authentication results currently active for the subject * * @return this authentication context */ @Nonnull public AuthenticationContext setActiveResults( @Nonnull @NonnullElements final Iterable<AuthenticationResult> results) { Constraint.isNotNull(results, "AuthenticationResult collection cannot be null"); activeResults.clear(); for (final AuthenticationResult result : results) { activeResults.put(result.getAuthenticationFlowId(), result); } return this; }
/** {@inheritDoc} */ @Override @Nullable public String apply(@Nullable final ProfileRequestContext input) { final AuthenticationContext authnCtx = input.getSubcontext(AuthenticationContext.class); if (authnCtx != null && authnCtx.getAuthenticationResult() != null) { return authnCtx.getAuthenticationResult().getAuthenticationFlowId(); } return null; }
/** * Selects an active result and completes processing. * * @param profileRequestContext the current IdP profile request context * @param authenticationContext the current authentication context * @param result the result to reuse */ private void selectActiveResult(@Nonnull final ProfileRequestContext profileRequestContext, @Nonnull final AuthenticationContext authenticationContext, @Nonnull final AuthenticationResult result) { log.debug("{} Reusing active result {}", getLogPrefix(), result.getAuthenticationFlowId()); result.setLastActivityInstantToNow(); authenticationContext.setAuthenticationResult(result); ActionSupport.buildProceedEvent(profileRequestContext); }
candidate.getAuthenticationFlowId()); if (descriptor != null) { if (descriptor.apply(profileRequestContext)) { < System.currentTimeMillis()) { log.debug("{} Ignoring active result from login flow {} due to maxAge on request", getLogPrefix(), candidate.getAuthenticationFlowId()); } else { results.add(candidate); getLogPrefix(), candidate.getAuthenticationFlowId()); candidate.getAuthenticationFlowId());
/** * Compare the result's custom principal names to the string values of the attribute. * * @param result result to examine * * @return a match between the result's principal names and the attribute's string values, or null */ @Nullable private String getMatch(@Nonnull final AuthenticationResult result) { log.debug("{} Looking for match for active result of flow {} against values for attribute {}", getLogPrefix(), result.getAuthenticationFlowId(), attribute.getId()); for (final Principal p : result.getSupportedPrincipals(Principal.class)) { log.debug("{} Comparing principal {} against attribute values {}", getLogPrefix(), p.getName(), attribute.getValues()); for (final IdPAttributeValue val : attribute.getValues()) { if (val instanceof StringAttributeValue && Objects.equals(val.getValue(), p.getName())) { return p.getName(); } } } return null; }
for (final AuthenticationResult result : session.getAuthenticationResults()) { final AuthenticationFlowDescriptor descriptor = authenticationContext.getPotentialFlows().get(result.getAuthenticationFlowId()); if (descriptor == null) { log.debug("{} Authentication result {} has no corresponding flow descriptor, considering inactive", getLogPrefix(), result.getAuthenticationFlowId()); continue; if (maxAge > 0 && result.getAuthenticationInstant() + maxAge < now) { log.debug("{} Authentication result {} exceeds maxAge setting, skiping it", getLogPrefix(), result.getAuthenticationFlowId()); continue; result.getAuthenticationFlowId()); actives.add(result); } else { log.debug("{} Authentication result {} is inactive, skipping it", getLogPrefix(), result.getAuthenticationFlowId());
/** {@inheritDoc} */ @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext, @Nonnull final AuthenticationContext authenticationContext) { if (canonicalPrincipalName != null) { final SubjectContext sc = profileRequestContext.getSubcontext(SubjectContext.class, true); // Check for an existing value. if (sc.getPrincipalName() != null && !canonicalPrincipalName.equals(sc.getPrincipalName())) { log.warn("{} Result of authentication ({}) does not match existing subject in context ({})", getLogPrefix(), canonicalPrincipalName, sc.getPrincipalName()); ActionSupport.buildEvent(profileRequestContext, IdPEventIds.INVALID_SUBJECT_CTX); return; } sc.setPrincipalName(canonicalPrincipalName); final Map scResults = sc.getAuthenticationResults(); scResults.putAll(authenticationContext.getActiveResults()); final AuthenticationResult latest = authenticationContext.getAuthenticationResult(); if (latest != null && !scResults.containsKey(latest.getAuthenticationFlowId())) { scResults.put(latest.getAuthenticationFlowId(), latest); } } authenticationContext.setCompletionInstant(); }
if (results != null) { for (final AuthenticationResult result : results) { mfaCtx.getActiveResults().put(result.getAuthenticationFlowId(), result);
/** {@inheritDoc} */ @Override public void updateAuthenticationResultActivity(@Nonnull final AuthenticationResult result) throws SessionException { final String flowId = result.getAuthenticationFlowId(); final AuthenticationFlowDescriptor flow = sessionManager.getAuthenticationFlowDescriptor(flowId); if (flow != null) { try { if (!sessionManager.getStorageService().updateExpiration(getId(), result.getAuthenticationFlowId(), result.getLastActivityInstant() + flow.getInactivityTimeout() + AuthenticationFlowDescriptor.STORAGE_EXPIRATION_OFFSET)) { log.warn("Skipping update, AuthenticationResult for flow {} in session {} not found in storage", flowId, getId()); } } catch (final IOException e) { log.error("Exception updating AuthenticationResult expiration for session {} and flow {}", getId(), flowId, e); if (!sessionManager.isMaskStorageFailure()) { throw new SessionException("Exception updating AuthenticationResult expiration in storage", e); } } } else { log.warn("No flow descriptor installed for ID {}, unable to update result in storage", flowId); } }
/** * Update an existing session. * * <p>If the result is the product of an attempted flow, then it's added to the session. * If reused, its last activity time is updated.</p> * * @param authenticationContext current authentication context * @param session session to update * @throws SessionException if an error occurs updating the session */ private void updateIdPSession(@Nonnull final AuthenticationContext authenticationContext, @Nonnull final IdPSession session) throws SessionException { if (authenticationContext.getAttemptedFlow() != null) { if (authenticationContext.isResultCacheable()) { log.debug("{} Adding new AuthenticationResult for flow {} to existing session {}", getLogPrefix(), authenticationContext.getAuthenticationResult().getAuthenticationFlowId(), session.getId()); session.addAuthenticationResult(authenticationContext.getAuthenticationResult()); } } else { log.debug("{} Updating activity time on reused AuthenticationResult for flow {} in existing session {}", getLogPrefix(), authenticationContext.getAuthenticationResult().getAuthenticationFlowId(), session.getId()); session.updateAuthenticationResultActivity(authenticationContext.getAuthenticationResult()); } }
/** * Check if a result generated by this flow is still active. * * @param result {@link AuthenticationResult} to check * * @return true iff the result remains valid */ public boolean isResultActive(@Nonnull final AuthenticationResult result) { Constraint.isNotNull(result, "AuthenticationResult cannot be null"); Constraint.isTrue(result.getAuthenticationFlowId().equals(getId()), "AuthenticationResult was not produced by this flow"); final long now = System.currentTimeMillis(); if (getLifetime() > 0 && result.getAuthenticationInstant() + getLifetime() <= now) { return false; } else if (getInactivityTimeout() > 0 && result.getLastActivityInstant() + getInactivityTimeout() <= now) { return false; } return true; }
authenticationContext.getInitialAuthenticationResult().getAuthenticationFlowId())) { authenticationContext.getInitialAuthenticationResult().getAuthenticationFlowId(), authenticationContext.getInitialAuthenticationResult())); } else if (authenticationContext.isForceAuthn()) {
while (!success && attempts-- > 0) { if (!getAuthenticationResultMap().containsKey(result.getAuthenticationFlowId())) { super.addAuthenticationResult(result); success = writeToStorage(); } catch (final IOException e) { log.error("Exception saving AuthenticationResult record for session {} and flow {}", getId(), result.getAuthenticationFlowId(), e); if (!sessionManager.isMaskStorageFailure()) { throw new SessionException("Exception saving AuthenticationResult record to storage", e);
final AuthenticationResult result = authenticationContext.getAuthenticationResult(); if (null != result) { resolutionContext.setPrincipalAuthenticationMethod(result.getAuthenticationFlowId());
final AuthenticationResult result = authenticationContext.getAuthenticationResult(); if (null != result) { filterContext.setPrincipalAuthenticationMethod(result.getAuthenticationFlowId());
final StringWriter sink = new StringWriter(128); final JsonGenerator gen = generatorFactory.createGenerator(sink); gen.writeStartObject().write(FLOW_ID_FIELD, instance.getAuthenticationFlowId()) .write(AUTHN_INSTANT_FIELD, instance.getAuthenticationInstant()) .writeStartArray(PRINCIPAL_ARRAY_FIELD);