Hi Scott, et al,
Sorry for the long delay.
Some of you have mentioned that the problem I'm having probably has to
do with a credential problem between CAS and AD, but I don't even see
traffic going to the AD, which makes me think something else is wrong
(though I won't be surprised if CAS<->AD winds up being the next
show-stopper).
I've attached the login-webflow.xml file.
Thanks for your help!
Brian
On 10/4/2010 6:52 PM, Scott Battaglia wrote:
> Can you also attach your webflow? I'm not a SPNEGO expert but maybe
> between all of us on the list, we can help :-)
>
> Thanks
> Scott
>
>
> On Mon, Oct 4, 2010 at 9:41 PM, Brian C. Hill <[email protected]
> <mailto:[email protected]>> wrote:
>
> Hello,
>
> I have to admit that with all of the reports of how easy this was
> to set up for all of you, I am surprised that I am having the
> opposite experience: too many files, too many components, too many
> players (kerberos, SSL required between CAS client and CAS server,
> ldap, java, tomcat/jboss, spnego, AD, etc..).
>
> I suppose the biggest frustration is that even with everything set
> to debug, I don't really see any specific errors except for maybe
> this one:
>
> * 2010-10-05 00:47:46,518 DEBUG
> [org.jasig.cas.support.spnego.web.flow.SpnegoNegociateCredentialsAction]
> - Authorization header not found. Sending WWW-Authenticate header
> *
> I do have LDAP auth working, but ...
>
> I don't have SPNEGO working. I've tested it with both Firefox and
> I.E. I try connecting to a simple web page set up with
> mod_auth_cas, which redirects to CAS to get a ticket, which I can
> get with LDAP auth. But with SPNEGO, it seems that the windows
> credentials from my current login (yes, same AD) don't get passed
> to the site and I still get redirected to the CAS server, which
> will then not authenticate me:
>
> * The credentials you provided are not supported by CAS
>
> *With a tcpdump, I don't see the simple web page ask the cas
> server to validate the ticket being presented to it by the browser
> - I guess that means that it isn't getting any such credentials
> from the browser, which causes it to redirect to the cas login page.
>
> Note that I took out the LDAP auth from deployerConfigContext.xml
> to make sure that only SPNEGO would be used.
>
> I set up everything as the SPNEGO page says to.
>
> I suspect that my problem is with one of the following:
>
> 1) <property name="loginConf" value="/WEB-INF/login.conf" />
>
> Does this have to be more explicit, like a full real path?
>
> 2) Kerberos
>
> The keys that my AD admin generated are:
>
> HTTP/<fqdn unix hostname>@<AD Domain>
>
> as opposed to
>
> HTTP/<fqdn unix hostname>@ <kerberos realm>
>
> Will this not work?
>
> 3) I saw a post in which someone came to the conclusion that the
> "user account can't be used for both SPN and binding the LDAP server"
>
> The format isn't the same (the kerberos user is a
> user@<kerberos realm>, LDAP auth user is in DN format), but the
> user they both reference is the same one.
>
> Am I misunderstanding something?
>
> I figure I am getting very close to making this work
> deployerConfigContext.xml is posted below.
>
> Thanks for any help!
>
> Brian
>
>
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>
> <?xml version="1.0" encoding="UTF-8"?>
> <beans xmlns="http://www.springframework.org/schema/beans"
> <http://www.springframework.org/schema/beans>
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> <http://www.w3.org/2001/XMLSchema-instance>
> xmlns:p="http://www.springframework.org/schema/p"
> <http://www.springframework.org/schema/p>
> xmlns:sec="http://www.springframework.org/schema/security"
> <http://www.springframework.org/schema/security>
>
> xsi:schemaLocation="http://www.springframework.org/schema/beans
> http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
> http://www.springframework.org/schema/security
> http://www.springframework.org/schema/security/spring-security-3.0.xsd">
>
> <bean id="authenticationManager"
>
> class="org.jasig.cas.authentication.AuthenticationManagerImpl">
> <property name="credentialsToPrincipalResolvers">
> <list>
> <bean
>
>
> class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver"
> />
> <bean
>
>
> class="org.jasig.cas.support.spnego.authentication.principal.SpnegoCredentialsToPrincipalResolver"
> />
> <bean
>
>
> class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver"
> />
> </list>
> </property>
> <property name="authenticationHandlers">
> <list>
> <bean
>
> class="org.jasig.cas.support.spnego.authentication.handler.support.JCIFSSpnegoAuthenticationHandler">
> <property name="authentication">
> <bean class="jcifs.spnego.Authentication" />
> </property>
> <property name="principalWithDomainName" value="false" />
> <property name="NTLMallowed" value="true"/>
> </bean>
> <bean
>
> class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler">
> <property name="httpClient" ref="httpClient" />
> </bean>
> </list>
> </property>
> </bean>
>
> <sec:user-service id="userDetailsService">
> <sec:user name="battags" password="notused"
> authorities="ROLE_ADMIN" />
> </sec:user-service>
>
> <bean id="attributeRepository"
>
> class="org.jasig.services.persondir.support.StubPersonAttributeDao">
> <property name="backingMap">
> <map>
> <entry key="uid" value="uid" />
> <entry key="eduPersonAffiliation" value="eduPersonAffiliation" />
> <entry key="groupMembership" value="groupMembership" />
> </map>
> </property>
> </bean>
>
> <bean id="serviceRegistryDao"
> class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl" />
>
> <bean name="jcifsConfig"
>
> class="org.jasig.cas.support.spnego.authentication.handler.support.JCIFSConfig">
> <property name="jcifsServicePrincipal"
> value="[email protected]" <mailto:[email protected]> />
> <property name="jcifsServicePassword" value="xxxxx" />
> <property name="kerberosDebug" value="true" />
> <property name="kerberosRealm" value="my.domain.tld" />
> <property name="kerberosKdc" value="ad-server.my.domain.tld" />
> <property name="loginConf" value="/WEB-INF/login.conf" />
> </bean>
>
> </beans>
>
>
> --
> You are currently subscribed [email protected]
> <mailto:[email protected]> as:[email protected]
> <mailto:[email protected]>
>
>
> To unsubscribe, change settings or access archives,
> seehttp://www.ja-sig.org/wiki/display/JSG/cas-user
>
>
> --
> 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
--
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"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
<on-start>
<evaluate expression="initialFlowSetupAction" />
</on-start>
<decision-state id="ticketGrantingTicketExistsCheck">
<if test="flowScope.ticketGrantingTicketId neq null" then="hasServiceCheck" else="gatewayRequestCheck" />
</decision-state>
<!--
<decision-state id="gatewayRequestCheck">
<if test="externalContext.requestParameterMap['gateway'] neq '' && externalContext.requestParameterMap['gateway'] neq null && flowScope.service neq null" then="redirect" else="viewLoginForm" />
</decision-state>
-->
<decision-state id="gatewayRequestCheck">
<if test="externalContext.requestParameterMap['gateway'] neq '' && externalContext.requestParameterMap['gateway'] neq null && flowScope.service neq null" then="redirect" else="startAuthenticate" />
</decision-state>
<decision-state id="hasServiceCheck">
<if test="flowScope.service != null" then="renewRequestCheck" else="viewGenericLoginSuccess" />
</decision-state>
<!--
<decision-state id="renewRequestCheck">
<if test="externalContext.requestParameterMap['renew'] neq '' && externalContext.requestParameterMap['renew'] neq null" then="viewLoginForm" else="generateServiceTicket" />
</decision-state>
-->
<decision-state id="renewRequestCheck">
<if test="externalContext.requestParameterMap['renew'] neq '' && externalContext.requestParameterMap['renew'] neq null" then="startAuthenticate" else="generateServiceTicket" />
</decision-state>
<!--
The "warn" action makes the determination of whether to redirect directly to the requested
service or display the "confirmation" page to go back to the server.
-->
<decision-state id="warn">
<if test="flowScope.warnCookieValue" then="showWarningView" else="redirect" />
</decision-state>
<!--
<action-state id="startAuthenticate">
<action bean="x509Check" />
<transition on="success" to="sendTicketGrantingTicket" />
<transition on="warn" to="warn" />
<transition on="error" to="viewLoginForm" />
</action-state>
-->
<action-state id="startAuthenticate">
<evaluate expression="negociateSpnego" />
<transition on="success" to="spnego" />
</action-state>
<action-state id="spnego">
<evaluate expression="spnego" />
<transition on="success" to="sendTicketGrantingTicket" />
<transition on="error" to="viewLoginForm" />
</action-state>
<view-state id="viewLoginForm" view="casLoginView" model="credentials">
<var name="credentials" class="org.jasig.cas.authentication.principal.UsernamePasswordCredentials" />
<binder>
<binding property="username" />
<binding property="password" />
</binder>
<on-entry>
<set name="viewScope.commandName" value="'credentials'" />
</on-entry>
<transition on="submit" bind="true" validate="true" to="realSubmit">
<set name="flowScope.credentials" value="credentials" />
<evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credentials)" />
</transition>
</view-state>
<action-state id="realSubmit">
<evaluate expression="authenticationViaFormAction.submit(flowRequestContext, flowScope.credentials, messageContext)" />
<transition on="warn" to="warn" />
<transition on="success" to="sendTicketGrantingTicket" />
<transition on="error" to="viewLoginForm" />
</action-state>
<action-state id="sendTicketGrantingTicket">
<evaluate expression="sendTicketGrantingTicketAction" />
<transition to="serviceCheck" />
</action-state>
<decision-state id="serviceCheck">
<if test="flowScope.service neq null" then="generateServiceTicket" else="viewGenericLoginSuccess" />
</decision-state>
<action-state id="generateServiceTicket">
<evaluate expression="generateServiceTicketAction" />
<transition on="success" to ="warn" />
<transition on="error" to="viewLoginForm" />
<transition on="gateway" to="redirect" />
</action-state>
<action-state id="redirect">
<evaluate expression="flowScope.service.getResponse(requestScope.serviceTicketId)" result-type="org.jasig.cas.authentication.principal.Response" result="requestScope.response" />
<transition on="requestScope.response" to="postView" />
<transition to="redirectView" />
</action-state>
<!--
the "viewGenericLogin" is the end state for when a user attempts to login without coming directly from a service.
They have only initialized their single-sign on session.
-->
<end-state id="viewGenericLoginSuccess" view="casLoginGenericSuccessView" />
<!--
The "showWarningView" end state is the end state for when the user has requested privacy settings (to be "warned") to be turned on. It delegates to a
view defines in default_views.properties that display the "Please click here to go to the service." message.
-->
<end-state id="showWarningView" view="casLoginConfirmView" />
<end-state id="postView" view="postResponseView">
<output name="viewScope.parameters" value="requestScope.response.attributes" />
<output name="viewScope.originalUrl" value="flowScope.service.id" />
</end-state>
<!--
The "redirect" end state allows CAS to properly end the workflow while still redirecting
the user back to the service required.
-->
<end-state id="redirectView" view="externalRedirect:${requestScope.response.url}" />
<end-state id="viewServiceErrorView" view="viewServiceErrorView" />
<end-state id="viewServiceSsoErrorView" view="viewServiceSsoErrorView" />
<global-transitions>
<transition to="viewServiceErrorView" on-exception="org.springframework.webflow.execution.repository.NoSuchFlowExecutionException" />
<transition to="viewServiceSsoErrorView" on-exception="org.jasig.cas.services.UnauthorizedSsoServiceException" />
<transition to="viewServiceErrorView" on-exception="org.jasig.cas.services.UnauthorizedServiceException" />
</global-transitions>
</flow>