JSON Service for CAS Client does not follow success message of required Handler

327 views
Skip to first unread message

Artur Stöcklin

unread,
Dec 1, 2015, 11:43:36 AM12/1/15
to CAS Community
hello community

I currently fight with the following problem:

1. in classpath:/services/service1.json I put the following file:

{
  "@class" : "org.jasig.cas.services.RegexRegisteredService",
  "serviceId" : "^(http|https)://localhost.*",
  "description" : "cool service",
  "name" : "coolService",
  "id" : 1,
  "theme" : "testtheme",
  "logoutType" : "BACK_CHANNEL",
  "evaluationOrder" : 1,
  "accessStrategy" : {
    "@class" : "org.jasig.cas.services.DefaultRegisteredServiceAccessStrategy",
    "enabled" : true,
    "ssoEnabled" : true
  },
  "requiredHandlers" : [ "java.util.HashSet", [ "hfcAuthenticationHandler2" ] ]

}

CAS reads the file and creates the associated service. I can see the service in the JsonServiceRegistryDao. There is also the "hfcAuthenticationHandler2" name in the Set of given requiredHandlers.


2. The deployerConfigContext.xml file looks like this one:

    <bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
       <constructor-arg>
           <map>
               <!--
                  | IMPORTANT
                  | Every handler requires a unique name.
                  | If more than one instance of the same handler class is configured, you must explicitly
                  | set its name to something other than its default name (typically the simple class name).
                  -->
               <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
               <!--  <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" /> -->
               
               <entry key-ref="hfcAuthenticationHandler" value-ref="primaryPrincipalResolver" />
               <entry key-ref="hfcAuthenticationHandler2" value-ref="primaryPrincipalResolver" />
           </map>
       </constructor-arg>

        <!-- Uncomment the metadata populator to capture the password.
       <property name="authenticationMetaDataPopulators">
          <util:list>
              <bean class="org.jasig.cas.authentication.CacheCredentialsMetaDataPopulator"/>
          </util:list>
       </property>
       -->

        <!--
          | Defines the security policy around authentication. Some alternative policies that ship with CAS:
          |
          | * NotPreventedAuthenticationPolicy - all credential must either pass or fail authentication
          | * AllAuthenticationPolicy - all presented credential must be authenticated successfully
          | * RequiredHandlerAuthenticationPolicy - specifies a handler that must authenticate its credential to pass
          -->
       <property name="authenticationPolicy">
           <bean class="org.jasig.cas.authentication.RequiredHandlerAuthenticationPolicy"
                    c:requiredHandlerName="hfcAuthenticationHandler"
               p:tryAll="false"/>
       </property>
       
       <!--  
       <property name="authenticationPolicy">
           <bean class="org.jasig.cas.authentication.AnyAuthenticationPolicy" />
       </property>
       -->
   </bean>  
 
<bean id="hfcAuthenticationHandler"
         class="ch.cas.authentication.handler.HFCAuthenticationHandler"
         p:name="hfcAuthenticationHandler">
        </bean>
         
      <bean id="hfcAuthenticationHandler2"
         class="ch.cas.authentication.handler.HFCAuthenticationHandler2"
         p:name="hfcAuthenticationHandler2">
     </bean>

      <bean id="serviceRegistryDao" class="org.jasig.cas.services.JsonServiceRegistryDao"
         c:configDirectory="${service.registry.config.location}" />

When I request the CAS Login page with a CAS client (webapp) which uses the defined CAS Service (Point 1) the required Handler (hfcAuthenticationHandler2) is called and returns "success". But CAS still returns "bad credentials" because the "hfcAuthenticationHandler" defined in the authenticationPolicy returns "failed". 

When I read the documentation (http://jasig.github.io/cas/4.1.x/installation/Service-Management.html) I understand that with the requiredHandlers parameter in the service json file I can define which handler should return "success" for the given service. If the defined service handler returns "success" the user should be logged in. Only when I change the authenticationPolicy to  "c:requiredHandlerName="hfcAuthenticationHandler2the service login successes.

How should I define the requiredHandlers in the json file if I want to specify the hfcAuthenticationHandler2 for my service which should return "success" independet from any other AuthenticationHandler defined in deployerConfigContext.xml which also can return "success"?
I want only the one handler be triggered if the defined CAS client requests the CAS service from json.

Thanks in advance

Artur

Misagh Moayyed

unread,
Dec 1, 2015, 1:53:56 PM12/1/15
to CAS Community
I don’t think that actually works the way you describe. You are telling CAS that the only way an authentication event can success is if handler X succeeds. In your case, it never does. 

If your use case is, “I only want this handler to run for this service, and that handler for that service”, then that does not exist in CAS yet. It’s on the roadmap. 


- Misagh

--
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.
Visit this group at http://groups.google.com/a/apereo.org/group/cas-user/.

Artur Stöcklin

unread,
Dec 2, 2015, 5:43:08 AM12/2/15
to CAS Community, mmoa...@unicon.net
Hi Misagh

Thank you for your reply. 

I do not understand. What is then the value of the "requiredHandlers" attribute in the service json file?
In my case, if I define the requiredHandler as "hfcAuthenticationHandler2" which during authentication throws an AuthenticationException (login failed), but my other AuthenticationHandler "hfcAuthenticationHandler" returns success, the CAS Client user will be anyway logged in. What is then the sense of defining the requiredHandlers on the service itself? 

And how the requiredHandlers attribute cooperates with my RequiredHandlerAuthenticationPolicy defined in deployerConfigContext.xml which determinates, that "hfcAuthenticationHandler" is my required Handler for (as I understand) direct login on CAS server without any CAS Client.

Thanks in advance
Artur

Misagh Moayyed

unread,
Dec 2, 2015, 1:52:33 PM12/2/15
to CAS Community
On Dec 2, 2015, at 3:43 AM, Artur Stöcklin <source...@gmail.com> wrote:

Hi Misagh

Thank you for your reply. 

I do not understand. What is then the value of the "requiredHandlers" attribute in the service json file?
In my case, if I define the requiredHandler as "hfcAuthenticationHandler2" which during authentication throws an AuthenticationException (login failed), but my other AuthenticationHandler "hfcAuthenticationHandler" returns success, the CAS Client user will be anyway logged in. What is then the sense of defining the requiredHandlers on the service itself? 



I suspect the intention of that property was to emulate MFA behavior to some degree at the time, which obviously is now defective and flawed in terms of how we “really” implement MFA. The idea conceptually is that you can require a number of authentication methods (i.e. handlers) for a given service, such that access to that service can only be granted if those methods have passed. Then you have say 5 handlers defined in your configuration. Out of those 5, for a given authentication event 4 handlers may fail and 1 may actually go through. (Note that all authentication handlers are tried regardless) Next, your authentication policy gets involved, understands that you have 4 failures and 1 success and cross-checks your successes with what’s required for that service, if any. If the policy is satisfied, the flow resumes. For this sort of behavior, rather than defining an authentication policy on the authentication manager, you should define a policy factory on the CentralAuthenticationServiceImpl definition:

And this is the policy you need:

The configuration is non-trivial, yes. Might be a good case to update the docs to make that distinction clear.  

If you are implementing “MFA” this way, please note that your client is not actually checking the response it gets back from the server. That’s why it goes through anyway. The server should respond to the client with “here is a list of strategies that were satisfied successfully for you”. The client should ALWAYS cross-check those settings with what it actually needs. You can not simply rely on the server to “protect” you; that is a requirement for ANY mfa deployment, though in this particular case the server just might be enough. 

HTH, 

- Misagh

Misagh Moayyed

unread,
Jun 13, 2016, 3:30:12 PM6/13/16
to cas-...@apereo.org

Share logs please.

 

From: Claude Viéville [mailto:claude....@univ-lille1.fr]
Sent: Monday, June 13, 2016 11:19 AM
To: jasig-cas-user <jasig-c...@googlegroups.com>
Cc: cas-...@apereo.org; mmoa...@unicon.net
Subject: Re: [cas-user] JSON Service for CAS Client does not follow success message of required Handler

 

Hello Community,

 

I would like to continue this discussion as I think I have observed the same behavior.

Cas Version 4.2

Tomcat 8

In my case, Cas is  configured with jpaServiceRegistryDao instead of jsonServiceRegistryDao. 

 

I also have 2 UserNamePasswordHandlers declared in deployerConfigContext.xml (ldapAuthenticationHandler and L1ldapAuthenticationHandler)

<util:map id="authenticationHandlersResolvers">

           <entry key-ref="ldapAuthenticationHandler" value="#{null}" />

           <entry key-ref="L1ldapAuthenticationHandler" value="#{null}" />  

        <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />

    </util:map>


I declared the anyAuthenticationPolicy

<alias name="anyAuthenticationPolicy" alias="authenticationPolicy" />said by 

And this factory :

<alias name="requiredHandlerAuthenticationPolicyFactory" alias="authenticationPolicyFactory" />


Moreover, the boolean tryAll is set to true to enforce PolicyBasedAuthenticationManager to try all the handler before returning.

 

The policy could be written like that : with the credential submitted by the web form, try to authenticate with the two handlers and if, for a given service (let say S) the handler ldapAuthenticationHandler is satisfied then return true

 

But, as Artur said in this thread  the behavior is not the one I hope. Only the first handler is tried and the authentication result is always false.

 

To day,I inspected the code and It seems that I could be an error : the policy returns true only if number of success added to number of failures equals number of credentials BUT NUMBER OF CREDENTIALS IS ALWAYS 1.

 

Do you thing it is an error or I made a misunderstanding.?

 

I followed my investgation by modifying the code of the PolicyBasedAuthenticationManager in order to add to the builder one credential by handler s upporting the credential (in my case 2. And, making that, the authentication process works fine in the different cas I tested !

 

Here is the piece of cod I modified

 

    protected AuthenticationBuilder authenticateInternal(final Collection<Credential> credentials)

            throws AuthenticationException {

          

        final AuthenticationBuilder builder = new DefaultAuthenticationBuilder(NullPrincipal.getInstance());

 

           /* initialize builder with credential only if it is unique  for each handler supporting this type of Credential 

           * as to ensure authentication.credentials.size() == total of authentication attemps !

           */

           if(credentials.size()==1) {

                 Credential credential = (Credential)(credentials.toArray()[0]);

                 for (final Map.Entry<AuthenticationHandler, PrincipalResolver> entry : this.handlerResolverMap.entrySet()) {

                       if(entry.getKey().supports(credential)) builder.addCredential(new BasicCredentialMetaData(credential));

                 }

           } else {

                 for (final Credential c : credentials) {

                  builder.addCredential(new BasicCredentialMetaData(c));

              }

           }

 

Do you think I am in the truth or I am completly wrong ?

 

Thank you for your answer

 

Have a good day,

 

Claude

 

Claude Viéville

unread,
Jun 20, 2016, 10:03:06 AM6/20/16
to CAS Community, mmoa...@unicon.net
Hello Misagh,

Sorry for the delay but I was out of my ofiice these last days.

cas-1.log is the log when the first handler sucesses with "vieville" : in this case the second handler is not runned by the authenticationManager despite of tryAll == true

The policy (AnyAuthenticationPolicy) is always satisfied when tryAll  == true

    @Override
    public boolean isSatisfiedBy(final Authentication authn) {
        if (this.tryAll) {
            return authn.getCredentials().size() == authn.getSuccesses().size() + authn.getFailures().size();
        }
        return !authn.getSuccesses().isEmpty();
    }
cas-2.log is a file log when the first handler is not satisfied. As you can see, a stack error is raised and the authentication fails.

I hope the files  logs may help you understand the behavior
best regards,

Claude
cas-1.log
cas-2.log

Misagh Moayyed

unread,
Jun 21, 2016, 9:48:43 PM6/21/16
to CAS Community

You wrote L1LdapAuthenticationHandler.java, correct? Can you share it as a gist, etc?

 

From: Claude Viéville [mailto:claude....@univ-lille1.fr]
Sent: Monday, June 20, 2016 7:03 AM
To: CAS Community <cas-...@apereo.org>
Cc: mmoa...@unicon.net
Subject: Re: [cas-user] JSON Service for CAS Client does not follow success message of required Handler

 

Hello Misagh,

Claude Viéville

unread,
Jun 22, 2016, 1:55:34 AM6/22/16
to CAS Community, mmoa...@unicon.net

Misagh Moayyed

unread,
Jun 22, 2016, 11:29:18 AM6/22/16
to CAS Community

OK, this got interesting J I was hoping I could blame your handler for doing something weird but offhand I don’t see much. So go ahead and submit and issue please, and attach your overlay to the issues project.

Reply all
Reply to author
Forward
0 new messages