Friday, November 1, 2013

Custom alfresco authentication by extending default authentication

Step 1 : Add following line in alfresco-global.properties file located at /alfresco/tomcat/shared/classes location.

authentication.chain=yamaha:yamaha

Step 2 : create new folder test at alfresco/tomcat/webapps/alfresco/WEB-INF/classes/alfresco/subsystems/Authentication location.

Step 3 : create new file test-authentication.properties in test folder created with following content.


external.authentication.defaultAdministratorUserNames=admin


Step 3 : Create new file test-authentication-context.xml in same test folder with following content.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
   <bean id="authenticationComponent" class="org.alfresco.repo.security.authentication.test.TestCustomAuthenticationImpl"
      parent="authenticationComponentBase">
      <property name="nodeService">
         <ref bean="nodeService" />
      </property>
      <property name="personService">
         <ref bean="personService" />
      </property>
      <property name="transactionService">
         <ref bean="transactionService" />
      </property>
      <property name="defaultAdministratorUserNameList">
         <value>${external.authentication.defaultAdministratorUserNames}</value>
      </property>
   </bean>

   <!-- Wrapped version to be used within subsystem -->
   <bean id="AuthenticationComponent" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
      <property name="proxyInterfaces">
         <list>
            <value>org.alfresco.repo.security.authentication.AuthenticationComponent</value>
         </list>
      </property>
      <property name="transactionManager">
         <ref bean="transactionManager" />
      </property>
      <property name="target">
         <ref bean="authenticationComponent" />
      </property>
      <property name="transactionAttributes">
         <props>
            <prop key="*">${server.transaction.mode.default}</prop>
         </props>
      </property>
   </bean>

   <!-- Authentication service for chaining -->
   <bean id="localAuthenticationService" class="org.alfresco.repo.security.authentication.AuthenticationServiceImpl">
      <property name="ticketComponent">
         <ref bean="ticketComponent" />
      </property>
      <property name="authenticationComponent">
         <ref bean="authenticationComponent" />
      </property>
      <property name="sysAdminParams">
         <ref bean="sysAdminParams" />
      </property>
   </bean>
</beans>


Step 4 : Create new file test-filter.properties in same test folder with following content.

external.authentication.proxyUserName=alfresco-system
external.authentication.proxyHeader=X-Alfresco-Remote-User
external.authentication.enabled=true
external.authentication.userIdPattern=


Step 5 : Create new file test-filter-context.xml in same test folder with following content.


<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>

   <!-- Enable control over mapping between request and user ID -->
   <bean id="remoteUserMapper" class="org.alfresco.web.app.servlet.DefaultRemoteUserMapper">
      <property name="proxyUserName">
         <value>${external.authentication.proxyUserName}</value>
      </property>
      <property name="proxyHeader">
         <value>${external.authentication.proxyHeader}</value>
      </property>
      <property name="active">
         <value>${external.authentication.enabled}</value>
      </property>
      <property name="userIdPattern">
         <value>${external.authentication.userIdPattern}</value>
      </property>
      <property name="personService">
         <ref bean="PersonService" />
      </property>
   </bean>

   <!-- Enable cookie-based handling of webscript logins. We must assume cookie based client authentication when external auth is in the chain. -->
   <bean id="webscriptAuthenticationFilter" class="org.alfresco.web.app.servlet.WebScriptSSOAuthenticationFilter">
      <property name="active">
         <value>true</value>
      </property>
      <property name="authenticationService">
         <ref bean="AuthenticationService" />
      </property>
      <property name="authenticationComponent">
         <ref bean="AuthenticationComponent" />
      </property>
      <property name="personService">
         <ref bean="personService" />
      </property>
      <property name="nodeService">
         <ref bean="NodeService" />
      </property>
      <property name="transactionService">
         <ref bean="TransactionService" />
      </property>
      <property name="container">
         <ref bean="webscripts.container" />
      </property>
   </bean>

</beans>


Step 5 : create new java project in eclipse with any name you want.

Step 6 : create package with name org.alfresco.repo.security.authentication.test in src folder.

Step 7 : Create java class TestCustomAuthenticationImpl.java with following content in same package created.


/**
 * Project Name : Alfresco Custom Authentication
 * ---------------------
 * @author      Sourabh Aggarwal
 * -----------------------------------------------------------------------------------
 * -----------------------------------------------------------------------------------
 */
package org.alfresco.repo.security.authentication.test;

import in.co.ymsli.sedocs.rest.client.ISeDocsRestClient;
import in.co.ymsli.sedocs.rest.client.dto.auth.ValidateTokenDTO;
import in.co.ymsli.sedocs.rest.client.impl.SeDocsRestClientImpl;
import net.sf.acegisecurity.Authentication;

import org.alfresco.repo.security.authentication.AbstractAuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationException;


/**
 * @author Sourabh Aggarwal
 *
 */
public class TestCustomAuthenticationImpl extends AbstractAuthenticationComponent
{


public void authenticateImpl(String userName, char[] password) throws AuthenticationException
{
System.out.println("userName = "+userName + " ::::::::::::::: password = "+String.valueOf(password));
             if(userName == "abc"){
setCurrentUser(oValidateTokenDTO.getUserName());
              }else{

System.out.println("Error calling login service");
throw new AuthenticationException("Unable to authentication");

                   }

}

/**
* The default is not to support Authentication token base authentication
*/
public Authentication authenticate(Authentication token) throws AuthenticationException
{

System.out.println("authenticating vi vi token");
//throw new AlfrescoRuntimeException("Authentication via token not supported");

return token;
}

@Override
protected boolean implementationAllowsGuestLogin() {
// TODO Auto-generated method stub
return false;
}
}


Step 8 : Import all library from alfresco/tomcat/webapps/alfresco/WEB-INF/lib folder.

Step 9 : create jar of java project and place it in alfresco/tomcat/webapps/alfresco/WEB-INF/lib folder.

Step 10: restart server.

Step 11 : its done.

Step 12 : only abc user with any password can login.





New Model in alfresco and make all field searchable

Step 1 : Create new file testCustomFields-model.xml in /alfresco/tomcat/shared/classes/alfresco/extension folder with following content.

<?xml version="1.0" encoding="UTF-8"?>

<model name="test:knowledgebase" xmlns="http://www.alfresco.org/model/dictionary/1.0">

   <!-- Optional meta-data about the model -->
   <description>test Base Model</description>
   <author>Sourabh Aggarwal</author>
   <version>1.0</version>

   <!-- Imports are required to allow references to definitions in other models -->
   <imports>
      <!-- Import Alfresco Dictionary Definitions -->
      <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
      <!-- Import Alfresco Content Domain Model Definitions -->
      <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
   </imports>

   <!-- Introduction of new namespaces defined by this model -->
   <namespaces>
      <namespace uri="test.model" prefix="yamaha"/>
   </namespaces>

    <aspects>
      <!-- Definition of new Content Aspect: Knowledge Base Document -->
      <aspect name="test:cutomfieldsdata">
         <title>Knowledge Base Referencable</title>
         <properties>

   <property name="test:metadata_serial_number">
               <type>d:text</type>
            </property>

   <property name="test:metadata_status">
               <type>d:text</type>
            </property>
   <property name="test:metadata_owner">
               <type>d:text</type>
            </property>
            <property name="test:metadata_name_of_agreement">
               <type>d:text</type>
            </property>
            <property name="test:metadata_type_of_agreement">
               <type>d:text</type>
            </property>

            <property name="test:metadata_title_of_agreement">
               <type>d:text</type>
            </property>

            <property name="test:metadata_renewal">
               <type>d:text</type>
            </property>
            <property name="test:metadata_area_of_agreement">
               <type>d:text</type>
            </property>
            <property name="test:metadata_nature_of_agreement">
               <type>d:text</type>
            </property>
            <property name="test:metadata_parties">
               <type>d:text</type>
            </property>
            <property name="test:metadata_department">
               <type>d:text</type>
            </property>
            <property name="test:metadata_department_created_by">
               <type>d:text</type>
            </property>

            <property name="test:metadata_agreement_linked_agreements">
               <type>d:text</type>
            </property>


            <property name="test:metadata_type_of_document">
               <type>d:text</type>
            </property>
         </properties>
      </aspect>
   </aspects>

</model>


Step 2 : create new file with name testCustomFields-model-context.xml  in /alfresco/tomcat/shared/classes/alfresco/extension folder with following content.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>

    <!-- Registration of new models -->
    <bean id="extension.kb.dictionaryBootstrap" parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap">
        <property name="models">
            <list>
                <value>alfresco/extension/testCustomFields-model.xml</value>
            </list>
        </property>
    </bean>

     <bean id="extension.kb.resourceBundle" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
       <property name="resourceBundles">
          <list>
             <value>alfresco.messages.testCustomFields</value>
          </list>
       </property>
    </bean>

</beans>


Step 3 : create new file web-client-config-custom.xml in /alfresco/tomcat/shared/classes/alfresco/extension folder with following content.

<alfresco-config>
   <config evaluator="string-compare" condition="Advanced Search">
      <advanced-search>
         <content-types>
         </content-types>
         <folder-types>
         </folder-types>
         <custom-properties>


<meta-data aspect="test:cutomfieldsdata" property="test:metadata_serial_number" />
<meta-data aspect="test:cutomfieldsdata" property="test:metadata_status" />
<meta-data aspect="test:cutomfieldsdata" property="test:metadata_owner" />
<meta-data aspect="test:cutomfieldsdata" property="test:metadata_name_of_agreement" />
<meta-data aspect="test:cutomfieldsdata" property="test:metadata_title_of_agreement" />
<meta-data aspect="test:cutomfieldsdata" property="test:metadata_type_of_agreement" />
<meta-data aspect="test:cutomfieldsdata" property="test:metadata_renewal" />
<meta-data aspect="test:cutomfieldsdata" property="test:metadata_area_of_agreement" />
<meta-data aspect="test:cutomfieldsdata" property="test:metadata_nature_of_agreement" />
<meta-data aspect="test:cutomfieldsdata" property="test:metadata_parties" />

<meta-data aspect="test:cutomfieldsdata" property="test:metadata_agreement_linked_agreements" />

<meta-data aspect="test:cutomfieldsdata" property="test:metadata_type_of_document" />
         </custom-properties>
      </advanced-search>
   </config>
  
</alfresco-config>

Step 4 : create new file testCustomFields.properties in alfresco/tomcat/shared/classes/alfresco/messages with following content.

# Custom test messages

test_knowledgebase.property.test_metadata_serial_number.title=Serial Number
test_knowledgebase.property.test_metadata_status.title=Status For Agreement
test_knowledgebase.property.test_metadata_owner.title=Owner
test_knowledgebase.property.test_metadata_name_of_agreement.title=Name Of Agreement
test_knowledgebase.property.test_metadata_title_of_agreement.title=Title Of Agreement
test_knowledgebase.property.test_metadata_type_of_agreement.title=Type Of Agreement
test_knowledgebase.property.test_metadata_renewal.title=Renewal
test_knowledgebase.property.test_metadata_area_of_agreement.title=Area Of Agreement
test_knowledgebase.property.test_metadata_nature_of_agreement.title=Nature Of Agreement
test_knowledgebase.property.test_metadata_parties.title=Parties

test_knowledgebase.property.test_metadata_agreement_linked_agreements.title=Linked Agreements

test_knowledgebase.property.test_metadata_type_of_document.title=Type Of Document

Step 5 : edit file share-config-custom.xml in alfresco/tomcat/shared/classes/alfresco/web-extension and add following content.

  <!-- cm:content type (existing nodes) -->
  <config  evaluator="node-type" condition="cm:content">
     <forms>

<form>
   <field-visibility>
<show id="test:metadata_serial_number" />

<show id="test:metadata_status" />
<show id="test:metadata_owner" />
<show id="test:metadata_name_of_agreement" />

<show id="test:metadata_title_of_agreement" />

<show id="test:metadata_type_of_agreement" />
<show id="test:metadata_renewal" />
<show id="test:metadata_area_of_agreement" />
<show id="test:metadata_nature_of_agreement" />
<show id="test:metadata_department" />
<show id="test:metadata_department_created_by" />

<show id="test:metadata_type_of_service" />

<show id="test:metadata_parties" />

<show id="test:metadata_agreement_linked_agreements" />

<show id="test:metadata_type_of_document" />
   </field-visibility>
</form>

<!-- Document Library pop-up Edit Metadata form -->
<form id="doclib-simple-metadata">
   <field-visibility>

<show id="test:metadata_serial_number" />

<show id="test:metadata_status" />
<show id="test:metadata_owner" />
<show id="test:metadata_name_of_agreement" />

<show id="test:metadata_title_of_agreement" />

<show id="test:metadata_type_of_agreement" />
<show id="test:metadata_renewal" />
<show id="test:metadata_area_of_agreement" />
<show id="test:metadata_nature_of_agreement" />
<show id="test:metadata_department" />
<show id="test:metadata_department_created_by" />

<show id="test:metadata_type_of_service" />

<show id="test:metadata_parties" />

<show id="test:metadata_agreement_linked_agreements" />

<show id="test:metadata_type_of_document" />
   </field-visibility>
   <edit-form template="../documentlibrary/forms/doclib-simple-metadata.ftl" />
</form>

<!-- Document Library Inline Edit form -->
<form id="doclib-inline-edit">
   <field-visibility>

<show id="test:metadata_serial_number" />

<show id="test:metadata_status" />
<show id="test:metadata_owner" />
<show id="test:metadata_name_of_agreement" />

<show id="test:metadata_title_of_agreement" />

<show id="test:metadata_type_of_agreement" />
<show id="test:metadata_renewal" />
<show id="test:metadata_area_of_agreement" />
<show id="test:metadata_nature_of_agreement" />
<show id="test:metadata_department" />
<show id="test:metadata_department_created_by" />

<show id="test:metadata_type_of_service" />

<show id="test:metadata_parties" />

<show id="test:metadata_agreement_linked_agreements" />

<show id="test:metadata_type_of_document" />
   </field-visibility>
</form>
     </forms>
  </config>

Step 6 : Optional if want this model as the aspect then we have to add following in the same share-config-custom.xml file.

  <!-- Document Library config section -->
  <config evaluator="string-compare" condition="DocumentLibrary">

     <!--
Used by the "Manage Aspects" action

For custom aspects, remember to also add the relevant i18n string(s)
   cm_myaspect=My Aspect
     -->
     <aspects>
<!-- Aspects that a user can see -->
<visible>
   <aspect name="cm:generalclassifiable" />
   <aspect name="cm:complianceable" />
   <aspect name="cm:dublincore" />
   <aspect name="cm:effectivity" />
   <aspect name="cm:summarizable" />
   <aspect name="cm:versionable" />
   <aspect name="cm:templatable" />
   <aspect name="cm:emailed" />
   <aspect name="emailserver:aliasable" />
   <aspect name="cm:taggable" />
   <aspect name="app:inlineeditable" />
   <aspect name="test:cutomfieldsdata" />
</visible>

<!-- Aspects that a user can add. Same as "visible" if left empty -->
<addable>
</addable>

<!-- Aspects that a user can remove. Same as "visible" if left empty -->
<removeable>
</removeable>
     </aspects>

  </config>

Step 7 : In file custom-slingshot-application-context.xml l in alfresco/tomcat/shared/classes/alfresco/web-extension and add following content between <beans></beans>.

   <!-- Add test messages -->
   <bean id="webscripts.kb.resources" class="org.springframework.extensions.surf.util.ResourceBundleBootstrapComponent">
      <property name="resourceBundles">
         <list>
            <value>alfresco.messages.testCustomFields</value>
         </list>
      </property>
   </bean>

step 8 : restart.