Unable to register MFA trusted devices

394 views
Skip to first unread message

Hayden Sartoris

unread,
Dec 13, 2019, 10:54:21 AM12/13/19
to CAS Community
The brief story: CAS never kicks off the multifactor trusted device registration webflow. I've tried this with just about every version of CAS 6, most recently with 6.1.2 and a large number of 6.2.0 snapshots. I've tested this with Google Authenticator, using both Redis and JSON for token storage, as well as CAS Simple MFA. I'm posting the very stripped-down configuration I've tried against a bare overlay template, but this has also been tested in a much more fully fledged environment with an LDAP backend, Redis ticket storage, etc. etc..

What stands out to me is that this was working before, at the beginning of the year, I believe. That leads me to suspect that something changed such that I am effectively misconfiguring the trusted MFA settings. Otherwise, I don't see how it could be so uniformly broken across multiple versions. On the other hand, I've attempted this with MFA REST storage, and the code for that is actually broken (in the sense that the cleaner process errors out without even contacting the REST URL), so perhaps there's just something totally wrong with MFA trusted devices in general.

My testbed uses the vanilla Apereo CAS overlay template with the below modifications, including removing cas.properties in favor of cas.yml. I have a single RegexRegisteredService with no configuration other than the name, id, and URL. I am able to login as casuser, which triggers MFA registration as expected, proceeds to prompt for the token, and then... authenticates me directly to the service. The entire time, the only occurrence of the strings 'trust' or 'Trust' in the logs are 1. CAS dumping the configured property names at startup, 2. warnings about the encryption keys being set (obviously doesn't occur with a production configuration), and 3. the MFA trusted device storage cleaner firing and not finding anything.

I'm really at the end of my rope here, and hoping someone will tell me I'm an idiot and I've missed something obvious.

Thanks for any input,
Hayden Sartoris

Additional modules in build.gradle:
dependencies {
   
// Other CAS dependencies/modules may be listed here...
    compile
"org.apereo.cas:cas-server-support-json-service-registry:${casServerVersion}"
    compile
"org.apereo.cas:cas-server-support-gauth:${casServerVersion}"
    compile
"org.apereo.cas:cas-server-support-gauth-redis:${casServerVersion}"
    compile
"org.apereo.cas:cas-server-support-trusted-mfa:${casServerVersion}"
}

CAS configuration:
redis:
  host
: redis
  port
: 6379
server
:
  port
: 8443
  ssl
:
    enabled
: true
    keyStore
: <...>

cas
:
  serviceRegistry
.json.location: "file:/etc/cas/services"
  server
:
    name
: https://cas02.bard.edu:8443
    prefix
: ${cas.server.name}/cas
  authn
:
    mfa
:
      globalProviderId
: mfa-gauth
      gauth
:
        issuer
: Bard
        label
: cas02.bard.edu
        codeDigits
: 6
        timeStepSize
: 30
        trustedDeviceEnabled
: true
        redis
:
          host
: ${redis.host}
          port
: ${redis.port}
      trusted
:
        deviceRegistrationEnabled
: true
        json
.location: "file:/etc/cas/config/trusted-dev.json"

Nono

unread,
Dec 16, 2019, 4:05:10 AM12/16/19
to CAS Community
Hello Hayden

i am working on a poc implementing trusted device fingerprinting with cas 6.1.2 (json storage for now) and i had the same problem, the user was never prompted the invite to register the device. I did a little debugging on cas and i found that if you redefine the class  org.apereo.cas.config.CasSimpleMultifactorAuthenticationConfiguration in your war overlay and remove the conditions of activation of the subclass CasSimpleMultifactorTrustConfiguration :


l133-l134 :

@ConditionalOnBean(name = "mfaTrustEngine")
@ConditionalOnProperty(prefix = "cas.authn.mfa.simple", name = "trustedDeviceEnabled", havingValue = "true", matchIfMissing = true)

then it works, though i have no idea yet of the possible side effects of this modification.

For now, cas registers the devices but the MFA always kicks in when a user try to connect from the same device, have anyone had any succes with this feature ?

Hayden Sartoris

unread,
Dec 16, 2019, 12:45:02 PM12/16/19
to CAS Community
Hi Nono,

Thanks for the tip, I think I have a better idea of what's going on now. The caveat is that I'm not a Java/Spring developer, but here's my take: MultifactorAuthnTrustConfiguration.java instantiates a Bean called 'mfaTrustEngine' if no other such Bean exists; i.e., when no storage provider like MongoDB, REST, etc., have been setup. The simple & gauth MFA configurations (and all of the other providers, it seems) watch for the existence of that Bean, only configuring the trusted device webflow if it exists. Because the Bean is waiting to ensure no other mfaTrustEngine has been created, it fires late in the startup sequence, after the MFA provider has been instantiated. Although it's tagged with @RefreshScope, the MFA provider does not refresh after the trusted device storage has been instantiated, and thus the webflow never gets updated.

By removing the @ConditionalOnBean, the configuration flow executes regardless, and indeed the mfaTrustEngine will be created later in the process. I'm trying some modifications to the underlying codebase, which I can keep you posted on if you'd like.

Worst case scenaria are either split split JSON/in-memory trusted device support out into another module that loads in the same way as the other backend modules, or use one of the existing modules. This is definitely a very confusing bug for people who are just trying to test things, though, so I don't like the latter.

Best,
Hayden

Hayden Sartoris

unread,
Dec 16, 2019, 1:30:16 PM12/16/19
to CAS Community
I think I've more or less confirmed the theory. Started a PR with a POC using Gauth here: https://github.com/apereo/cas/pull/4552

Hayden Sartoris

unread,
Dec 20, 2019, 1:31:59 PM12/20/19
to CAS Community
Update: patched! Thanks for the tip, Nono!

randomuser878

unread,
Dec 20, 2019, 2:03:43 PM12/20/19
to CAS Community
Hello. Do you happen to know if this patch is applicable to 6.1.x tree as well or only 6.2.x?

Thanks.

Nono

unread,
Dec 21, 2019, 3:16:57 PM12/21/19
to CAS Community
Nice ! Good job, thanks for the job !

Matthew Gordon

unread,
Mar 22, 2022, 11:56:13 AM3/22/22
to CAS Community
I believe this issue has arisen again in 6.5.1, at least with the REST iteration: support-trusted-mfa-rest.

Thank you,
Matt
Reply all
Reply to author
Forward
0 new messages