Authentication Policy with Multiple Directories

51 views
Skip to first unread message

Tom O'Neill

unread,
Jan 1, 2021, 3:51:13 PM1/1/21
to cas-...@apereo.org

Hi All,

 

I am working on a CAS 6.3 deployment where we need to configure multiple directories for authentication using LDAP.

 

I have both LDAP sources configured and working with LPPE enabled but I need to change the authentication behavior slightly.

 

If the user is found in the first directory and authentication fails, I need the authentication process to stop.

The second directory should not be queried if the first has a user record with a different password than what the user entered.

If no record is found for the user in the first directory, the authentication process should continue on through the chain.

 

I thought I’d be able to use an existing Authentication Policy but I don’t see any that match my goal.

https://apereo.github.io/cas/6.3.x/configuration/Configuration-Properties.html#authentication-policy

 

I don’t want it to allow ‘any’ and I don’t want to specify one or the other as required.

 

LLPE doesn’t process the exception since there is no entry in the errorMap object for ‘LOGON_FAILURE’.

After processing the first result CAS moves on to check the next ‘GENERIC’ directory:

 

2021-01-01 19:21:32,215 DEBUG [org.apereo.cas.authentication.support.DefaultLdapAccountStateHandler] - <Handling LDAP account state error [LOGON_FAILURE]>

2021-01-01 19:21:32,215 DEBUG [org.apereo.cas.authentication.support.DefaultLdapAccountStateHandler] - <No LDAP error mapping defined for [LOGON_FAILURE]>

2021-01-01 19:21:32,215 DEBUG [org.apereo.cas.authentication.support.DefaultLdapAccountStateHandler] - <Handling account state warning [null]>

2021-01-01 19:21:32,215 DEBUG [org.apereo.cas.authentication.support.DefaultLdapAccountStateHandler] - <Account state warning not defined>

2021-01-01 19:21:32,216 INFO [org.apereo.cas.authentication.PolicyBasedAuthenticationManager] - <[AD] exception details: [Invalid credentials].>

2021-01-01 19:21:32,216 DEBUG [org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler] - <Examining credential [UsernamePasswordCredential(username=testaccount, source=null, customFields={})] eligibility for authentication handler [GENERIC]>

 

With so many configurable options, it seems like there should be a way to accomplish this without writing code.

Right now I’m looking at modifying the DefaultAccountStateHandler to include a mapping in errorMap for ‘LOGIN_FAILURE’.

I’m not 100% sure that will work the way I need it to but it seems like a fairly straightforward option and modification.

 

Thanks!!

Tom

 

Tom O'Neill

unread,
Jan 5, 2021, 12:08:31 PM1/5/21
to cas-...@apereo.org

Hi All,

 

I’ve done some additional digging and it seems like the easiest solution would be to use a Groovy script for the authentication policy.

https://apereo.github.io/cas/6.3.x/installation/Configuring-Authentication-Components.html#authentication-policy

 

I may be missing something but I don’t see to be able to get CAS to execute the a Groovy script.

I’ve tried setting the following property in my CAS config:

 

cas.authn.policy.groovy[0].script=file:/etc/cas/config/account.groovy

 

I modified the example so that it would output a message to the log and then return NULL – just wanted to see it get invoked.

 

import java.util.*

import org.apereo.cas.authentication.exceptions.*

import javax.security.auth.login.*

 

def Exception run(final Object... args) {

    def principal = args[0]

    def logger = args[1]

    logger.error(“***** Groovy Account Policy”)

    return null;

}

 

The code doesn’t seem to get hit at all – no messages output in the log and the default account policies are applied.

 

Any suggestions or guidance would be greatly appreciated.

I tried a Groovy password policy script and while it executed, it didn’t stop the authentication chain from processing the second LDAP after authentication fails on the first.

 

Thanks,

 

Tom

 

From: 'Tom O'Neill' via CAS Community <cas-...@apereo.org>
Sent: Friday, January 1, 2021 3:51 PM
To: cas-...@apereo.org
Subject: [EXT] [cas-user] Authentication Policy with Multiple Directories

 

CAUTION: This email originated from outside of SIG. Exercise caution when opening attachments or clicking links, especially from unknown senders.

[EXT-STAMP-ADDED]

--
- 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+u...@apereo.org.
To view this discussion on the web visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/MN2PR02MB665506502F74EA8261B96008CBD50%40MN2PR02MB6655.namprd02.prod.outlook.com.

Tom O'Neill

unread,
Jan 5, 2021, 3:23:46 PM1/5/21
to cas-...@apereo.org

Hi All,

 

I re-read my message and realized immediately where the issue was.

Whenever properties “aren’t being read” it’s always because I’m missing a dependency.

Since the password policy was covered by ‘cas-server-support-ldap’ I wasn’t thinking when I switched to testing the authentication policy.

I added the following dependency and I see the log entries:

cas-server-support-generic

 

I’m going to see if I can use this approach to accomplish my goal.

 

Still open to suggestions.

Tom O'Neill

unread,
Jan 8, 2021, 8:15:10 AM1/8/21
to cas-...@apereo.org

I have my Groovy authentication policy code being executed but I may be missing something.

The script is only passed the authenticated principal from the authentication context in GroovyScriptAuthenticationPolicy.java

 

cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/policy/GroovyScriptAuthenticationPolicy.java

 

    private Optional<Exception> getScriptExecutionResult(final Authentication auth) {

        val args = CollectionUtils.wrap("principal", auth.getPrincipal(), "logger", LOGGER);

        executableScript.setBinding(args);

        return executableScript.execute(args.values().toArray(), Optional.class);

    }

 

How would I evaluate the authentication handler results from a Groovy script if I only have the principal?

 

I was able to create a workaround by applying the NotPreventedException policy and using a Groovy password policy script to throw a Prevented Exception on certain conditions.

It mostly works but it isn’t perfect and it seems like the authentication policy is the root issue so I’d like to create a new one either through a Groovy script or Java, if necessary.

amit rathee

unread,
Jan 8, 2021, 8:49:59 AM1/8/21
to cas-...@apereo.org

It appears that the body returned is not a valid SOAP-ENV XML document.
Actually after inspecting the body, two XML SOAP-ENV documents (concatenated) are returned within the same response, which is unexpected and gets our SOAP parser lost.

This happens only with PHP/APACHE apps , all Java/JBOSS apps working fine 

Cheers ,
Amit

Reply all
Reply to author
Forward
0 new messages