Exclusive Authentication Source

140 views
Skip to first unread message

Colin Ryan

unread,
May 4, 2021, 11:58:20 AM5/4/21
to cas-...@apereo.org

Folks,


Sorry for the likely stupid post, I swore I had sorted this prior. But I have 3 authentication sources defined. LDAP, Radius and Google MFA.

I want to restrict a service to using - and most importantly trying - only an explicitly configured service. I.e. If I say LDAP as the Auth Resource, upon a failure I do _not_ want it to go ahead and try the other resources.


In cas.properties I have:


cas.authn.policy.source-selection-enabled=false
cas.authn.policy.required-handler-authentication-policy-enabled=true
cas.authn.policy.req.try-all=false


and an example service definition as below:


{
    "_id": {
        "$numberLong": "9999999999999"
    },
    "serviceId": "xxxxxxxxxx",
    "name": "SSO CAS Server",
    "expirationPolicy": {
        "deleteWhenExpired": false,
        "notifyWhenDeleted": false,
        "notifyWhenExpired": false,
        "_class": "org.apereo.cas.services.DefaultRegisteredServiceExpirationPolicy"
    },
    "acceptableUsagePolicy": {
        "enabled": true,
        "_class": "org.apereo.cas.services.DefaultRegisteredServiceAcceptableUsagePolicy"
    },
    "proxyPolicy": {
        "_class": "org.apereo.cas.services.RefuseRegisteredServiceProxyPolicy"
    },
    "proxyTicketExpirationPolicy": {
        "numberOfUses": {
            "$numberLong": "0"
        },
        "_class": "org.apereo.cas.services.DefaultRegisteredServiceProxyTicketExpirationPolicy"
    },
    "serviceTicketExpirationPolicy": {
        "numberOfUses": {
            "$numberLong": "0"
        },
        "_class": "org.apereo.cas.services.DefaultRegisteredServiceServiceTicketExpirationPolicy"
    },
    "evaluationOrder": 99999,
    "usernameAttributeProvider": {
        "canonicalizationMode": "NONE",
        "encryptUsername": false,
        "_class": "org.apereo.cas.services.DefaultRegisteredServiceUsernameProvider"
    },
    "logoutType": "BACK_CHANNEL",
    "environments": [],
    "attributeReleasePolicy": {
        "principalAttributesRepository": {
            "mergingStrategy": "MULTIVALUED",
            "attributeRepositoryIds": [],
            "ignoreResolvedAttributes": false,
            "_class": "org.apereo.cas.authentication.principal.DefaultPrincipalAttributesRepository"
        },
        "consentPolicy": {
            "enabled": true,
            "order": 0,
            "_class": "org.apereo.cas.services.consent.DefaultRegisteredServiceConsentPolicy"
        },
        "authorizedToReleaseCredentialPassword": false,
        "authorizedToReleaseProxyGrantingTicket": false,
        "excludeDefaultAttributes": false,
        "authorizedToReleaseAuthenticationAttributes": true,
        "order": 0,
        "_class": "org.apereo.cas.services.ReturnAllAttributeReleasePolicy"
    },
    "multifactorPolicy": {
        "multifactorAuthenticationProviders": [],
        "failureMode": "UNDEFINED",
        "bypassEnabled": false,
        "forceExecution": false,
        "bypassTrustedDeviceEnabled": false,
        "_class": "org.apereo.cas.services.DefaultRegisteredServiceMultifactorPolicy"
    },
    "accessStrategy": {
        "order": 0,
        "enabled": true,
        "ssoEnabled": true,
        "delegatedAuthenticationPolicy": {
            "allowedProviders": [],
            "permitUndefined": true,
            "exclusive": false,
            "_class": "org.apereo.cas.services.DefaultRegisteredServiceDelegatedAuthenticationPolicy"
        },
        "requireAllAttributes": true,
        "requiredAttributes": {},
        "rejectedAttributes": {},
        "caseInsensitive": false,
        "_class": "org.apereo.cas.services.DefaultRegisteredServiceAccessStrategy"
    },
    "authenticationPolicy": {
        "requiredAuthenticationHandlers" : ["java.util.TreeSet", [ "LDAP" ]],
        "criteria": {
            "tryAll": false,
            "_class": "org.apereo.cas.services.AllowedAuthenticationHandlersRegisteredServiceAuthenticationPolicyCriteria"
        },
        "_class": "org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy"
    },
    "properties": {},
    "contacts": [],
    "_class": "org.apereo.cas.services.RegexRegisteredService"
}

What am I missing?

Thanks

artur miś

unread,
Dec 2, 2021, 10:34:45 AM12/2/21
to CAS Community, C Ryan
Have you find out solution ?

Colin Ryan

unread,
Dec 2, 2021, 11:04:45 AM12/2/21
to artur miś, CAS Community

This is what I'm using...to be honest I can't seem to recall if this does not bother trying the other resources...I think it does what we originally wanted.


 "authenticationPolicy": {
        "requiredAuthenticationHandlers": ["LDAP"],
        "criteria": {
            "tryAll": false,
            "_class": "org.apereo.cas.services.AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria"
        },
        "_class": "org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy"
    },

artur miś

unread,
Dec 3, 2021, 2:58:43 AM12/3/21
to CAS Community, C Ryan, artur miś
Could you please  if you  can show   cas.auth.policies too ,you have  connectet to this solution ?

AM

artur miś

unread,
Dec 3, 2021, 6:59:32 AM12/3/21
to CAS Community, artur miś, C Ryan
My service is  test-1.json


{
"@class": "org.apereo.cas.services.RegexRegisteredService",
"serviceId": "^(http|https|imaps)://serwis.org/casphp*",
"name": "test",
"id": 1,
"description": "Straggle Today!",
"authenticationPolicy": {
        "requiredAuthenticationHandlers": ["java.util.TreeSet", [ "everest" ]],
        "criteria": {
            "try-All": false, <- this probablly shoud make magic but it didn't
            "@class": "org.apereo.cas.services.AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria"
        },
        "@class": "org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy"
    }
}


I am not included in cas.propierties any directive  like cas.auth.policy.<xxx>:

cas.authn.policy.any.try-All
or
cas.authn.policy.all.enabled
or
cas.authn.policy.source-selection-enabled
or
cas.authn.policy.required-handler-authentication-policy-enabled



My  version Cas-overlay  is 6.3.2 on docker ,I  have 3 AD handlers  and   i test   nonserviced  login via https://exaple.org/casphp  and i can see that   some times  it use  ppm handler or  second everest  one becouse userx is in  both it semms to be ok.If i test fore service  via   REST API  (becouse  for this sandbox cas i not conected any servis phisicaly yet  so i  test it via comand line  but it doesn't seem be a reason  of problems),but i  trully blieve that you have some hack  to manage it.



TEST curl:
from server side:
cat api_test.bash
#!/bin/bash
ff=`curl -k -X POST -H 'Content-Type: Application/x-www-form-urlencoded' -H 'Accept: applications/json' https://example.org/casphp/v1/tickets -d 'username=userx&password=xxx'`
echo $ff
dd="curl -X POST -H \"Content-Type: Application/x-www-form-urlencoded\" -H \"Accept: application/json\" https://example.org/casphp/v1/tickets/"$ff"?service=https://serwis.org/casphp"
echo "dd:$dd"
st=`$dd`
echo "$st"
vv="curl  -k  https://example.org/casphp/p3/serviceValidate?service=https://serwice.org/casphp&ticket="$st
echo "|$vv|"
output=`$vv`1
echo "|$output|"

So i received:

|<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
    <cas:authenticationSuccess>
        <cas:user>userx</cas:user>
        <cas:attributes>
            <cas:credentialType>UsernamePasswordCredential</cas:credentialType>
            <cas:isFromNewLogin>true</cas:isFromNewLogin>
            <cas:authenticationDate>2021-12-03T11:25:14.792314Z</cas:authenticationDate>
            <cas:authenticationMethod>ppm</cas:authenticationMethod>
            <cas:successfulAuthenticationHandlers>ppm</cas:successfulAuthenticationHandlers> < - here i want to have deterministic everest ( not sometimes ppm  or everest )
            <cas:longTermAuthenticationRequestTokenUsed>false</cas:longTermAuthenticationRequestTokenUsed>
            </cas:attributes>
    </cas:authenticationSuccess>
</cas:serviceResponse>|


Restult is not deterministic  .User is receiving auth sometimes from ppm sometimes from everest  . I dicsovered that if i restart cas container : I coud have ppm    and  it seems that to te next restart keep ppm handler .If i meke next restart od cas i can have ppm or everest. Between restart it looks like it keep handler   chosed at the begginig. It is litle bit magic for me.

artur miś

unread,
Dec 3, 2021, 12:28:50 PM12/3/21
to CAS Community, artur miś, C Ryan
Dear C Ryan,


 I have made some  new test  with:

"try-All": true
or
"tryAll": true

user kowalski has credentials  in handers:ppm and everest.

{
"@class": "org.apereo.cas.services.RegexRegisteredService",
"serviceId": "^(http|https|imaps)://serwis.org/casphp*",
"name": "Test",

"id": 1,
"description": "Straggle Today!",
"authenticationPolicy": {
        "requiredAuthenticationHandlers": ["java.util.TreeSet", [ "everest" ]],
        "criteria": {
              "tryAll": true       OR   "tryAll": true
            "@class": "org.apereo.cas.services.AnyAuthenticationHandlerRegisteredServiceAuthenticationPolicyCriteria"
        },
        "@class": "org.apereo.cas.services.DefaultRegisteredServiceAuthenticationPolicy"
    }
}
With cas.propierties:
cas.authn.policy.required-handler-authentication-policy-enabled=true


Shortcut Debug log from CAS :
Examining credential  is not deterministic ,sometimes it strats from  handler ppm  , sometimes from everest_365 ,  sometimes everest (probaly it is normal  or  mayby  i could  put    <handler>.order=0   but  it seems to be not enough , i would like thet servise  launch handler in deterministic way ) . This small example is showing  how it comes in my case:

2021-12-03 16:31:11,779 DEBUG [org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler] - <Examining credential [UsernamePasswordCredential(username=kowalski, source=null, customFields={})] eligibility for authentication handler [ppm]>

Here i cant see any  probe to  Examine credential do everest handler ( After it  had achived ppm    it was not trying  any exmination other handlers - one positive is that kowalski is not able use credential from  ppm to  log to serwis.org/casphp

Ready go father...

2021-12-03 16:31:11,854 DEBUG [org.apereo.cas.authentication.policy.AtLeastOneCredentialValidatedAuthenticationPolicy] - <Authentication policy is satisfied having found at least one authentication transactions>

...

2021-12-03 16:31:12,063 DEBUG [org.apereo.cas.authentication.policy.RequiredHandlerAuthenticationPolicyFactory] - <Required authentication handlers for this service [Test] are [[everest]]>
2021-12-03 16:31:12,064 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: kowalski
WHAT: https://serwice.org/casphp
ACTION: SERVICE_TICKET_NOT_CREATED
APPLICATION: CAS
WHEN: Fri Dec 03 16:31:12 GMT 2021
CLIENT IP ADDRESS: *****
SERVER IP ADDRESS: ****
=============================================================

>



Is is look like cas doesn't  event  try  examine other handlers  , but why  i have  included tryAll  or try-All   in json file ? .
What more , i have seen  that if cas examine first  i.e everest_365 where kowalski  has not got credentials , cas is switched to next handler it started examine  next handlers. If it is ppm , user is succesfully authenticated  and no more action with everest is made.


I dont know if i explained well . Anyway thank you  if you have time to waste on this topic.
Reply all
Reply to author
Forward
0 new messages