CAS 6.6.6 Is it possible to use Simple MFA as part of initial authentication and then flow to Surrogate selection?
(1) Have full deployment working with MFA, and Surrogate functioning, but not for the same authentication instance. If MFA triggered during authentication then surrogate selection is bypassed. Would like to be able to have ability for Simple MFA then proceed to surrogacy if authenticating user logins in with +username. If this is even possible. (2) With simple MFA, using couchDb for storage, what is the correct setting for MFA expiration? For instance require MFA every 30 days. All settings seem to leave couchDb expiration defaulting to 100 years in the future. Guessing un-documented parameter, not implemented, or a glitch. Worked around this with a nightly batch process to update the expirationDate relative to recordDate for all newly generated cache entries in couchDb. As an FYI, if expirationDate is greater than systemdate, couchDb entry will automatically be removed either during CAS scheduled cleanup, or if record is read during MFA. Spent extensive time ironing out details and testing with MFA and Surrogate, but could not solve (1). Would be good to know (2) for reference, or at least make note of it. # from service file "matchingStrategy": { "@class": "org.apereo.cas.services.FullRegexRegisteredServiceMatchingStrategy", "caseInsensitive": true }, "authenticationPolicy" : { "@class" : "org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy", "requiredAuthenticationHandlers" : ["java.util.TreeSet", [ "NetworkUser" ]], "criteria": { "@class": "org.apereo.cas.services.AllowedAuthenticationHandlersRegisteredServiceAuthenticationPolicyCriteria" } }, "usernameAttributeProvider" : { "@class" : "org.apereo.cas.services.PrincipalAttributeRegisteredServiceUsernameProvider", "usernameAttribute" : "username", "canonicalizationMode" : "NONE" }, "attributeReleasePolicy" : { "principalAttributesRepository" : { "@class" : "org.apereo.cas.authentication.principal.DefaultPrincipalAttributesRepository", "ignoreResolvedAttributes": false, "attributeRepositoryIds": ["java.util.HashSet", [ "usersimpersonated" ]], "mergingStrategy" : "REPLACE" }, "@class" : "org.apereo.cas.services.ReturnAllowedAttributeReleasePolicy", "allowedAttributes" : [ "java.util.ArrayList", [ "email", "username", "name_first", "name_last", "mfa_mode", "phone", "impersonate"] ] }, cas.authn.authentication-attribute-release.enabled=true # These attributes are released to determine whether to use mfa or impersonation cas.authn.attribute-repository.core.default-attributes-to-release=mfa_mode,username,impersonate,email,phone # Setting the expiration time to 0 disables caching these attributes in memory, # so they will be retrieved each time cas.authn.attribute-repository.core.expiration-time=0 # use cascade so that the attributes from initial queries can be used as the # query for the next repository cas.authn.attribute-repository.core.aggregation=CASCADE # this has to be set to REPLACE, otherwise the process fails between the simple name/pass # login and the MFA step cas.authn.attribute-repository.core.merger=REPLACE ## MFA settings cas.authn.mfa.web-authn.core.enabled=true cas.authn.mfa.trusted.device-fingerprint.cookie.max-age=-1 ### this setting does NOT seem to have any effect on MFA expiration ### cas.authn.mfa.web-authn.core.expire-devices=30 cas.authn.mfa.web-authn.core.expire-devices-time-unit=DAYS cas.authn.mfa.trusted.cleaner.schedule.enabled-on-host=.* cas.authn.mfa.trusted.cleaner.schedule.enabled=true cas.authn.mfa.trusted.cleaner.schedule.repeat-interval=PT2M cas.authn.mfa.trusted.cleaner.schedule.start-delay=PT15S cas.authn.mfa.web-authn.crypto.encryption.key=<hidden> cas.authn.mfa.web-authn.crypto.signing.key=<hidden> # use couchDb to cache MFA cas.authn.mfa.trusted.couch-db.caching=false cas.authn.mfa.trusted.couch-db.db-name=<db name> cas.authn.mfa.trusted.couch-db.username=<hidden> cas.authn.mfa.trusted.couch-db.password=<hidden> cas.authn.mfa.trusted.couch-db.url=<hidden> # leave as false, auto-create for MFA 6.6 is broken # (HAVE TO LOAD THE MFA DB DESIGN MANUALLY) cas.authn.mfa.trusted.couch-db.create-if-not-exists=false cas.authn.mfa.core.provider-selection-enabled=false cas.authn.mfa.simple.id=mfa-simple cas.authn.mfa.simple.name=mfa-simple cas.authn.mfa.simple.mail.from=<hidden> cas.authn.mfa.simple.mail.text=/<path to>/mfa_email.gtemplate cas.authn.mfa.simple.mail.subject= Your login code cas.authn.mfa.simple.mail.attribute-name=email cas.authn.mfa.simple.mail.validate-addresses=true cas.authn.mfa.simple.sms.attribute-name=phone cas.authn.mfa.simple.sms.from=<hidden> cas.authn.mfa.simple.sms.text=/<path to>/mfa_sms.gtemplate # due to a strange limitation in sending just the digits of the token # directly through Twilio ==> communicating to Twilio with a groovy script # that can first strip out the extra characters cas.sms-provider.groovy.location=file:/<path to>/send_sms.groovy ## time the generated token is valid for (set to 10 minutes) cas.authn.mfa.simple.token.core.time-to-kill-in-seconds=600 cas.authn.mfa.simple.token.core.token-length=6 cas.authn.mfa.simple.trusted-device-enabled=true cas.authn.mfa.simple.order=1 cas.authn.mfa.simple.failure-mode=OPEN # Trigger MFA based on outcome of Groovy script (instead of using a global setting) cas.authn.mfa.groovy-script.location=file:/etc/cas/casint/config/mfa_trigger.groovy # Trusted MFA Devices cas.authn.mfa.trusted.crypto.encryption.key=<hidden> cas.authn.mfa.trusted.crypto.signing.key=<hidden> cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.encryption.key=<hidden> cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.signing.key=<hidden> cas.authn.mfa.trusted.core.device-registration-enabled=true cas.authn.mfa.trusted.core.auto-assign-device-name=true cas.authn.mfa.trusted.core.authentication-context-attribute=isFromTrustedMultifactorAuthentication # MFA Fingerprint Settings # To control what is saved in the database during MFA cas.authn.mfa.trusted.device-fingerprint.component-separator=@ cas.authn.mfa.trusted.device-fingerprint.cookie.enabled=true cas.authn.mfa.trusted.device-fingerprint.cookie.order=1 cas.authn.mfa.trusted.device-fingerprint.client-ip.enabled=true cas.authn.mfa.trusted.device-fingerprint.client-ip.order=2 cas.authn.mfa.trusted.device-fingerprint.user-agent.enabled=false cas.authn.mfa.trusted.device-fingerprint.user-agent.order=3 cas.authn.mfa.trusted.device-fingerprint.cookie.comment=CAS Cookie cas.authn.mfa.trusted.device-fingerprint.cookie.name=CASMFACookie cas.authn.mfa.trusted.device-fingerprint.cookie.secure=false cas.authn.mfa.trusted.device-fingerprint.cookie.http-only=false # Surrogate attribute repository settings ## ## configure an attribute repository used by impersonation (in this case we are using the ## impersonatee's username to retrieve their info from this attribute repository) ## ## the <users who can be impersonated view> is every possible user who can be impersonated ## cas.authn.attribute-repository.jdbc[0].id=usersimpersonated cas.authn.attribute-repository.jdbc[0].driver-class=oracle.jdbc.OracleDriver cas.authn.attribute-repository.jdbc[0].dialect=org.hibernate.dialect.Oracle12cDialect cas.authn.attribute-repository.jdbc[0].url=<hidden> ## NOTE: the {0} in the following WHERE clause is replaced with username from the jdbc[2].username=username ## authentication setting ==> this is also 100% dependent upon the final username being resolved before using this ## ==> even though there are person directory settings for principal attribute, those ## are 100% (ignored?) / over-ridden by what is returned as the principal attribute from ## prior authentication actions ## cas.authn.attribute-repository.jdbc[0].sql=SELECT * FROM <users who can be impersonated view> WHERE {0} cas.authn.attribute-repository.jdbc[0].read-only=true cas.authn.attribute-repository.jdbc[0].require-all-attributes=false cas.authn.attribute-repository.jdbc[0].single-row=true cas.authn.attribute-repository.jdbc[0].state=ACTIVE cas.authn.attribute-repository.jdbc[0].attributes.name_first=name_first cas.authn.attribute-repository.jdbc[0].attributes.name_last=name_last cas.authn.attribute-repository.jdbc[0].attributes.mfa_mode=mfa_mode cas.authn.attribute-repository.jdbc[0].attributes.username=username cas.authn.attribute-repository.jdbc[0].attributes.impersonate=impersonate cas.authn.attribute-repository.jdbc[0].attributes.email=email cas.authn.attribute-repository.jdbc[0].attributes.phone=phone cas.authn.attribute-repository.jdbc[0].attributes.lowerusername=lowerusername # a lowercase version of the username is necessary in order for # the surrogate match/drop down to work correctly, while at the # same time allowing the username attribute to remain case sensitive # # lowerusername is NOT included in the released attributes cas.authn.attribute-repository.jdbc[0].username=lowerusername cas.authn.attribute-repository.jdbc[0].password=<hidden> cas.authn.attribute-repository.jdbc[0].user=<hidden> cas.authn.attribute-repository.jdbc[0].case-insensitive-query-attributes=username->NONE cas.authn.attribute-repository.jdbc[0].default-schema=<hidden> cas.authn.attribute-repository.jdbc[0].autocommit=false cas.authn.attribute-repository.jdbc[0].batch-size=1 cas.authn.attribute-repository.jdbc[0].ddl-auto=none cas.authn.attribute-repository.jdbc[0].fail-fast-timeout=1 cas.authn.attribute-repository.jdbc[0].fetch-size=2000 cas.authn.attribute-repository.jdbc[0].health-query=select 1 from dual cas.authn.attribute-repository.jdbc[0].idle-timeout=PT10M cas.authn.attribute-repository.jdbc[0].isolate-internal-queries=false cas.authn.attribute-repository.jdbc[0].isolation-level-name=ISOLATION_READ_COMMITTED cas.authn.attribute-repository.jdbc[0].leak-threshold=10 cas.authn.attribute-repository.jdbc[0].order=1 cas.authn.attribute-repository.jdbc[0].pool.keep-alive-time=0 cas.authn.attribute-repository.jdbc[0].pool.max-size=18 cas.authn.attribute-repository.jdbc[0].pool.max-wait=PT20S cas.authn.attribute-repository.jdbc[0].pool.maximum-lifetime=PT10M cas.authn.attribute-repository.jdbc[0].pool.min-size=6 cas.authn.attribute-repository.jdbc[0].pool.suspension=false cas.authn.attribute-repository.jdbc[0].pool.timeout-millis=1000 cas.authn.attribute-repository.jdbc[0].propagation-behavior-name=PROPAGATION_REQUIRED cas.person-directory.active-attribute-repository-ids=usersimpersonated cas.person-directory.attribute-resolution-enabled=true cas.person-directory.principal-resolution-conflict-strategy=last cas.person-directory.principal-resolution-failure-fatal=false cas.person-directory.principal-transformation.case-conversion=NONE cas.person-directory.return-null=true cas.person-directory.use-existing-principal-id=false ## ## configure impersonation ## cas.authn.jaas[0].realm=CAS cas.authn.surrogate.separator=+ # Timeout in seconds to kill the surrogate session and consider tickets expired. # currently set to 8 hours cas.authn.surrogate.tgt.time-to-kill-in-seconds=28800 cas.authn.surrogate.principal.active-attribute-repository-ids=usersimpersonated cas.authn.surrogate.principal.attribute-resolution-enabled=true cas.authn.surrogate.principal.principal-attribute=username cas.authn.surrogate.principal.principal-resolution-conflict-strategy=last cas.authn.surrogate.principal.principal-resolution-failure-fatal=false cas.authn.surrogate.principal.principal-transformation.case-conversion=NONE cas.authn.surrogate.principal.return-null=true cas.authn.surrogate.principal.use-existing-principal-id=false cas.authn.surrogate.jdbc.driver-class=oracle.jdbc.OracleDriver cas.authn.surrogate.jdbc.dialect=org.hibernate.dialect.Oracle12cDialect cas.authn.surrogate.jdbc.url=<hidden> cas.authn.surrogate.jdbc.user=<hidden> cas.authn.surrogate.jdbc.password=<hidden> cas.authn.surrogate.jdbc.default-schema=<hidden> cas.authn.surrogate.jdbc.ddl-auto=none cas.authn.surrogate.jdbc.leak-threshold=10000 # NOTE: both of the following queries are wrapping the username with LOWER # ==> this is necessary for the impersonation dropdown selector to sort # and work correctly with short cut keys ==> this DOES NOT impact the # username release attribute (which needs to be case sensitive) # NOTE: the following queries may not match the documentation... # the 6.x documentation appears incorrect in regards to these queries # deterimine whether authenicated user can impersonate another user cas.authn.surrogate.jdbc.surrogate-search-query=SELECT COUNT(*) FROM <users per impersonator view> WHERE impersonator = ? AND LOWER(username) = ? # list of qualified accounts that can be impersonated per the "authenticated" impersonating user cas.authn.surrogate.jdbc.surrogate-account-query=SELECT LOWER(username) AS surrogateAccount FROM <users per impersonator view> WHERE impersonator = ? -- - 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 cas-user+unsubscr...@apereo.org. To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/a8cecf8d-a607-4695-b787-7ad1325348f4n%40apereo.org.