cancel
Showing results for 
Search instead for 
Did you mean: 

Alfresco integration with CAS with Acegi

escaglia
Champ in-the-making
Champ in-the-making
Hello everybody,
we'd like to submit you the way we integrated Alfresco with our CAS, asking you for help on (at least) a couple of doubts we have.
The relevant part of web.xml we used is:

<filter>          <filter-name>Acegi CAS Processing Filter</filter-name>          <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>          <init-param>            <param-name>targetClass</param-name>           <param-value>net.sf.acegisecurity.util.FilterChainProxy</param-value>          </init-param></filter>       <filter-mapping>          <filter-name>Acegi CAS Processing Filter</filter-name>          <url-pattern>/*</url-pattern></filter-mapping>‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The file authentication-services-context.xml we used is:

<beans>    <!–                                                                    –>    <!– The Acegi authentication manager.                                  –>    <!–                                                                    –>    <!– Provders are asked to authenticate in order.                       –>    <!– First, is a provider that checks if an acegi authentication object –>    <!– is already bound to the executing thread. If it is, and it is set  –>    <!– as authenticated then no further authentication is required. If    –>    <!– this is absent, Acegi validates the password for every method      –>    <!– invocation, which is too CPU expensive. If we set an               –>    <!– authentication based on a ticket etc …. or we want to set the    –>    <!– the system user as the current user … we do not have the         –>    <!– password. So if we have set an authentication and set it as        –>    <!– authenticated that is sufficient to validate the user.             –>    <!–                                                                    –>    <!– If the authentication bound to the current thread is not set as    –>    <!– authenticated the standard Acegi DAO Authentication provider       –>    <!– is used to authenticate.                                           –>    <!–                                                                    –>   <bean id="filterChainProxy" class="net.sf.acegisecurity.util.FilterChainProxy">      <property name="filterInvocationDefinitionSource">         <value>          CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON          PATTERN_TYPE_APACHE_ANT            /faces/**=Cas2AlfrescoContextIntegrationFilter,securityEnforcementFilter            /j_acegi_cas_security_check**=Cas2AlfrescoContextIntegrationFilter,casProcessingFilter         </value>      </property>    </bean>    <bean id="Cas2AlfrescoContextIntegrationFilter" class="org.alfresco.web.app.servlet.Cas2AlfrescoContextIntegrationFilter">        <property name="context"><value>net.sf.acegisecurity.context.security.SecureContextImpl</value></property>     </bean>     <bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">        <property name="providers">            <list>                <ref bean="authenticatedAuthenticationPassthroughProvider" />                <ref bean="casAuthenticationProvider" />            </list>        </property>    </bean>   <bean id="serviceProperties" class="net.sf.acegisecurity.ui.cas.ServiceProperties">     <property name="service"><value>http://pc29029.csi.it:8080/alfresco/j_acegi_cas_security_check</value></property>     <property name="sendRenew"><value>false</value></property>   </bean>   <bean id="casProcessingFilter" class="net.sf.acegisecurity.ui.cas.CasProcessingFilter">     <property name="authenticationManager"><ref bean="authenticationManager"/></property>     <property name="authenticationFailureUrl"><value>/casfailed.jsp</value></property>     <property name="defaultTargetUrl"><value>/</value></property>     <property name="filterProcessesUrl"><value>/j_acegi_cas_security_check</value></property>   </bean>   <bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">        <property name="authenticationEntryPoint"><ref bean="casProcessingFilterEntryPoint"/></property>      <property name="filterSecurityInterceptor" ref="filterInvocationInterceptor"/>    </bean>   <bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">        <property name="authenticationManager"><ref bean="authenticationManager"/></property>        <property name="accessDecisionManager"><ref bean="httpRequestAccessDecisionManager"/></property><!–<ref bean="accessDecisionManager"/></property–>        <property name="objectDefinitionSource">            <value>CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISONPATTERN_TYPE_APACHE_ANT/**=ROLE_AUTHENTICATED            </value>        </property>    </bean>   <bean id="httpRequestAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">      <property name="allowIfAllAbstainDecisions"><value>false</value></property>      <property name="decisionVoters">         <list><ref bean="roleVoter"/></list>      </property>   </bean>    <!– ~~~~~~~~~~~~~~~~~~~~ AUTHORIZATION DEFINITIONS ~~~~~~~~~~~~~~~~~~~ –>    <!– An access decision voter that reads ROLE_* configuaration settings –>    <!– <bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/> –>    <!– <bean id="ACLEntryVoter" class="org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoter"/> –>    <!– An access decision manager used by the business objects –>       <bean id="casProcessingFilterEntryPoint" class="net.sf.acegisecurity.ui.cas.CasProcessingFilterEntryPoint">     <property name="loginUrl"><value>https://cstvip01.csi.it/ssobart/login</value></property>     <property name="serviceProperties"><ref bean="serviceProperties"/></property>   </bean>   <bean id="casAuthenticationProvider" class="net.sf.acegisecurity.providers.cas.CasAuthenticationProvider">     <property name="casAuthoritiesPopulator"><ref bean="casAuthoritiesPopulator"/></property>     <property name="casProxyDecider"><ref bean="casProxyDecider"/></property>     <property name="ticketValidator"><ref bean="casProxyTicketValidator"/></property>     <property name="statelessTicketCache"><ref bean="statelessTicketCache"/></property>     <property name="key"><value>my_password_for_this_auth_provider_only</value></property>   </bean>      <bean id="casProxyTicketValidator" class="net.sf.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator">     <property name="casValidate"><value>http://alessandria.cst-alessandria.csi.it/ssobart/serviceValidate</value></property>     <property name="proxyCallbackUrl"><value>https://localhost:8443/contacts-cas/casProxy/receptor</value></property>     <property name="serviceProperties"><ref bean="serviceProperties"/></property>     <!– <property name="trustStore"><value>/some/path/to/your/lib/security/cacerts</value></property> –>   </bean>      <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">     <property name="configLocation">       <value>classpath:/ehcache-failsafe.xml</value>     </property>   </bean>          <bean id="ticketCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">     <property name="cacheManager">       <ref local="cacheManager"/>     </property>     <property name="cacheName">       <value>ticketCache</value>     </property>   </bean>         <bean id="statelessTicketCache" class="net.sf.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache">     <property name="cache"><ref local="ticketCacheBackend"/></property>   </bean>      <bean id="casAuthoritiesPopulator" class="net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator">     <property name="authenticationDao"><ref bean="alfDaoImpl"/></property>   </bean>      <bean id="casProxyDecider" class="net.sf.acegisecurity.providers.cas.proxy.RejectProxyTickets"/>    <bean id="inMemoryDaoImpl" class="org.alfresco.repo.security.authentication.InMemoryDaoImpl">        <property name="userMap">            <value>               AAAAAA00B77B000F=***,ROLE_ADMIN                admin=***,ROLE_ADMIN                    gcs=***,ROLE_ADMIN                mc=***,ROLE_ADMIN,ROLE_TELLER,ROLE_SUPERVISOR                    peter=***,disabled,ROLE_TELLER            </value>        </property>    </bean>    <!– We provide a DAO to plug into the Acegi DaoAuthenticationProvider  –>    <bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">        <property name="authenticationDao">            <ref bean="authenticationDao" />        </property>        <property name="saltSource">            <ref bean="saltSource" />        </property>        <property name="passwordEncoder">            <ref bean="passwordEncoder" />        </property>    </bean>    <!– An authentication Provider that just believes authentications      –>    <!– bound to the local thread are valid if they are set as             –>    <!– authenticated.                                                     –>    <bean id="authenticatedAuthenticationPassthroughProvider" class="org.alfresco.repo.security.authentication.AuthenticatedAuthenticationPassthroughProvider" />    <!– The authroity DAO implements an interface extended from the Acegi  –>    <!– DAO that supports CRUD.                                            –>    <bean id="alfDaoImpl" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">        <property name="proxyInterfaces">            <value>org.alfresco.repo.security.authentication.MutableAuthenticationDao</value>        </property>        <property name="transactionManager">            <ref bean="transactionManager" />        </property>        <property name="target">            <ref bean="authenticationDao"/>        </property>        <property name="transactionAttributes">            <props>                <prop key="*">${server.transaction.mode.default}</prop>            </props>        </property>    </bean>        <bean id="authenticationDao" class="org.alfresco.repo.security.authentication.RepositoryAuthenticationDao">       <property name="nodeService">           <ref bean="nodeService" />       </property>       <property name="dictionaryService">           <ref bean="dictionaryService" />       </property>       <property name="namespaceService">           <ref bean="namespaceService" />       </property>       <property name="searchService">           <ref bean="searchService" />       </property>       <property name="userNamesAreCaseSensitive">          <value>${user.name.caseSensitive}</value>       </property>       <property name="passwordEncoder">           <ref bean="passwordEncoder" />       </property>    </bean>    <!– The DAO also acts as a salt provider.                              –>        <alias alias="saltSource" name="alfDaoImpl"/>    <!– Passwords are encoded using MD4                                    –>    <!– This is not ideal and only done to be compatible with NTLM         –>    <!– authentication against the default authentication mechanism.       –>    <bean id="passwordEncoder" class="org.alfresco.repo.security.authentication.MD4PasswordEncoderImpl"></bean>    <!– A transactional wrapper around the implementation.                 –>    <!– TODO: This should be removed.                                      –>                  <bean id="authenticationService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">        <property name="proxyInterfaces">            <value>org.alfresco.service.cmr.security.AuthenticationService</value>        </property>        <property name="transactionManager">            <ref bean="transactionManager" />        </property>        <property name="target">            <ref bean="authenticationServiceImpl" />        </property>        <property name="transactionAttributes">            <props>                <prop key="*">${server.transaction.mode.default}</prop>            </props>        </property>    </bean>    <!– The Authentication Service implementation.                         –>    <!–                                                                    –>    <!– This delegates its work to two services:                           –>    <!– an AuthenticationComponent and a MutableAuthenticationDAO.         –>    <!–                                                                    –>    <!– The permissions service is required so that permissions can be     –>    <!– cleaned up when a user is deleted.                                 –>        <bean id="authenticationServiceImpl" class="org.alfresco.repo.security.authentication.AuthenticationServiceImpl">        <property name="authenticationDao">            <ref bean="authenticationDao" />        </property>        <property name="ticketComponent">            <ref bean="ticketComponent" />        </property>        <property name="authenticationComponent">            <ref bean="authenticationComponentImpl" />        </property>    </bean>    <!– A transactional wrapper that should be removed.                    –>    <bean id="authenticationComponent" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">        <property name="proxyInterfaces">            <value>org.alfresco.repo.security.authentication.AuthenticationComponent</value>        </property>        <property name="transactionManager">            <ref bean="transactionManager" />        </property>        <property name="target">            <ref bean="authenticationComponentImpl" />        </property>        <property name="transactionAttributes">            <props>                <prop key="*">${server.transaction.mode.default}</prop>            </props>        </property>    </bean>    <!– The authentication component.                                      –>    <bean id="authenticationComponentImpl" class="org.alfresco.repo.security.authentication.AuthenticationComponentImpl">        <property name="authenticationDao">            <ref bean="authenticationDao" />        </property>        <property name="authenticationManager">            <ref bean="authenticationManager" />        </property>        <property name="allowGuestLogin">            <value>true</value>        </property>    </bean>        <!– Simple Authentication component that rejects all authentication requests –>    <!– Use this defintion for Novell IChain integration.                        –>    <!– It should never go to the login screen  so this is not required          –>    <!– (Enterprise version only)                                                –>        <!–    <bean id="authenticationComponentImpl" class="org.alfresco.repo.security.authentication.SimpleAcceptOrRejectAllAuthenticationComponentImpl">    </bean>    –>    <!– The person service.                                                –>    <bean id="personService" class="org.alfresco.repo.security.person.PersonServiceImpl">      <property name="nodeService">          <ref bean="nodeService" />      </property>      <property name="searchService">          <ref bean="searchService" />      </property>      <property name="permissionServiceSPI">         <ref bean="permissionServiceImpl" />      </property>        <property name="authorityService">           <ref bean="authorityService" />        </property>      <property name="namespacePrefixResolver">         <ref bean="namespaceService" />      </property>        <!– Configurable properties.                                 –>        <!–                                                          –>        <!– TODO:                                                    –>        <!– Add support for creating real home spaces adn setting    –>        <!– permissions on the hame space and people created.        –>        <!–                                                          –>        <!– The store in which people are persisted.                 –>        <property name="storeUrl">           <value>${spaces.store}</value>        </property>        <!– The path to the company home space, used to set the      –>        <!– default home space for users that are created if         –>        <!– missing.                                                 –>         <property name="companyHomePath">           <value>/${spaces.company_home.childname}</value>        </property>        <!– Some authentication mechanisms may need to create people –>        <!– in the repository on demand. This enables that feature.  –>        <!– If dsiabled an error will be generated for missing       –>        <!– people. If enabled then a person will be created and     –>        <!– persisted.                                               –>        <!–                                                          –>        <!– This value should be false or only true if the           –>        <!– repository is mutable; set from the property             –>        <!– ${server.transaction.allow-writes}                       –>        <property name="createMissingPeople">           <value>${server.transaction.allow-writes}</value>        </property>        <!– Set is user names are case sensitive - taken from the    –>        <!– repository wide setting - you are advised not to change  –>        <!– this setting.                                            –>        <!– This value should be ${user.name.caseSensitive}          –>        <property name="userNamesAreCaseSensitive">           <value>${user.name.caseSensitive}</value>        </property>    </bean>    <!– The ticket component.                                              –>    <!– Used for reauthentication                                          –>    <bean id="ticketComponent" class="org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl">        <!– The period for which tickets are valid in XML duration format. –>        <!– The default is P1H for one hour.                               –>        <property name="validDuration">            <value>P1H</value>        </property>        <!– Do tickets expire or live for ever?                            –>        <property name="ticketsExpire">            <value>false</value>        </property>        <!– Are tickets only valid for a single use?                       –>        <property name="oneOff">            <value>false</value>        </property>    </bean>    </beans>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

We used the class FilterToBeanProxy to make spring load the class FilterChainProxy which can apply a filter chain.

We used the filter Cas2AlfrescoContextIntegrationFilter which extends from net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter to put into session the object ACEGI_SECURITY_CONTEXT and the ticket _alfAuthTicket.
ACEGI_SECURITY_CONTEXT is a SecureContextImpl containing as a property CasAuthenticationToken, result of the Cas authentication process. _alfAuthTicket instead contains org.alfresco.web.bean.repository.User, object required by Alfresco after authentication.

We didn't use InMemoryDaoImpl but we used Alfresco alfDaoImpl bean as the Alfresco user store. This means that a user, beside existing in the Cas repository, must be priorly created by an admin user in Alfresco.
First question: is there a way to force user creation at first login?

Here is the code of our class:
Cas2AlfrescoContextIntegrationFilter
package org.alfresco.web.app.servlet;import net.sf.acegisecurity.context.Context;import net.sf.acegisecurity.context.ContextHolder;import net.sf.acegisecurity.context.security.SecureContextImpl;import org.alfresco.model.ContentModel;import org.alfresco.service.ServiceRegistry;import org.alfresco.service.cmr.repository.NodeRef;import org.alfresco.service.cmr.repository.NodeService;import org.alfresco.service.cmr.security.AuthenticationService;import org.alfresco.service.cmr.security.PersonService;import org.alfresco.service.transaction.TransactionService;import org.alfresco.web.bean.repository.User;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.context.support.WebApplicationContextUtils;import java.io.IOException;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import javax.transaction.UserTransaction;public class Cas2AlfrescoContextIntegrationFilter extends net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter {    //~ Static fields/initializers =============================================    protected static final Log logger = LogFactory.getLog(Cas2AlfrescoContextIntegrationFilter.class);    private static final String FILTER_APPLIED = "__acegi_session_integration_filter_applied";    public static final String ACEGI_SECURITY_CONTEXT_KEY = "ACEGI_SECURITY_CONTEXT";    public static final String ALF_SECURITY_CONTEXT_KEY = "_alfAuthTicket";    //~ Instance fields ========================================================    private Object contextObject;    /**     * Indicates if this filter can create a HttpSession if needed     * (sessions are always created sparingly, but setting this value to false     * will prohibit sessions from ever being created). Defaults to true.     */    private boolean allowSessionCreation = true;    //~ Methods ================================================================    public void doFilter(ServletRequest request, ServletResponse response,        FilterChain chain) throws IOException, ServletException {        if ((request != null) && (request.getAttribute(FILTER_APPLIED) != null)) {            // ensure that filter is only applied once per request            chain.doFilter(request, response);        } else {            if (request != null) {                request.setAttribute(FILTER_APPLIED, Boolean.TRUE);            }            if (ContextHolder.getContext() != null) {                if (logger.isWarnEnabled()) {                    logger.warn(                        "ContextHolder should have been null but contained: '"                        + ContextHolder.getContext() + "'; setting to null now");                }                ContextHolder.setContext(null);            }            HttpSession httpSession = null;            boolean httpSessionExistedAtStartOfRequest = false;            try {                httpSession = ((HttpServletRequest) request).getSession(false);            } catch (IllegalStateException ignored) {}            if (httpSession != null) {                httpSessionExistedAtStartOfRequest = true;                Object contextObject = httpSession.getAttribute(ACEGI_SECURITY_CONTEXT_KEY);                if (contextObject != null) {                    if (contextObject instanceof Context) {                        if (logger.isDebugEnabled()) {                            logger.debug(                                "Obtained from ACEGI_SECURITY_CONTEXT a valid Context and set to ContextHolder: '"                                + contextObject + "'");                        }                        ContextHolder.setContext((Context) contextObject);                    } else {                        if (logger.isWarnEnabled()) {                            logger.warn(                                "ACEGI_SECURITY_CONTEXT did not contain a Context but contained: '"                                + contextObject                                + "'; are you improperly modifying the HttpSession directly (you should always use ContextHolder) or using the HttpSession attribute reserved for this class?");                        }                    }                } else {                    if (logger.isDebugEnabled()) {                        logger.debug(                            "HttpSession returned null object for ACEGI_SECURITY_CONTEXT");                    }                }            } else {                if (logger.isDebugEnabled()) {                    logger.debug("No HttpSession currently exists");                }            }            if (ContextHolder.getContext() == null) {                ContextHolder.setContext(generateNewContext());                if (logger.isDebugEnabled()) {                    logger.debug(                        "As ContextHolder null, setup ContextHolder with a fresh new instance: '"                        + ContextHolder.getContext() + "'");                }            }            // Make the HttpSession null, as we want to ensure we don't keep            // a reference to the HttpSession laying around in case the            // chain.doFilter() invalidates it.            httpSession = null;            // Proceed with chain            chain.doFilter(request, response);            // Store context back to HttpSession            try {                httpSession = ((HttpServletRequest) request).getSession(false);            } catch (IllegalStateException ignored) {}            if ((httpSession == null) && httpSessionExistedAtStartOfRequest) {                if (logger.isDebugEnabled()) {                    logger.debug(                        "HttpSession is now null, but was not null at start of request; session was invalidated, so do not create a new session");                }            }            // Generate a HttpSession only if we need to            if ((httpSession == null) && !httpSessionExistedAtStartOfRequest) {                if (!allowSessionCreation) {                    if (logger.isDebugEnabled()) {                        logger.debug(                            "Whilst ContextHolder contents have changed, the HttpSessionContextIntegrationFilter is prohibited from creating a HttpSession by the allowSessionCreation property being false");                    }                } else if (!contextObject.equals(ContextHolder.getContext())) {                    if (logger.isDebugEnabled()) {                        logger.debug(                            "HttpSession being created as ContextHolder contents are non-default");                    }                    try {                        httpSession = ((HttpServletRequest) request).getSession(true);                    } catch (IllegalStateException ignored) {}                } else {                    if (logger.isDebugEnabled()) {                        logger.debug(                            "HttpSession still null, but ContextHolder has not changed from default: ' "                            + ContextHolder.getContext()                            + "'; not creating HttpSession or storing ContextHolder contents");                    }                }            }            // If HttpSession exists, store current ContextHolder contents            if (httpSession != null) {                httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY,                    ContextHolder.getContext());                if (logger.isDebugEnabled()) {                    logger.debug("Context stored to HttpSession: '"                        + ContextHolder.getContext() + "'");                }                SecureContextImpl sec_context = (SecureContextImpl)ContextHolder.getContext();                if (sec_context != null && (sec_context.getAuthentication() != null)) {                    //String username = ((UserDetails)sec_context.getAuthentication().getDetails()).getUsername().substring(0,16);                    String username = (String)sec_context.getAuthentication().getPrincipal();                    User alfuser = null;                    WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(httpSession.getServletContext());                    ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);                    AuthenticationService authService = (AuthenticationService) ctx.getBean("authenticationService");                    TransactionService transactionService = serviceRegistry.getTransactionService();                    UserTransaction tx = transactionService.getUserTransaction();                    PersonService personService = (PersonService)ctx.getBean("personService");                                   try {                  tx.begin();                  //personService.setCreateMissingPeople(true);                  String currentTicket = authService.getCurrentTicket();                        alfuser =  new User(username,currentTicket,personService.getPerson(username));                        NodeService nodeService = serviceRegistry.getNodeService();                        //personService.setCreateMissingPeople(false);                        NodeRef homeSpaceRef = (NodeRef) nodeService.getProperty(personService.getPerson(username),                                ContentModel.PROP_HOMEFOLDER);                        alfuser.setHomeSpaceId(homeSpaceRef.getId());                        tx.commit();               } catch (Throwable ex) {                  logger.error(ex);                  try {                     tx.rollback();                  } catch (Exception ex2) {                     logger.error(                           "Failed to rollback transaction",                           ex2);                  }                  if (ex instanceof RuntimeException) {                     throw (RuntimeException) ex;                  } else {                     throw new RuntimeException(                           "Failed to set authenticated user",                           ex);                  }               }                    httpSession.setAttribute(ALF_SECURITY_CONTEXT_KEY,alfuser);                }            }            // Remove ContextHolder contents            ContextHolder.setContext(null);            if (logger.isDebugEnabled()) {                logger.debug(                    "ContextHolder set to null as request processing completed");            }        }    }}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Second question: we had to change the class org.alfresco.repo.security.permissions.impl.PermissionServiceImpl.java at line 444 in method getAuthorizations to avoid a classCastExceptionError:
java.lang.ClassCastException: java.lang.String        at org.alfresco.repo.security.permissions.impl.PermissionServiceImpl.getAuthorisations(PermissionServiceImpl.java:444)        at org.alfresco.repo.security.permissions.impl.PermissionServiceImpl.hasPermission(PermissionServiceImpl.java:363)        at org.alfresco.repo.security.permissions.impl.PermissionServiceImpl.hasPermission(PermissionServiceImpl.java:582)        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)        at java.lang.reflect.Method.invoke(Method.java:585)        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)        at $Proxy64.hasPermission(Unknown Source)        at org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoter.vote(ACLEntryVoter.java:316)        at net.sf.acegisecurity.vote.AffirmativeBased.decide(AffirmativeBased.java:69)        at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:394)        at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:77)        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)        at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:40)        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)        at $Proxy66.getProperty(Unknown Source)at org.alfresco.web.app.servlet.Cas2AlfrescoContextIntegrationFilter.doFilter(Cas2AlfrescoContextIntegrationFilter.java:275)  …‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This is due, for what we can understand, to a mismatch between line 201 of casAuthenticationProvider, which state
return new CasAuthenticationToken(this.key, response.getUser(),            authentication.getCredentials(), userDetails.getAuthorities(),            userDetails, response.getProxyList(),            response.getProxyGrantingTicketIou());‍‍‍‍‍‍‍‍‍
(note the second parameter response.getUser which returns a String)
and line 444 of org.alfresco.repo.security.permissions.impl.PermissionServiceImpl.java where auth is of type CasAuthenticationToken and so auth.getPrincipal() returns a String and cannot be casted to User (see code inside constructor of CasAuthenticationToken.
To solve this problem we changed method getAuthorisations in PermissionServiceImpl.java this way:
    private Set<String> getAuthorisations(Authentication auth, NodeRef nodeRef)    {        HashSet<String> auths = new HashSet<String>();        // No authenticated user then no permissions        if (auth == null)        {            return auths;        }        // TODO: Refactor and use the authentication service for this.        //User user = (User) auth.getPrincipal();                //auths.add(user.getUsername());        auths.add((String)auth.getPrincipal());        for (GrantedAuthority authority : auth.getAuthorities())        {            auths.add(authority.getAuthority());        }        if (dynamicAuthorities != null)        {            for (DynamicAuthority da : dynamicAuthorities)            { //               if (da.hasAuthority(nodeRef, user.getUsername()))               if (da.hasAuthority(nodeRef,(String)auth.getPrincipal()))                {                    auths.add(da.getAuthority());                }            }        }        auths.addAll(authorityService.getAuthorities());        return auths;    }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Does it seem meaningful or we missed the all thing?javascript:emoticon('Smiley Very Happy')
Thank you in advance for your help?

Davide & Emanuele
5 REPLIES 5

ribz33
Champ on-the-rise
Champ on-the-rise
Have you find a solution ?
Your Casifying of alfresco is it working now?

Im trying to do same thing…

Thx

escaglia
Champ in-the-making
Champ in-the-making
Yes it was working,
provided that we change the class org.alfresco.repo.security.permissions.impl.PermissionServiceImpl.java changing the method getAuthorisations as explained in the post.
We used Alfresco vers. 1.3, I don't know if it's still working with 1.4
Good luck,
Emanuele

dpalmeira
Champ in-the-making
Champ in-the-making
Hi,

I'm trying cas + user & group importing using ldap, but I get an exception after login into cas, just when redirect to alfresco occur

I dont know how can I fix it…

org.alfresco.error.AlfrescoRuntimeException: Not implementedat org.alfresco.repo.security.authentication.DefaultMutableAuthenticationDao.loadUserByUsername(DefaultMutableAuthenticationDao.java:402)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:585)at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)at $Proxy6.loadUserByUsername(Unknown Source)at net.sf.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator.getUserDetails(DaoCasAuthoritiesPopulator.java:58)at net.sf.acegisecurity.providers.cas.CasAuthenticationProvider.authenticateNow(CasAuthenticationProvider.java:197)at net.sf.acegisecurity.providers.cas.CasAuthenticationProvider.authenticate(CasAuthenticationProvider.java:165)at net.sf.acegisecurity.providers.ProviderManager.doAuthentication(ProviderManager.java:159)at net.sf.acegisecurity.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:49)at net.sf.acegisecurity.ui.cas.CasProcessingFilter.attemptAuthentication(CasProcessingFilter.java:109)at net.sf.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:287)at net.sf.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303)at…‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Another point is that I'm using passthru authenticator, but I'm not sure if it's the cause, because if I use alfresco authenticator widthout ldap sync, it's works !

I'm confussed about that.

can somebody help me?

thx

dpalmeira
Champ in-the-making
Champ in-the-making
I found the solution….

I had a DefaultMutableAuthenticationDao defined already in ldap-authentication-context.xml

So I commented it and wuaaaalaaa ! it works fine !

Smiley Tongue

andrepra
Champ in-the-making
Champ in-the-making
This is the solution i use

http://issues.alfresco.com/browse/AWC-952

Andrea