org.apereo.cas.web.flow.resolver.impl.mfa.RequestParameterMultifactorAuthenticationPolicyEventResolver   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 69
c 0
b 0
f 0
rs 10
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
F resolveInternal(RequestContext) 0 43 10
A resolveSingle(RequestContext) 0 6 1
A RequestParameterMultifactorAuthenticationPolicyEventResolver(AuthenticationSystemSupport,CentralA 0 11 1
1
package org.apereo.cas.web.flow.resolver.impl.mfa;
2
3
import org.apache.commons.lang3.StringUtils;
4
import org.apereo.cas.CentralAuthenticationService;
5
import org.apereo.cas.authentication.Authentication;
6
import org.apereo.cas.authentication.AuthenticationException;
7
import org.apereo.cas.authentication.AuthenticationServiceSelectionPlan;
8
import org.apereo.cas.authentication.AuthenticationSystemSupport;
9
import org.apereo.cas.authentication.MultifactorAuthenticationUtils;
10
import org.apereo.cas.configuration.CasConfigurationProperties;
11
import org.apereo.cas.services.MultifactorAuthenticationProvider;
12
import org.apereo.cas.services.MultifactorAuthenticationProviderSelector;
13
import org.apereo.cas.services.RegisteredService;
14
import org.apereo.cas.services.ServicesManager;
15
import org.apereo.cas.ticket.registry.TicketRegistrySupport;
16
import org.apereo.cas.util.CollectionUtils;
17
import org.apereo.cas.web.flow.authentication.BaseMultifactorAuthenticationProviderEventResolver;
18
import org.apereo.cas.web.support.WebUtils;
19
import org.apereo.inspektr.audit.annotation.Audit;
20
import org.slf4j.Logger;
21
import org.slf4j.LoggerFactory;
22
import org.springframework.web.util.CookieGenerator;
23
import org.springframework.webflow.execution.Event;
24
import org.springframework.webflow.execution.RequestContext;
25
26
import javax.servlet.http.HttpServletRequest;
27
import java.util.Map;
28
import java.util.Optional;
29
import java.util.Set;
30
31
/**
32
 * This is {@link RequestParameterMultifactorAuthenticationPolicyEventResolver}
33
 * that attempts to resolve the next event based on the authentication providers of this service.
34
 *
35
 * @author Misagh Moayyed
36
 * @since 5.0.0
37
 */
38
public class RequestParameterMultifactorAuthenticationPolicyEventResolver extends BaseMultifactorAuthenticationProviderEventResolver {
39
    private static final Logger LOGGER = LoggerFactory.getLogger(RequestParameterMultifactorAuthenticationPolicyEventResolver.class);
40
41
    private final String mfaRequestParameter;
42
43
    public RequestParameterMultifactorAuthenticationPolicyEventResolver(final AuthenticationSystemSupport authenticationSystemSupport,
44
                                                                        final CentralAuthenticationService centralAuthenticationService,
45
                                                                        final ServicesManager servicesManager,
46
                                                                        final TicketRegistrySupport ticketRegistrySupport,
47
                                                                        final CookieGenerator warnCookieGenerator,
48
                                                                        final AuthenticationServiceSelectionPlan authenticationStrategies,
49
                                                                        final MultifactorAuthenticationProviderSelector selector,
50
                                                                        final CasConfigurationProperties casProperties) {
51
        super(authenticationSystemSupport, centralAuthenticationService, servicesManager,
52
                ticketRegistrySupport, warnCookieGenerator, authenticationStrategies, selector);
53
        mfaRequestParameter = casProperties.getAuthn().getMfa().getRequestParameter();
54
    }
55
56
    @Override
57
    public Set<Event> resolveInternal(final RequestContext context) {
58
        final RegisteredService service = resolveRegisteredServiceInRequestContext(context);
59
        final Authentication authentication = WebUtils.getAuthentication(context);
60
61
        if (service == null || authentication == null) {
62
            LOGGER.debug("No service or authentication is available to determine event for principal");
63
            return null;
64
        }
65
        if (StringUtils.isBlank(mfaRequestParameter)) {
66
            LOGGER.debug("No request parameter is defined to trigger multifactor authentication.");
67
            return null;
68
        }
69
        
70
        final HttpServletRequest request = WebUtils.getHttpServletRequestFromExternalWebflowContext(context);
71
        final String[] values = request.getParameterValues(mfaRequestParameter);
72
        if (values != null && values.length > 0) {
73
            LOGGER.debug("Received request parameter [{}] as [{}]", mfaRequestParameter, values);
74
75
            final Map<String, MultifactorAuthenticationProvider> providerMap =
76
                    MultifactorAuthenticationUtils.getAvailableMultifactorAuthenticationProviders(this.applicationContext);
77
            if (providerMap == null || providerMap.isEmpty()) {
78
                LOGGER.error("No multifactor authentication providers are available in the application context to satisfy [{}]", (Object[]) values);
79
                throw new AuthenticationException();
80
            }
81
82
            final Optional<MultifactorAuthenticationProvider> providerFound = resolveProvider(providerMap, values[0]);
83
            if (providerFound.isPresent()) {
84
                final MultifactorAuthenticationProvider provider = providerFound.get();
85
                if (provider.isAvailable(service)) {
86
                    LOGGER.debug("Attempting to build an event based on the authentication provider [{}] and service [{}]", provider, service.getName());
87
                    final Event event = validateEventIdForMatchingTransitionInContext(provider.getId(), context,
88
                            buildEventAttributeMap(authentication.getPrincipal(), service, provider));
89
                    return CollectionUtils.wrapSet(event);
90
                }
91
                LOGGER.warn("Located multifactor provider [{}], yet the provider cannot be reached or verified", providerFound.get());
92
                return null;
93
            }
94
            LOGGER.warn("No multifactor provider could be found for request parameter [{}]", (Object[]) values);
95
            throw new AuthenticationException();
96
        }
97
        LOGGER.debug("No value could be found for request parameter [{}]", mfaRequestParameter);
98
        return null;
99
    }
100
101
    @Audit(action = "AUTHENTICATION_EVENT",
102
            actionResolverName = "AUTHENTICATION_EVENT_ACTION_RESOLVER",
103
            resourceResolverName = "AUTHENTICATION_EVENT_RESOURCE_RESOLVER")
104
    @Override
105
    public Event resolveSingle(final RequestContext context) {
106
        return super.resolveSingle(context);
107
    }
108
}
109