Thank you all for your suggestions and help.  I touch CAS maybe once a year
when changes are needed, so I'm not very savvy.

By setting the log values to TRACE I was able to determine that CAS was
never initiating the ldap search (as Daniel pointed out) and figure out
what was causing that.

The authentication *succeeded* after the following:
1) Using the 2nd option (LDAP Requiring Authenticated Search), and fixing
differences in the sample code and my cas.properties file (e.g.
ldap.managerDn vs ldap.authn.managerDn)
2) changing the the managerDN to the [email protected] -- in the
3.5.2 installation, I used the full CN=CASADMIN, etc...
3) setting useStartTLS=false
4) setting searchFilter to (sAMAccountName={user}) -- anything else seems
to fail

The response from the server (in catalina.out) contains all the attributes
I'm hoping to get (and then some), so it seems that the attribute mapping
is working as well.  I'll find out more when I modify the authorization
plugins for our external apps to pull the CAS attributes list.

*SSL*
It seems that disabling/enabling the sslConfig bean makes no difference in
my config; the certs are stored in the default keystore as well, so both
methods build and authenticate.

In the interest of helping fellow Google searchers down the road, I've
attached my LDAP properties section of the cas.properties file below:

#========================================
# General properties
#========================================
ldap.url=ldaps://id.fuller.edu
# LDAP connection timeout in milliseconds
ldap.connectTimeout=3000
# Whether to use StartTLS (probably needed if not SSL connection)
ldap.useStartTLS=false
#========================================
# LDAP connection pool configuration
#========================================
ldap.pool.minSize=3
ldap.pool.maxSize=10
ldap.pool.validateOnCheckout=false
ldap.pool.validatePeriodically=true
ldap.pool.blockWaitTime=3000
ldap.pool.validatePeriod=300
ldap.pool.prunePeriod=300
ldap.pool.idleTime=600
#========================================
# Authentication
#========================================
# Base DN of users to be authenticated
ldap.baseDn=ou=fuller,DC=id,DC=fuller,DC=edu
# Manager DN for authenticated searches
[email protected]
# Manager password for authenticated searches
ldap.authn.managerPassword=admin_password
# Search filter used for configurations that require searching for DNs
ldap.authn.searchFilter=(sAMAccountName={user})
# Domain Setting
ldap.domain=fuller.edu
ldap.trustedCert=file:/etc/cas/id_app.pem

and am attaching my current deployerConfigContext.xml file to this email.

Thanks again,

Mike


On Tue, Jun 30, 2015 at 3:27 PM, Mike Seiler <[email protected]>
wrote:

> Thank you Mihai and John.
>
> I will try those things first thing in the morning and get back to you
> with all the additional logs and details.
>
> Mike
>
> On Tue, Jun 30, 2015 at 3:22 PM, John Ryan <[email protected]> wrote:
>
>>  Mike,
>>
>> I think Daniel is on to something: we see no indication whatsoever in
>> your log output that LDAP authentication is even being attempted.  In your
>> log4j.xml please dial way back everything (most especially
>> org.springframework) to WARN except org.jasig and org.ldaptive (set both
>> to TRACE).  After you attempt to hit a CAS-ified application, we should
>> then see a rich set of detail about CAS placing a service in FlowScope,
>> generating a login ticket, etc.
>>
>> If everything is OK up to that point, we'll see an "Attempting LDAP
>> authentication" message from
>> org.jasig.cas.authentication.LdapAuthenticationHandler, followed by rich
>> detail from org.ldaptive components as they interact with AD.
>>
>> FYI we're using CAS 4.0 with AD and it is working fine.  The only
>> differences that jump out to me from our configuration is that we don't use
>> any of the ldap.authn properties at all, as we want to use the user's
>> sAMAccountName.
>>
>> Also, one departure from the deployerConfigContext.xml at
>> http://jasig.github.io/cas/4.0.x/installation/LDAP-Authentication.html#active_directory_authentication
>> is that we do not use an sslConfig bean.  We use ldaps, the cert for our AD
>> server is in the JVM's keystore, and things seem to work just fine without
>> the sslConfig bean.
>>
>> But again, we see no indication an attempt at LDAP authentication is even
>> being attempted.  Updating log4j.xml with the suggested changes should at
>> least make that clear.
>>
>> On 6/29/2015 9:26 PM, Daniel Fisher wrote:
>>
>>  On Mon, Jun 29, 2015 at 1:28 PM, Mike Seiler <[email protected]>
>> wrote:
>>
>>> Any further suggestions on what might be causing the system to fail to
>>> authenticate users?
>>>
>>>  Bind with manager password works. Certificates validate.
>>> sAMAccountName is set as the search filter.
>>>
>>>  Any suggestions would be appreciated.
>>>
>>
>>  I didn't see the LDAP authentication component being exercised. Your
>> LDAP pools initialize correctly, but the authentication handler does not
>> appear to use them. I don't know enough about the v4 config to say what's
>> wrong, but I would look for something fundamental in the authentication
>> wiring, not in the LDAP config.
>>
>>  --Daniel Fisher
>>
>>   --
>> You are currently subscribed to [email protected] as: [email protected]
>> To unsubscribe, change settings or access archives, see 
>> http://www.ja-sig.org/wiki/display/JSG/cas-user
>>
>>
>> --
>>  John Ryan  / Senior Software Engineer /  RedZone Software
>> [email protected]  /  www.redzone.co
>>
>> --
>> You are currently subscribed to [email protected] as: 
>> [email protected]
>> To unsubscribe, change settings or access archives, see 
>> http://www.ja-sig.org/wiki/display/JSG/cas-user
>>
>>
>> This transmission contains confidential information intended solely for
>> the party identified above. If you receive this message in error, you must
>> not use it or convey it to others. Please destroy it immediately and
>> contact the sender at (303) 386-3955 or by return e-mail to the sender.
>
>
>
>
> --
> *Michael Seiler*
> --------------------------------------------------
> Systems Integration Engineer
> Fuller Theological Seminary
> Phone: (970) 306-6105
> [email protected]
>
> *Fuller Summer Hours:* Please note that all Fuller offices will be closed
> on Fridays from 7/3-8/28
> *Mike's Vacation Notice:* From 7/3-8/28 I will also be taking Mondays
> off, and will be out of the office for vacation 7/31 - 8/31
>
> *Please NOTE:*
> I respond to email at 8 AM, 1PM, and at 4:30PM.  If you need more
> immediate help, please contact TSS (626.584.5675) and they can route the
> issue to the appropriate person.  If this is a business process life or
> death emergency, you may call me at the above number.
>



-- 
*Michael Seiler*
--------------------------------------------------
Systems Integration Engineer
Fuller Theological Seminary
Phone: (970) 306-6105
[email protected]

*Fuller Summer Hours:* Please note that all Fuller offices will be closed
on Fridays from 7/3-8/28
*Mike's Vacation Notice:* From 7/3-8/28 I will also be taking Mondays off,
and will be out of the office for vacation 7/31 - 8/31

*Please NOTE:*
I respond to email at 8 AM, 1PM, and at 4:30PM.  If you need more immediate
help, please contact TSS (626.584.5675) and they can route the issue to the
appropriate person.  If this is a business process life or death emergency,
you may call me at the above number.

-- 
You are currently subscribed to [email protected] as: 
[email protected]
To unsubscribe, change settings or access archives, see 
http://www.ja-sig.org/wiki/display/JSG/cas-user
<?xml version="1.0" encoding="UTF-8"?>
<!--

    Licensed to Jasig under one or more contributor license
    agreements. See the NOTICE file distributed with this work
    for additional information regarding copyright ownership.
    Jasig licenses this file to you under the Apache License,
    Version 2.0 (the "License"); you may not use this file
    except in compliance with the License.  You may obtain a
    copy of the License at the following location:

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

-->
<beans xmlns="http://www.springframework.org/schema/beans";
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
       xmlns:p="http://www.springframework.org/schema/p";
       xmlns:c="http://www.springframework.org/schema/c";
       xmlns:tx="http://www.springframework.org/schema/tx";
       xmlns:util="http://www.springframework.org/schema/util";
       xmlns:sec="http://www.springframework.org/schema/security";
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd";>

    <bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
        <constructor-arg>
            <map>
                <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
                <entry key-ref="ldapAuthenticationHandler" value-ref="primaryPrincipalResolver" />
            </map>
        </constructor-arg>
        <property name="authenticationPolicy">
            <bean class="org.jasig.cas.authentication.AnyAuthenticationPolicy" />
        </property>
    </bean>

    <!-- Required for proxy ticket mechanism. -->
    <bean id="proxyAuthenticationHandler"
          class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
          p:httpClient-ref="httpClient" />

    <bean id="primaryAuthenticationHandler"
          class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
        <property name="users">
            <map>
                <entry key="casuser" value="Mellon"/>
            </map>
        </property>
    </bean>

    <!-- Required for proxy ticket mechanism -->
    <bean id="proxyPrincipalResolver"
          class="org.jasig.cas.authentication.principal.BasicPrincipalResolver" />

    <!--
       | Resolves a principal from a credential using an attribute repository that is configured to resolve
       | against a deployer-specific store (e.g. LDAP).
       -->
    <bean id="primaryPrincipalResolver"
          class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" >
        <property name="attributeRepository" ref="attributeRepository" />
    </bean>

    <!--
    Bean that defines the attributes that a service may return.  This example uses the Stub/Mock version.  A real implementation
    may go against a database or LDAP server.  The id should remain "attributeRepository" though.
    +-->
    <bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao"
            p:backingMap-ref="attrRepoBackingMap" />
    
    <util:map id="attrRepoBackingMap">
        <entry key="uid" value="uid" />
        <entry key="eduPersonAffiliation" value="eduPersonAffiliation" /> 
        <entry key="groupMembership" value="groupMembership" />
    </util:map>

    <!-- 
    Sample, in-memory data store for the ServiceRegistry. A real implementation
    would probably want to replace this with the JPA-backed ServiceRegistry DAO
    The name of this bean should remain "serviceRegistryDao".
    +-->
    <bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl"
            p:registeredServices-ref="registeredServicesList" />

    <util:list id="registeredServicesList">
        <bean class="org.jasig.cas.services.RegexRegisteredService"
              p:id="0" p:name="HTTP and IMAP" p:description="Allows HTTP(S) and IMAP(S) protocols"
              p:serviceId="^(https?|imaps?)://.*" p:evaluationOrder="10000001" />
        <!--
        Use the following definition instead of the above to further restrict access
        to services within your domain (including sub domains).
        Note that example.com must be replaced with the domain you wish to permit.
        This example also demonstrates the configuration of an attribute filter
        that only allows for attributes whose length is 3.
        -->
        <!--
        <bean class="org.jasig.cas.services.RegexRegisteredService">
            <property name="id" value="1" />
            <property name="name" value="HTTP and IMAP on example.com" />
            <property name="description" value="Allows HTTP(S) and IMAP(S) protocols on example.com" />
            <property name="serviceId" value="^(https?|imaps?)://([A-Za-z0-9_-]+\.)*example\.com/.*" />
            <property name="evaluationOrder" value="0" />
            <property name="attributeFilter">
              <bean class="org.jasig.cas.services.support.RegisteredServiceRegexAttributeFilter" c:regex="^\w{3}$" /> 
            </property>
        </bean>
        -->
    </util:list>
    
    <bean id="auditTrailManager" class="com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager" />
    
    <bean id="healthCheckMonitor" class="org.jasig.cas.monitor.HealthCheckMonitor" p:monitors-ref="monitorsList" />
  
    <util:list id="monitorsList">
      <bean class="org.jasig.cas.monitor.MemoryMonitor" p:freeMemoryWarnThreshold="10" />
      <!--
        NOTE
        The following ticket registries support SessionMonitor:
          * DefaultTicketRegistry
          * JpaTicketRegistry
        Remove this monitor if you use an unsupported registry.
      -->
      <bean class="org.jasig.cas.monitor.SessionMonitor"
          p:ticketRegistry-ref="ticketRegistry"
          p:serviceTicketCountWarnThreshold="5000"
          p:sessionCountWarnThreshold="100000" />
    </util:list>
<!-- INSERT CONFIGURATIONS HERE -->
<bean id="ldapAuthenticationHandler"
      class="org.jasig.cas.authentication.LdapAuthenticationHandler"
      p:principalIdAttribute="mail"
      c:authenticator-ref="authenticator">
    <property name="principalAttributeMap">
        <map>
            <!--
               | This map provides a simple attribute resolution mechanism.
               | Keys are LDAP attribute names, values are CAS attribute names.
               | Use this facility instead of a PrincipalResolver if LDAP is
               | the only attribute source.
               -->
            <entry key="memberOf" value="memberOf" />
            <entry key="mail" value="mail" />
            <entry key="displayName" value="displayName" />
        </map>
    </property>
</bean>

<bean id="authenticator" class="org.ldaptive.auth.Authenticator"
      c:resolver-ref="dnResolver"
      c:handler-ref="authHandler" />

<bean id="dnResolver" class="org.ldaptive.auth.PooledSearchDnResolver"
      p:baseDn="${ldap.baseDn}"
      p:subtreeSearch="true"
      p:allowMultipleDns="false"
      p:connectionFactory-ref="searchPooledLdapConnectionFactory"
      p:userFilter="${ldap.authn.searchFilter}" />

<bean id="searchPooledLdapConnectionFactory"
      class="org.ldaptive.pool.PooledConnectionFactory"
      p:connectionPool-ref="searchConnectionPool" />

<bean id="searchConnectionPool" parent="abstractConnectionPool"
      p:connectionFactory-ref="searchConnectionFactory" />

<bean id="searchConnectionFactory"
      class="org.ldaptive.DefaultConnectionFactory"
      p:connectionConfig-ref="searchConnectionConfig" />

<bean id="searchConnectionConfig" parent="abstractConnectionConfig"
      p:connectionInitializer-ref="bindConnectionInitializer" />

<bean id="bindConnectionInitializer"
      class="org.ldaptive.BindConnectionInitializer"
      p:bindDn="${ldap.authn.managerDn}">
    <property name="bindCredential">
        <bean class="org.ldaptive.Credential"
              c:password="${ldap.authn.managerPassword}" />
    </property>
</bean>

<bean id="abstractConnectionPool" abstract="true"
      class="org.ldaptive.pool.BlockingConnectionPool"
      init-method="initialize"
      p:poolConfig-ref="ldapPoolConfig"
      p:blockWaitTime="${ldap.pool.blockWaitTime}"
      p:validator-ref="searchValidator"
      p:pruneStrategy-ref="pruneStrategy" />

<bean id="abstractConnectionConfig" abstract="true"
      class="org.ldaptive.ConnectionConfig"
      p:ldapUrl="${ldap.url}"
      p:connectTimeout="${ldap.connectTimeout}"
      p:useStartTLS="${ldap.useStartTLS}"
      p:sslConfig-ref="sslConfig" />

<bean id="ldapPoolConfig" class="org.ldaptive.pool.PoolConfig"
      p:minPoolSize="${ldap.pool.minSize}"
      p:maxPoolSize="${ldap.pool.maxSize}"
      p:validateOnCheckOut="${ldap.pool.validateOnCheckout}"
      p:validatePeriodically="${ldap.pool.validatePeriodically}"
      p:validatePeriod="${ldap.pool.validatePeriod}" />

<bean id="sslConfig" class="org.ldaptive.ssl.SslConfig">
    <property name="credentialConfig">
        <bean class="org.ldaptive.ssl.X509CredentialConfig"
              p:trustCertificates="${ldap.trustedCert}" />
    </property>
</bean>

<bean id="pruneStrategy" class="org.ldaptive.pool.IdlePruneStrategy"
      p:prunePeriod="${ldap.pool.prunePeriod}"
      p:idleTime="${ldap.pool.idleTime}" />

<bean id="searchValidator" class="org.ldaptive.pool.SearchValidator" />

<bean id="authHandler" class="org.ldaptive.auth.PooledBindAuthenticationHandler"
      p:connectionFactory-ref="bindPooledLdapConnectionFactory" />

<bean id="bindPooledLdapConnectionFactory"
      class="org.ldaptive.pool.PooledConnectionFactory"
      p:connectionPool-ref="bindConnectionPool" />

<bean id="bindConnectionPool" parent="abstractConnectionPool"
      p:connectionFactory-ref="bindConnectionFactory" />

<bean id="bindConnectionFactory"
      class="org.ldaptive.DefaultConnectionFactory"
      p:connectionConfig-ref="bindConnectionConfig" />

<bean id="bindConnectionConfig" parent="abstractConnectionConfig" />
</beans>

Reply via email to