/** {@inheritDoc} */ @Override protected void doExecute(@Nonnull final ProfileRequestContext profileRequestContext, @Nonnull final AuthenticationContext authenticationContext) { final List<Principal> principals = authenticationProfileConfig.getDefaultAuthenticationMethods(); if (authenticationProfileConfig.getDefaultAuthenticationMethods().isEmpty()) { log.debug("{} Profile configuration did not supply any default authentication methods", getLogPrefix()); return; } final RequestedPrincipalContext principalCtx = new RequestedPrincipalContext(); principalCtx.setOperator("exact"); principalCtx.setRequestedPrincipals(principals); principalCtx.setPrincipalEvalPredicateFactoryRegistry( authenticationContext.getPrincipalEvalPredicateFactoryRegistry()); authenticationContext.addSubcontext(principalCtx, true); log.debug("{} Established RequestedPrincipalContext with {} methods", getLogPrefix(), principalCtx.getRequestedPrincipals().size()); }
@Nonnull @NotEmpty final String configName, @Nullable final Subject subject) { if (subject != null && requestedPrincipalCtx != null && requestedPrincipalCtx.getOperator() != null) { log.debug("{} Request contains principal requirements, evaluating JAAS config '{}' for compatibility", getLogPrefix(), configName); for (final Principal p : requestedPrincipalCtx.getRequestedPrincipals()) { final PrincipalEvalPredicateFactory factory = requestedPrincipalCtx.getPrincipalEvalPredicateFactoryRegistry().lookup( p.getClass(), requestedPrincipalCtx.getOperator()); if (factory != null) { final PrincipalEvalPredicate predicate = factory.getPredicate(p); if (predicate.apply(wrapper)) { log.debug("{} JAAS config '{}' compatible with principal type '{}' and operator '{}'", getLogPrefix(), configName, p.getClass(), requestedPrincipalCtx.getOperator()); requestedPrincipalCtx.setMatchingPrincipal(predicate.getMatchingPrincipal()); return true; } else { log.debug("{} JAAS config '{}' not compatible with principal type '{}' and operator '{}'", getLogPrefix(), configName, p.getClass(), requestedPrincipalCtx.getOperator()); getLogPrefix(), p.getClass(), requestedPrincipalCtx.getOperator());
/** * Helper method that evaluates a {@link PrincipalSupportingComponent} against * this context to determine if the input is compatible with it. * * @param component component to evaluate * * @return true iff the input is compatible with the requested authentication requirements * * @since 3.3.0 */ public boolean isAcceptable(@Nonnull final PrincipalSupportingComponent component) { for (final Principal requestedPrincipal : requestedPrincipals) { final PrincipalEvalPredicate predicate = getPredicate(requestedPrincipal); if (predicate != null) { if (predicate.apply(component)) { return true; } } } // Nothing matched the candidate. return false; }
/** * Add requested principal into context. * * @param ac the ac * @param principals the principals */ private void addRequestedPrincipalIntoContext(final AuthenticationContext ac, final List<Principal> principals) { final RequestedPrincipalContext rpc = new RequestedPrincipalContext(); rpc.setOperator("exact"); rpc.setRequestedPrincipals(principals); ac.addSubcontext(rpc, true); }
final RequestedPrincipalContext rpCtx = new RequestedPrincipalContext(); if (requestedCtx.getComparison() != null) { rpCtx.setOperator(requestedCtx.getComparison().toString()); } else { rpCtx.setOperator(AuthnContextComparisonTypeEnumeration.EXACT.toString()); rpCtx.setRequestedPrincipals(principals); getLogPrefix(), rpCtx.getOperator(), principals.size());
for (final Principal p : requestedPrincipalCtx.getRequestedPrincipals()) { log.debug("{} Checking for an inactive flow compatible with operator '{}' and principal '{}'", getLogPrefix(), requestedPrincipalCtx.getOperator(), p.getName()); final PrincipalEvalPredicate predicate = requestedPrincipalCtx.getPredicate(p); if (predicate != null) { for (final AuthenticationFlowDescriptor descriptor : potentialFlows.values()) { + "operator '{}' and type '{}'", getLogPrefix(), requestedPrincipalCtx.getOperator(), p.getClass());
for (final Principal p : requestedPrincipalCtx.getRequestedPrincipals()) { log.debug("{} Checking result for compatibility with operator '{}' and principal '{}'", getLogPrefix(), requestedPrincipalCtx.getOperator(), p.getName()); final PrincipalEvalPredicateFactory factory = requestedPrincipalCtx.getPrincipalEvalPredicateFactoryRegistry().lookup( p.getClass(), requestedPrincipalCtx.getOperator()); if (factory != null) { final PrincipalEvalPredicate predicate = factory.getPredicate(p); + "operator '{}' and type '{}'", getLogPrefix(), requestedPrincipalCtx.getOperator(), p.getClass());
if (requestedPrincipalCtx.getOperator() == null || requestedPrincipalCtx.getRequestedPrincipals().isEmpty()) { requestedPrincipalCtx = null;
final Principal match = requestedPrincipalCtx.getMatchingPrincipal(); if (match != null) { if (!latest.getSupportedPrincipals(match.getClass()).contains(match)) { log.debug("{} Authentication result lacks originally projected matching principal '{}'," + " reevaluating", getLogPrefix(), match.getName()); requestedPrincipalCtx.setMatchingPrincipal(null); requestedPrincipalCtx.setMatchingPrincipal( findMatchingPrincipal(authenticationContext, requestedPrincipalCtx)); if (requestedPrincipalCtx.getMatchingPrincipal() == null) { log.warn("{} Authentication result for flow {} did not satisfy the request", getLogPrefix(), latest.getAuthenticationFlowId());
statement.setAuthenticationInstant(new DateTime(getAuthenticationResult().getAuthenticationInstant())); if (requestedPrincipalContext != null && requestedPrincipalContext.getMatchingPrincipal() != null && requestedPrincipalContext.getMatchingPrincipal() instanceof AuthenticationMethodPrincipal) { statement.setAuthenticationMethod(requestedPrincipalContext.getMatchingPrincipal().getName()); } else { statement.setAuthenticationMethod(methodLookupStrategy.apply(profileRequestContext).getName());
/** * Set the registry of predicate factories for custom principal evaluation to inject into instances of * {@link RequestedPrincipalContext} created via the {@link #addRequestedPrincipalContext(String, List, boolean)} * helper method. * * <p>It also propagates this object into any existing {@link RequestedPrincipalContext} subcontext.</p> * * @param registry predicate factory registry * * @return this context */ @Nonnull public AuthenticationContext setPrincipalEvalPredicateFactoryRegistry( @Nullable final PrincipalEvalPredicateFactoryRegistry registry) { evalRegistry = registry; final RequestedPrincipalContext rpCtx = getSubcontext(RequestedPrincipalContext.class); if (rpCtx != null) { rpCtx.setPrincipalEvalPredicateFactoryRegistry(registry); } return this; }
/** * Get the registry of predicate factories for custom principal evaluation. * * <p>This object is only needed when evaluating a {@link RequestedPrincipalContext}, so the presence of it at * this level of the tree is solely for use by the {@link #addRequestedPrincipalContext(String, List, boolean)} * helper method.</p> * * @return predicate factory registry */ @Nonnull public PrincipalEvalPredicateFactoryRegistry getPrincipalEvalPredicateFactoryRegistry() { final RequestedPrincipalContext rpCtx = getSubcontext(RequestedPrincipalContext.class); if (rpCtx != null) { return rpCtx.getPrincipalEvalPredicateFactoryRegistry(); } else if (evalRegistry != null) { return evalRegistry; } else { return new PrincipalEvalPredicateFactoryRegistry(); } }
for (final Principal p : requestedPrincipalCtx.getRequestedPrincipals()) { log.debug("{} Checking for an active result compatible with operator '{}' and principal '{}'", getLogPrefix(), requestedPrincipalCtx.getOperator(), p.getName()); final PrincipalEvalPredicate predicate = requestedPrincipalCtx.getPredicate(p); if (predicate != null) { for (final AuthenticationResult result : activeResults.values()) { + "operator '{}' and type '{}'", getLogPrefix(), requestedPrincipalCtx.getOperator(), p.getClass()); for (final Principal p : requestedPrincipalCtx.getRequestedPrincipals()) { log.debug("{} Checking for an inactive flow or active result compatible with " + "operator '{}' and principal '{}'", getLogPrefix(), requestedPrincipalCtx.getOperator(), p.getName()); final PrincipalEvalPredicate predicate = requestedPrincipalCtx.getPredicate(p); if (predicate != null) { for (final AuthenticationFlowDescriptor descriptor : potentialFlows.values()) { + "operator '{}' and type '{}'", getLogPrefix(), requestedPrincipalCtx.getOperator(), p.getClass());
requestedPrincipalCtx.getOperator(), requestedPrincipalCtx.getRequestedPrincipals());
if (principalContext != null && principalContext.getMatchingPrincipal() != null) { LOG.debug("Found requested principal context context with matching principal {}", principalContext.getMatchingPrincipal().getName()); principalContext.getMatchingPrincipal().getName());
authenticationContext.getSubcontext(RequestedPrincipalContext.class); if (rpCtx != null) { rpCtx.setPrincipalEvalPredicateFactoryRegistry(evalRegistry);
/** * Add (or replace) a {@link RequestedPrincipalContext} as a child of this context using the * supplied parameters and the previously established {@link PrincipalEvalPredicateFactoryRegistry} * for comparison handling. * * @param operator matching operator * @param principals principals to request * @param replace whether to replace an existing context or simply return false * * @return true iff a new context was created */ public boolean addRequestedPrincipalContext(@Nonnull @NotEmpty final String operator, @Nonnull @NonnullElements final List<Principal> principals, final boolean replace) { RequestedPrincipalContext rpCtx = getSubcontext(RequestedPrincipalContext.class); if (rpCtx != null && !replace) { return false; } rpCtx = new RequestedPrincipalContext(); rpCtx.setOperator(operator) .setPrincipalEvalPredicateFactoryRegistry(evalRegistry) .setRequestedPrincipals(principals); addSubcontext(rpCtx, true); return true; }
if (rpCtx != null && rpCtx.getOperator() != null && !getSubject().getPrincipals().isEmpty()) { log.debug("{} Request contains principal requirements, evaluating for compatibility", getLogPrefix()); for (final Principal p : rpCtx.getRequestedPrincipals()) { final PrincipalEvalPredicateFactory factory = rpCtx.getPrincipalEvalPredicateFactoryRegistry().lookup(p.getClass(), rpCtx.getOperator()); if (factory != null) { final PrincipalEvalPredicate predicate = factory.getPredicate(p); if (predicate.apply(this)) { log.debug("{} Compatible with principal type '{}' and operator '{}'", getLogPrefix(), p.getClass(), rpCtx.getOperator()); rpCtx.setMatchingPrincipal(predicate.getMatchingPrincipal()); return true; } else { log.debug("{} Not compatible with principal type '{}' and operator '{}'", getLogPrefix(), p.getClass(), rpCtx.getOperator()); getLogPrefix(), p.getClass(), rpCtx.getOperator());
for (final Principal p : requestedPrincipalCtx.getRequestedPrincipals()) { final PrincipalEvalPredicate predicate = requestedPrincipalCtx.getPredicate(p); if (predicate != null) { if (predicate.apply(activeResult)) { log.warn("{} Configuration does not support requested principal evaluation with " + "operator '{}' and type '{}'", getLogPrefix(), requestedPrincipalCtx.getOperator(), p.getClass()); return; } else if (requestedPrincipalCtx != null) { for (final Principal p : requestedPrincipalCtx.getRequestedPrincipals()) { final PrincipalEvalPredicate predicate = requestedPrincipalCtx.getPredicate(p); if (predicate != null) { if (predicate.apply(flow) && flow.apply(profileRequestContext)) { + "operator '{}' and type '{}'", getLogPrefix(), requestedPrincipalCtx.getOperator(), p.getClass());
statement.setAuthnContext(authnContext); if (requestedPrincipalContext != null && requestedPrincipalContext.getMatchingPrincipal() != null) { final Principal matchingPrincipal = requestedPrincipalContext.getMatchingPrincipal(); if (matchingPrincipal instanceof AuthnContextClassRefPrincipal) { authnContext.setAuthnContextClassRef(