Partially: https://apereo.github.io/cas/5.2.x/installation/DuoSecurity-Authentication.html#user-account-status
Specifically: https://github.com/apereo/cas/blob/5.2.x/support/cas-server-support-duo-core-mfa/src/main/java/org/apereo/cas/adaptors/duo/authn/DefaultDuoMultifactorAuthenticationProvider.java#L94 --Misagh > From: "brian mancuso" <[email protected]> > To: "CAS Community" <[email protected]> > Cc: "Misagh Moayyed" <[email protected]> > Sent: Wednesday, February 7, 2018 11:56:22 AM > Subject: Re: [cas-user] Multiple Duo Instances > Hey Misagh, > Could you point me to something about the built in feature for checking if a > user is already registered for MFA/Duo? > On Tuesday, February 6, 2018 at 2:14:53 PM UTC-5, Misagh Moayyed wrote: >> Brian, if I have understood things correctly I think you're doing this the >> hard >> way: I suspect the sort of thing you're after can be handled with bypass >> options in CAS where you skip MFA if a particular attribute is found on the >> authenticated user (ldap group is blah). If a match is found, bypass will >> kick >> in and if not, CAS should be able to trigger MFA. There is also the built-in >> ability to check with Duo directly to see if the user has in fact registered >> for MFA/Duo and does have an account. >> --Misagh >>> From: "Man H" < [email protected] > >>> To: [email protected] >>> Sent: Tuesday, February 6, 2018 10:56:18 AM >>> Subject: Re: [cas-user] Multiple Duo Instances >>> So in my opinion you have a globaltriggerpolicy mfa-duo and eg a groovy >>> trigger >>> for employees. >>> https://apereo.github.io/cas/5.2.x/installation/Configuring-Multifactor-Authentication-Triggers.html >>> 2018-02-06 12:18 GMT-03:00 brian mancuso < [email protected] > : >>>> I'm open to any solution that simplifies things and meets the needs. When >>>> I'd >>>> read the documentation, it seemed custom triggers were the way to go here. >>>> To give a little more information, I have students and employees that both >>>> need >>>> to login via CAS to several systems. For some of those systems, we need to >>>> require employees that login to use DUO while students will have the >>>> option, >>>> but not be required. Other systems won't require DUO for either group >>>> unless >>>> they're already enrolled. >>>> On Tuesday, February 6, 2018 at 9:59:02 AM UTC-5, Manfredo Hopp wrote: >>>>> Couldn't this be achieved through custom authentication handler? >>>>> El martes, 6 de febrero de 2018, brian mancuso < [email protected] > >>>>> escribió: >>>>>> We would like to allow users in a specific ldap group the ability to >>>>>> optionally >>>>>> bypass Duo for a given service if the user is not signed up for a 2fa >>>>>> account. >>>>>> Essentially there would be these two cases for a user: >>>>>> - 2fa always required >>>>>> - 2fa optionally required (but always required if the user has a Duo >>>>>> account) >>>>>> I have two duo instances defined in the cas.properties file: mfa-duo, >>>>>> mfa-duo-force. The first is in bypass mode while the latter doesn't >>>>>> allow any >>>>>> bypass. >>>>>> Then my other classes are thus: >>>>>> spring.factories >>>>>> org . springframework . boot . autoconfigure . EnableAutoConfiguration = >>>>>> org . >>>>>> apereo . cas . custom . config . >>>>>> SelectiveDuoWebflowEventResolverConfiguration >>>>>> I then put together a custom trigger that will determine if a user is >>>>>> required >>>>>> to use DUO or not: >>>>>> SelectiveDuoWebflowEventResolver.java >>>>>> package org.apereo.cas.custom.mfa; >>>>>> import com.google.common.collect.ImmutableSet; >>>>>> import java.util.Map; >>>>>> import java.util.Optional; >>>>>> import java.util.Set; >>>>>> import org.apereo.cas.CentralAuthenticationService; >>>>>> import org.apereo.cas.authentication.Authentication; >>>>>> import org.apereo.cas.authentication.AuthenticationServiceSelectionPlan; >>>>>> import org.apereo.cas.authentication.AuthenticationSystemSupport; >>>>>> import org.apereo.cas.authentication.principal.Principal; >>>>>> import org.apereo.cas.services.MultifactorAuthenticationProvider; >>>>>> import org.apereo.cas.services.MultifactorAuthenticationProviderSelector; >>>>>> import org.apereo.cas.services.RegisteredService; >>>>>> import org.apereo.cas.services.ServicesManager; >>>>>> import org.apereo.cas.ticket.registry.TicketRegistrySupport; >>>>>> import >>>>>> org.apereo.cas.web.flow.resolver.impl.AbstractCasWebflowEventResolver; >>>>>> import org.apereo.cas.web.support.WebUtils; >>>>>> import org.slf4j.Logger; >>>>>> import org.slf4j.LoggerFactory; >>>>>> import org.springframework.web.util.CookieGenerator; >>>>>> import org.springframework.webflow.execution.Event; >>>>>> import org.springframework.webflow.execution.RequestContext; >>>>>> public class SelectiveDuoWebflowEventResolver extends >>>>>> AbstractCasWebflowEventResolver { >>>>>> private static final Logger LOGGER = >>>>>> LoggerFactory.getLogger(SelectiveDuoWebflowEventResolver.class); >>>>>> public SelectiveDuoWebflowEventResolver(AuthenticationSystemSupport >>>>>> authenticationSystemSupport, CentralAuthenticationService >>>>>> centralAuthenticationService, ServicesManager servicesManager, >>>>>> TicketRegistrySupport ticketRegistrySupport, CookieGenerator >>>>>> warnCookieGenerator, AuthenticationServiceSelectionPlan >>>>>> authenticationSelectionStrategies, >>>>>> MultifactorAuthenticationProviderSelector >>>>>> selector) { >>>>>> super(authenticationSystemSupport, centralAuthenticationService, >>>>>> servicesManager, ticketRegistrySupport, warnCookieGenerator, >>>>>> authenticationSelectionStrategies, selector); >>>>>> } >>>>>> @Override >>>>>> public Set<Event> resolveInternal(RequestContext context) { >>>>>> final RegisteredService service = WebUtils.getRegisteredService(context); >>>>>> final Authentication authentication = >>>>>> WebUtils.getAuthentication(context); >>>>>> Set<String> attributeKeys = authentication.getAttributes().keySet(); >>>>>> for (String s : attributeKeys) { >>>>>> System.out.println("s: " + s + " " + >>>>>> authentication.getAttributes().get(s)); >>>>>> } >>>>>> Principal principal = authentication.getPrincipal(); >>>>>> attributeKeys = principal.getAttributes().keySet(); >>>>>> for (String s : attributeKeys) { >>>>>> System.out.println("p: " + s + " " + principal.getAttributes().get(s)); >>>>>> } >>>>>> if (userRequiresDUO()) { >>>>>> LOGGER.warn("Forcing MFA"); >>>>>> Optional<MultifactorAuthenticationProvider> mfaDuoForced = >>>>>> this.getMultifactorAuthenticationProviderFromApplicationContext("mfa-duo-force"); >>>>>> MultifactorAuthenticationProvider forcedProvider = mfaDuoForced.get(); >>>>>> final Map eventAttributes >>>>>> = buildEventAttributeMap(authentication.getPrincipal(), >>>>>> service, >>>>>> forcedProvider); >>>>>> final Event event >>>>>> = validateEventIdForMatchingTransitionInContext(forcedProvider.getId(), >>>>>> context, eventAttributes); >>>>>> return ImmutableSet.of(event); >>>>>> } else { >>>>>> LOGGER.warn("Not forcing MFA"); >>>>>> Optional<MultifactorAuthenticationProvider> mfaDuo = >>>>>> this.getMultifactorAuthenticationProviderFromApplicationContext("mfa-duo"); >>>>>> MultifactorAuthenticationProvider bypassableProvider = mfaDuo.get(); >>>>>> final Map eventAttributes >>>>>> = buildEventAttributeMap(authentication.getPrincipal(), >>>>>> service, >>>>>> bypassableProvider); >>>>>> final Event event >>>>>> = >>>>>> validateEventIdForMatchingTransitionInContext(bypassableProvider.getId(), >>>>>> context, eventAttributes); >>>>>> return ImmutableSet.of(event); >>>>>> } >>>>>> } >>>>>> } >>>>>> SelectiveDuoWebflowEventResolverConfiguration.java >>>>>> package org.apereo.cas.custom.config; >>>>>> import javax.annotation.PostConstruct; >>>>>> import org.apereo.cas.CentralAuthenticationService; >>>>>> import org.apereo.cas.authentication.AuthenticationServiceSelectionPlan; >>>>>> import org.apereo.cas.authentication.AuthenticationSystemSupport; >>>>>> import org.apereo.cas.configuration.CasConfigurationProperties; >>>>>> import org.apereo.cas.custom.mfa.SelectiveDuoWebflowEventResolver; >>>>>> import org.apereo.cas.services.MultifactorAuthenticationProviderSelector; >>>>>> import org.apereo.cas.services.ServicesManager; >>>>>> import org.apereo.cas.ticket.registry.TicketRegistrySupport; >>>>>> import >>>>>> org.apereo.cas.web.flow.authentication.RankedMultifactorAuthenticationProviderSelector; >>>>>> import >>>>>> org.apereo.cas.web.flow.resolver.CasDelegatingWebflowEventResolver; >>>>>> import org.apereo.cas.web.flow.resolver.CasWebflowEventResolver; >>>>>> import org.springframework.beans.factory.annotation.Autowired; >>>>>> import org.springframework.beans.factory.annotation.Qualifier; >>>>>> import >>>>>> org.springframework.boot.context.properties.EnableConfigurationProperties; >>>>>> import org.springframework.cloud.context.config.annotation.RefreshScope; >>>>>> import org.springframework.context.an notation.Bean; >>>>>> import org.springframework.context.an notation.Configuration; >>>>>> import org.springframework.web.util.CookieGenerator; >>>>>> @Configuration("selectiveDuoWebflowEventResolverConfiguration") >>>>>> @EnableConfigurationProperties(CasConfigurationProperties.class) >>>>>> public class SelectiveDuoWebflowEventResolverConfiguration { >>>>>> @Autowired >>>>>> @Qualifier("initialAuthenticationAttemptWebflowEventResolver") >>>>>> private CasDelegatingWebflowEventResolver initialEventResolver; >>>>>> @Autowired >>>>>> @Qualifier("centralAuthenticationService") >>>>>> private CentralAuthenticationService centralAuthenticationService; >>>>>> @Autowired >>>>>> @Qualifier("defaultAuthenticationSystemSupport") >>>>>> private AuthenticationSystemSupport authenticationSystemSupport; >>>>>> @Autowired >>>>>> @Qualifier("defaultTicketRegistrySupport") >>>>>> private TicketRegistrySupport ticketRegistrySupport; >>>>>> @Autowired >>>>>> @Qualifier("servicesManager") >>>>>> private ServicesManager servicesManager; >>>>>> @Autowired(required = false) >>>>>> @Qualifier("multifactorAuthenticationProviderSelector") >>>>>> private final MultifactorAuthenticationProviderSelector >>>>>> multifactorAuthenticationProviderSelector = new >>>>>> RankedMultifactorAuthenticationProviderSelector(); >>>>>> @Autowired >>>>>> @Qualifier("warnCookieGenerator") >>>>>> private CookieGenerator warnCookieGenerator; >>>>>> @Autowired >>>>>> @Qualifier("authenticationServiceSelectionPlan") >>>>>> private AuthenticationServiceSelectionPlan >>>>>> authenticationRequestServiceSelectionStrategies; >>>>>> @RefreshScope >>>>>> @Bean >>>>>> public CasWebflowEventResolver selectiveDuoWebflowEventResolver() { >>>>>> return new SelectiveDuoWebflowEventResolver(authenticationSystemSupport, >>>>>> centralAuthenticationService, >>>>>> servicesManager, ticketRegistrySupport, warnCookieGenerator, >>>>>> authenticationRequestServiceSelectionStrategies, >>>>>> multifactorAuthenticationProviderSelector); >>>>>> } >>>>>> @PostConstruct >>>>>> public void initialize() { >>>>>> initialEventResolver.addDelegate(selectiveDuoWebflowEventResolver()); >>>>>> } >>>>>> } >>>>>> This is driving me nuts because in the documentation it just states that >>>>>> you are >>>>>> allowed to use multiple DUO instances. But I'm getting an error that >>>>>> transitions aren't defined for the mfa-duo-force instance: >>>>>> 2018-02-01 10:25:29,433 WARN >>>>>> [org.apereo.cas.web.flow.resolver.impl.AbstractCasWebflowEventResolver] - >>>>>> <Transition definition cannot be found for event [mfa-duo-force|mfa-duo]> >>>>>> If anyone has any information on how I can get this working or if I'm >>>>>> approaching this all wrong, please let me know. Thanks in advance! >>>>>> -- >>>>>> - Website: https://apereo.github.io/cas >>>>>> - Gitter Chatroom: https://gitter.im/apereo/cas >>>>>> - List Guidelines: https://goo.gl/1VRrw7 >>>>>> - Contributions: https://goo.gl/mh7qDG >>>>>> --- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "CAS >>>>>> Community" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>>> an email >>>>>> to [email protected] . >>>>>> To view this discussion on the web visit >>>>>> https://groups.google.com/a/apereo.org/d/msgid/cas-user/263f6a6c-9f2b-446f-9707-3c23b96a3f65%40apereo.org >>>>>> . >>>> -- >>>> - Website: https://apereo.github.io/cas >>>> - Gitter Chatroom: https://gitter.im/apereo/cas >>>> - List Guidelines: https://goo.gl/1VRrw7 >>>> - Contributions: https://goo.gl/mh7qDG >>>> --- >>>> You received this message because you are subscribed to the Google Groups >>>> "CAS >>>> Community" group. >>>> To unsubscribe from this group and stop receiving emails from it, send an >>>> email >>>> to [email protected] . >>>> To view this discussion on the web visit >>>> https://groups.google.com/a/apereo.org/d/msgid/cas-user/ea1c8c9e-e871-458c-bb74-38e3ed896421%40apereo.org >>>> . >>> -- >>> - Website: https://apereo.github.io/cas >>> - Gitter Chatroom: https://gitter.im/apereo/cas >>> - List Guidelines: https://goo.gl/1VRrw7 >>> - Contributions: https://goo.gl/mh7qDG >>> --- >>> You received this message because you are subscribed to the Google Groups >>> "CAS >>> Community" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email >>> to [email protected] . >>> To view this discussion on the web visit >>> https://groups.google.com/a/apereo.org/d/msgid/cas-user/CAMY5mid4RVozXqMAivmt%2BTFbduDud8054NkJFEdO8CM0tY6rTA%40mail.gmail.com >>> . > -- > - Website: https://apereo.github.io/cas > - Gitter Chatroom: https://gitter.im/apereo/cas > - List Guidelines: https://goo.gl/1VRrw7 > - Contributions: https://goo.gl/mh7qDG > --- > You received this message because you are subscribed to the Google Groups "CAS > Community" group. > To unsubscribe from this group and stop receiving emails from it, send an > email > to [email protected] . > To view this discussion on the web visit > https://groups.google.com/a/apereo.org/d/msgid/cas-user/f690f841-79e4-4df3-baa8-a69db84857cb%40apereo.org > . -- - Website: https://apereo.github.io/cas - Gitter Chatroom: https://gitter.im/apereo/cas - List Guidelines: https://goo.gl/1VRrw7 - Contributions: https://goo.gl/mh7qDG --- You received this message because you are subscribed to the Google Groups "CAS Community" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/1077095572.14106549.1518030638078.JavaMail.zimbra%40unicon.net.
