Alternate auth method for WS

Do you want to create a native client or integrate with third party applications: webservices are the solution.
Forum rules
Please, before asking something see the documentation wiki or use the search feature of the forum. And remember we don't have a crystal ball or mental readers, so if you post about an issue tell us which OpenKM are you using and also the browser and operating system version. For more info read How to Report Bugs Effectively.
dejanfc
Senior Boarder
Senior Boarder
Posts: 60
Joined: Wed Dec 05, 2012 1:40 pm

Alternate auth method for WS

Post by dejanfc » Tue Mar 26, 2013 8:29 am

Hi

We are using Kerberos authentication for our OpenKM setup and we'd like to extend this scheme to webservices. Is there any way to replace the default basic authentication in OKMAuth with a system that checks for user's ticket instead of user/pass strings?

jllort
Moderator
Moderator
Posts: 10608
Joined: Fri Dec 21, 2007 11:23 am
Location: Sineu - ( Illes Balears ) - Spain
Contact:

Re: Alternate auth method for WS

Post by jllort » Wed Mar 27, 2013 10:23 pm

You have changed OpenKM.xml for it no ? can you share this kind of configuration to other community user. I would like to add in our wiki documentation.

About ws authetication, other openkm staff will give you more information about it. From what I know without some source code change I think is not possible.

dejanfc
Senior Boarder
Senior Boarder
Posts: 60
Joined: Wed Dec 05, 2012 1:40 pm

Re: Alternate auth method for WS

Post by dejanfc » Thu Mar 28, 2013 7:20 am

I changed the applicationContext.xml and commented out the configuration in OpenKM.xml, since you have to define a spnego entry point on the protected urls to get the single sign on functionality. I'll write a tutorial later once I find some time.

About WS, I have no problem changing the source code, just point me into right direction :). I've briefly checked the CXF documentation yesterday and the cxf lib you use in OpenKM seems to have kerberos client included already ( org.apache.cxf.ws.security.kerberos.KerberosClient ) so this thing should theoretically be possible, assuming I change the schema (on endpoints?) to accept the kerberos tickets. I have no experience with web services so any help would be appreciated.

pavila
Moderator
Moderator
Posts: 3062
Joined: Tue Dec 11, 2007 6:02 pm
Location: Alicante, Spain
Contact:

Re: Alternate auth method for WS

Post by pavila » Thu Mar 28, 2013 10:32 am

Webservice configuration is located at WEB-INF/applicationContext.xml, so if you want to play with Kerberos authentication this is the right place. You should also check Spring Security documentation and also Apache CXF Web Services documentation.

An please, share any interesting configuration like this with the community so we can add it to he OpenKM Documentation Wiki.

dejanfc
Senior Boarder
Senior Boarder
Posts: 60
Joined: Wed Dec 05, 2012 1:40 pm

Re: Alternate auth method for WS

Post by dejanfc » Thu Mar 28, 2013 2:58 pm

Here is a quick and dirty version, I'll write a complete tutorial sometime in the future (with up to date version of OpenKM :)). No kerberos auth for webservices yet.

Setup we use:

Samba4 AD
OpenKM Community 6.2.1. (tested on 6.2.4, works) hosted on Ubuntu 12.04 within a OpenVZ container
java version:

Code: Select all

java version "1.6.0_27"
OpenJDK Runtime Environment (IcedTea6 1.12.3) (6b27-1.12.3-0ubuntu1~12.04.1)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
Note: when I tried to replicate this setup on 6.2.2 I had to upgrade java version but that one had a problem with handling of 'file:<keytab location>' attribute value, so you'd have to make a minor correction in the kerberos extension files (I'll post a link later if I can find it)

I won't go into details on how to set up Samba4 AD or kerberize a server since there's plenty of documentation available, so this config assumes you already have a working AD/Kerberos environment or know how to set up one.

Base DN in AD: DC=fictional,DC=company
Bind user: ldap-lookup, pass 'secret01'
Users are stored in: OU=Employees,DC=fictional,DC=company
Groups are stored in: OU=Groups,DC=fictional,DC=company
AD hostname: ad
OpenKM server hostname: openkm
Keytab is located in /etc/krb5.keytab and has a HTTP/openkm.fictional.company service name.

Before starting the install,create ROLE_USER and ROLE_ADMIN roles in your AD (if that isn't possible you can also use custom roles in your OpenKM config).

Configure your OpenKM Admin/Config tab like this:

Code: Select all

principal.adapter		 com.openkm.principal.LdapPrincipalAdapter	    
principal.database.filter.inactive.users	Boolean		    
principal.ldap.mail.attribute		 mail	    
principal.ldap.mail.search.base		 ou=Employees,dc=fictional,dc=company	    
principal.ldap.mail.search.filter		 (&(objectClass=person)(userPrincipalName={0}))	    
principal.ldap.referral		 follow	    
principal.ldap.role.attribute		 cn	    
principal.ldap.role.search.base	List	 ou=Groups,dc=fictional,dc=company	    
principal.ldap.role.search.filter		 objectClass=group	    
principal.ldap.roles.by.user.attribute		 memberOf	    
principal.ldap.roles.by.user.search.base		 ou=Employees,dc=fictional,dc=company	    
principal.ldap.roles.by.user.search.filter		 (&(objectClass=person)(userPrincipalName={0}))	    
principal.ldap.security.credentials		 secret01	    
principal.ldap.security.principal		 cn=ldap-lookup,cn=Users,dc=fictional,dc=company	    
principal.ldap.server		 ldap://ad.fictional.company:389	    
principal.ldap.user.attribute		 userPrincipalName	    
principal.ldap.user.search.base	List	 ou=Employees,dc=fictional,dc=company	    
principal.ldap.user.search.filter		 objectClass=person	    
principal.ldap.username.attribute		 cn	    
principal.ldap.username.search.base		 ou=Employees,dc=fictional,dc=company	    
principal.ldap.username.search.filter		 (&(objectClass=person)(userPrincipalName={0}))	    
principal.ldap.users.by.role.attribute		 userPrincipalName	    
principal.ldap.users.by.role.search.base		 ou=Employees,dc=fictional,dc=company	    
principal.ldap.users.by.role.search.filter		 (&(objectClass=person)(memberOf=cn={0},ou=Groups,dc=fictional,dc=company))	
At this point you can also decide to use custom default roles, however, this requires setting read permissions on every repository node - this can be done through the interface for every node except Trash folder, for which you will have to manually add an entry into the database.

1) Download and install OpenKM using your prefered method
2) Download the Spring Security Kerberos Extension .jar file and put it into your OpenKM lib folder ( for example, /opt/tomcat/webapps/OpenKM/WEB-INF/lib)
http://netload.in/dateiZrhLN1m90h/sprin ... OT.jar.htm
Alternatively you can download and compile the file yourself from https://github.com/SpringSource/spring- ... -kerberos/ (note that this is a newer version which I have not yet tested)
3) Create the keytab for your OpenKM server and make sure it will be readable by tomcat
4) Open OpenKM.xml and comment out the authentication manager, since you will be doing all the changes directly in applicationContext.xml
5) Change the applicationContext.xml

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:security="http://www.springframework.org/schema/security"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:task="http://www.springframework.org/schema/task"
             xmlns:jee="http://www.springframework.org/schema/jee"
             xmlns:jaxws="http://cxf.apache.org/jaxws"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                                 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                                 http://www.springframework.org/schema/security
                                 http://www.springframework.org/schema/security/spring-security-3.1.xsd
                                 http://www.springframework.org/schema/context
                                 http://www.springframework.org/schema/context/spring-context-3.1.xsd
                                 http://www.springframework.org/schema/task
                                 http://www.springframework.org/schema/task/spring-task-3.1.xsd
                                 http://www.springframework.org/schema/jee
                                 http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
                                 http://cxf.apache.org/jaxws
                                 http://cxf.apache.org/schemas/jaxws.xsd">
    
    <context:component-scan base-package="com.openkm"/>
    
    <!-- <task:annotation-driven/> -->
    <!-- Tasks configuration moved to $CATALINA_HOME/OpenKM.xml -->
    
    <!-- Apache CXF Web Services -->
    <beans:import resource="classpath:META-INF/cxf/cxf.xml" />
    <beans:import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
    
    <!--
    <beans:bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <beans:property name="targetClass" value="org.springframework.security.core.context.SecurityContextHolder" />
        <beans:property name="targetMethod" value="setStrategyName" />
        <beans:property name="arguments" value="_INHERITABLETHREADLOCAL" />
    </beans:bean>
    -->
    
    <beans:bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
        <beans:constructor-arg>
            <beans:map>
                <beans:entry key="action" value="UsernameToken" />
                <beans:entry key="passwordType" value="PasswordText" />
                <beans:entry key="passwordCallbackClass" value="com.openkm.spring.ClientPasswordCallback" />
            </beans:map>
        </beans:constructor-arg>
    </beans:bean>
    
    <jaxws:endpoint id="authService" implementor="com.openkm.ws.endpoint.AuthService" address="/OKMAuth"/>
    <jaxws:endpoint id="bookmarkService" implementor="com.openkm.ws.endpoint.BookmarkService" address="/OKMBookmark"/>
    <jaxws:endpoint id="documentService" implementor="com.openkm.ws.endpoint.DocumentService" address="/OKMDocument"/>
    <jaxws:endpoint id="folderService" implementor="com.openkm.ws.endpoint.FolderService" address="/OKMFolder"/>
    <jaxws:endpoint id="mailService" implementor="com.openkm.ws.endpoint.MailService" address="/OKMMail"/>
    <jaxws:endpoint id="noteService" implementor="com.openkm.ws.endpoint.NoteService" address="/OKMNote"/>
    <jaxws:endpoint id="notificationService" implementor="com.openkm.ws.endpoint.NotificationService" address="/OKMNotification"/>
    <jaxws:endpoint id="propertyGroupService" implementor="com.openkm.ws.endpoint.PropertyGroupService" address="/OKMPropertyGroup"/>
    <jaxws:endpoint id="propertyService" implementor="com.openkm.ws.endpoint.PropertyService" address="/OKMProperty"/>
    <jaxws:endpoint id="repositoryService" implementor="com.openkm.ws.endpoint.RepositoryService" address="/OKMRepository"/>
    <jaxws:endpoint id="searchService" implementor="com.openkm.ws.endpoint.SearchService" address="/OKMSearch"/>
    <jaxws:endpoint id="dashboardService" implementor="com.openkm.ws.endpoint.DashboardService" address="/OKMDashboard"/>
    <jaxws:endpoint id="workflowService" implementor="com.openkm.ws.endpoint.WorkflowService" address="/OKMWorkflow"/>
    <jaxws:endpoint id="testService" implementor="com.openkm.ws.endpoint.TestService" address="/OKMTest">
        <!--
            <jaxws:inInterceptors>
                <beans:ref bean="WSS4JInInterceptor"/>
            </jaxws:inInterceptors>
        -->
    </jaxws:endpoint>
    
    <security:global-method-security secured-annotations="enabled"/>
    
<!--  Remove prefix to be able of use custom roles
    <beans:bean class="org.springframework.security.access.vote.RoleVoter">
        <beans:property name="rolePrefix" value=""/>
    </beans:bean> -->
    
    <!-- Web Services using Basic authentication -->
    <security:http pattern="/services/**" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <security:http-basic />
    </security:http>
    
    <!-- Status -->
    <security:http pattern="/Status" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
        <security:http-basic />
    </security:http>
    
    <!-- Download -->
    <security:http pattern="/Download" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
        <security:http-basic />
    </security:http>
    
    <!-- Workflow deploy -->
    <security:http pattern="/workflow-register" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
        <security:http-basic />
    </security:http>
    
    <!-- WebDAV using Basic authentication -->
    <security:http pattern="/webdav/**" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
        <security:http-basic />
    </security:http>
    
    <!-- Syndication using Basic authentication -->
    <security:http pattern="/feed/**" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
        <security:http-basic />
    </security:http>
    

	<security:http entry-point-ref="spnegoEntryPoint">

<!-- GWT -->
        <security:intercept-url pattern="/frontend/**" access="IS_AUTHENTICATED_FULLY" />

        <!-- JSPs -->
        <security:intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <security:intercept-url pattern="/admin/**" access="IS_AUTHENTICATED_FULLY" />

        <!-- Servlets -->
        <security:intercept-url pattern="/RepositoryStartup" access="IS_AUTHENTICATED_FULLY" />
        <security:intercept-url pattern="/Test" access="IS_AUTHENTICATED_FULLY" />

        <!-- Extensions -->
        <security:intercept-url pattern="/extension/**" access="IS_AUTHENTICATED_FULLY" />

        <!-- Login page -->


		<security:custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
		<security:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=1"/>
	</security:http>

	<beans:bean id="spnegoEntryPoint" class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" />

	<beans:bean id="spnegoAuthenticationProcessingFilter" class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
		<beans:property name="authenticationManager" ref="authenticationManager" />
	</beans:bean>

	<security:authentication-manager alias="authenticationManager">
		<security:authentication-provider ref="kerberosServiceAuthenticationProvider" /> <!-- Used with SPNEGO -->
		<security:authentication-provider ref="kerberosAuthenticationProvider"/> <!-- Used with form login -->
	</security:authentication-manager>

	<beans:bean id="kerberosAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
		<beans:property name="kerberosClient">
			<beans:bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
				<beans:property name="debug" value="true"/>
			</beans:bean>
		</beans:property>
		<beans:property name="userDetailsService" ref="ldapUserService"/>
	</beans:bean>
	
	<beans:bean id="kerberosServiceAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
		<beans:property name="ticketValidator">
			<beans:bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
				<beans:property name="servicePrincipal" value="HTTP/openkm.fictional.company" />
				<!-- Setting keyTabLocation to a classpath resource will most likely not work in a Java EE application Server -->
				<!-- See the Javadoc for more information on that -->
				<beans:property name="keyTabLocation" value="file:/etc/krb5.keytab" />
				<beans:property name="debug" value="true" />
			</beans:bean>
		</beans:property>
		<beans:property name="userDetailsService" ref="ldapUserService" />
	</beans:bean>
	
	<beans:bean class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
		<beans:property name="debug" value="true" />
		<!-- You can point to a different kerberos config location here, if you don't want the default one -->
		<!-- <property name="krbConfLocation" value="/etc/krb5.conf"/> -->
	</beans:bean>


<beans:bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
  <beans:constructor-arg value="ldap://ad.fictional.company:389/ "/>
  <beans:property name="userDn" value="CN=ldap-lookup,cn=Users,dc=fictional,dc=company"/>
  <beans:property name="password" value="secret01"/>
  <beans:property name="baseEnvironmentProperties">
      <beans:map>
        <beans:entry>
          <beans:key>
            <beans:value>java.naming.referral</beans:value>
          </beans:key>
          <beans:value>follow</beans:value>
        </beans:entry>
      </beans:map>
    </beans:property>
  </beans:bean>

<beans:bean id="ldapUserService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
  <beans:constructor-arg index="0">
    <beans:bean class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
      <beans:constructor-arg value="ou=Employees,DC=,fictional,DC=company"/>
	 <beans:constructor-arg value="userPrincipalName={0}"/>
      <beans:constructor-arg ref="contextSource"/>
      <beans:property name="searchSubtree" value="true" />
    </beans:bean>
  </beans:constructor-arg>
  <beans:constructor-arg index="1">
    <beans:bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
      <beans:constructor-arg ref="contextSource"/>
      <beans:constructor-arg value="ou=Groups,dc=fictional,dc=company"/>
      <beans:property name="groupRoleAttribute" value="cn"/>
      <beans:property name="searchSubtree" value="true" />
      <beans:property name="convertToUpperCase" value="false"/>
      <beans:property name="rolePrefix" value=""/>
   </beans:bean>
  </beans:constructor-arg>
</beans:bean>

</beans:beans>
Make sure to restart Tomcat.

Open up a browser that supports SPNEGO (Firefox) and add the url of your openkm server to trusted urls (open about:config, search for 'network.n' and add 'openkm.fictional.company' in this case to the list of trusted urls)

If you have a valid kerberos ticket you can then log in to your OpenKM via http://openkm.fictional.company:8080/OpenKM OR log in manually via http://openkm.fictional.company:8080/OpenKM/login.jsp where you type in your AD username/pass. I still have to figure out how to make the server redirect me to login page if the spnego fails, but it's not critical at this point.
Last edited by dejanfc on Mon Sep 09, 2013 6:22 am, edited 1 time in total.

pavila
Moderator
Moderator
Posts: 3062
Joined: Tue Dec 11, 2007 6:02 pm
Location: Alicante, Spain
Contact:

Re: Alternate auth method for WS

Post by pavila » Mon Apr 01, 2013 10:31 am

I have added this info to the OpenKM documentation wiki http://wiki.openkm.com/index.php/Kerberos so, feel free to correct, enhance or complete this article.

dejanfc
Senior Boarder
Senior Boarder
Posts: 60
Joined: Wed Dec 05, 2012 1:40 pm

Re: Alternate auth method for WS

Post by dejanfc » Tue Apr 02, 2013 6:07 am

Just one small thing, the urls got cut off during copypaste :).

pavila
Moderator
Moderator
Posts: 3062
Joined: Tue Dec 11, 2007 6:02 pm
Location: Alicante, Spain
Contact:

Re: Alternate auth method for WS

Post by pavila » Wed Apr 03, 2013 10:34 am

Thanks! URL fixed.

joako
Expert Boarder
Expert Boarder
Posts: 92
Joined: Wed Feb 23, 2011 5:31 am

Re: Alternate auth method for WS

Post by joako » Wed Apr 24, 2013 6:15 am

So under this configuration when you visit the OpenKM login page you don't need to input anything and it's automatically logged in with the current Windows user?

dejanfc
Senior Boarder
Senior Boarder
Posts: 60
Joined: Wed Dec 05, 2012 1:40 pm

Re: Alternate auth method for WS

Post by dejanfc » Thu Apr 25, 2013 6:36 am

That is correct.

edit: If you go to login page (login.jsp) directly, the browser won't perform negotiation because that url is exempt from the protected urls listed in Spnego Entry Point bean. To perform spnego auth you have to visit **/OpenKM/ url which is the default.

jjirik
Fresh Boarder
Fresh Boarder
Posts: 4
Joined: Wed Apr 09, 2014 12:46 pm

Re: Alternate auth method for WS

Post by jjirik » Mon Apr 14, 2014 6:55 pm

Hi all. First of all great post - you guys rock!!

Now, I have kerberos authentication working between my Samba4 AD and Samba3 file server. Now I would like to use it to authenticate the webservice (openKM) also. I am confused about the point 2 and 3 of your little manual - where do I get the Spring Security and how do I download/change/compile it? and also how do I create the keytab (I looked for the krb5.keytab and cannot find it).

Thanks a lot for all your help.

jjirik
Fresh Boarder
Fresh Boarder
Posts: 4
Joined: Wed Apr 09, 2014 12:46 pm

Re: Alternate auth method for WS

Post by jjirik » Mon Jun 23, 2014 7:15 pm

Hi guys,

Update on my search. I now have the keytab working (I can use kinit to confirm that) but while I am trying to open the openKM, I am getting HTTP Status 404 - the resource (OpenKM) is not available. I downloaded wget http://maven.springframework.org/milest ... 0.0.M2.jar and put it in /opt/tomcat-7.0.27/webapps/OpenKM/WEB-INF/lib folder, but honestly I am not sure what this jar file does. Can someone enlighten me and is there a way to see if is it working properly?

Thanks a lot for all your help.

mtchathuranga
Fresh Boarder
Fresh Boarder
Posts: 1
Joined: Wed Dec 12, 2018 10:03 am

Re: Alternate auth method for WS

Post by mtchathuranga » Mon Mar 11, 2019 4:17 am

Hi , I'm trying to implement SSO with OpenKM version 6.3.3. is it possible ? I followed above all steps.But, i couldn't . if some one have implemented please share necessary information.Also having some issues with spring-security-kerberos-core-1.0.0.CI-SNAPSHOT.jar.
If some one have that jar please share.

Thank you all

jllort
Moderator
Moderator
Posts: 10608
Joined: Fri Dec 21, 2007 11:23 am
Location: Sineu - ( Illes Balears ) - Spain
Contact:

Re: Alternate auth method for WS

Post by jllort » Tue Mar 12, 2019 10:07 pm

What OpenKM documentation did you followed for it?

vaajayashanka
Fresh Boarder
Fresh Boarder
Posts: 3
Joined: Thu Mar 21, 2019 4:01 am

Re: Alternate auth method for WS

Post by vaajayashanka » Wed Apr 03, 2019 4:41 am

dejanfc wrote:
Thu Mar 28, 2013 2:58 pm
Here is a quick and dirty version, I'll write a complete tutorial sometime in the future (with up to date version of OpenKM :)). No kerberos auth for webservices yet.

Setup we use:

Samba4 AD
OpenKM Community 6.2.1. (tested on 6.2.4, works) hosted on Ubuntu 12.04 within a OpenVZ container
java version:

Code: Select all

java version "1.6.0_27"
OpenJDK Runtime Environment (IcedTea6 1.12.3) (6b27-1.12.3-0ubuntu1~12.04.1)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
Note: when I tried to replicate this setup on 6.2.2 I had to upgrade java version but that one had a problem with handling of 'file:<keytab location>' attribute value, so you'd have to make a minor correction in the kerberos extension files (I'll post a link later if I can find it)

I won't go into details on how to set up Samba4 AD or kerberize a server since there's plenty of documentation available, so this config assumes you already have a working AD/Kerberos environment or know how to set up one.

Base DN in AD: DC=fictional,DC=company
Bind user: ldap-lookup, pass 'secret01'
Users are stored in: OU=Employees,DC=fictional,DC=company
Groups are stored in: OU=Groups,DC=fictional,DC=company
AD hostname: ad
OpenKM server hostname: openkm
Keytab is located in /etc/krb5.keytab and has a HTTP/openkm.fictional.company service name.

Before starting the install,create ROLE_USER and ROLE_ADMIN roles in your AD (if that isn't possible you can also use custom roles in your OpenKM config).

Configure your OpenKM Admin/Config tab like this:

Code: Select all

principal.adapter		 com.openkm.principal.LdapPrincipalAdapter	    
principal.database.filter.inactive.users	Boolean		    
principal.ldap.mail.attribute		 mail	    
principal.ldap.mail.search.base		 ou=Employees,dc=fictional,dc=company	    
principal.ldap.mail.search.filter		 (&(objectClass=person)(userPrincipalName={0}))	    
principal.ldap.referral		 follow	    
principal.ldap.role.attribute		 cn	    
principal.ldap.role.search.base	List	 ou=Groups,dc=fictional,dc=company	    
principal.ldap.role.search.filter		 objectClass=group	    
principal.ldap.roles.by.user.attribute		 memberOf	    
principal.ldap.roles.by.user.search.base		 ou=Employees,dc=fictional,dc=company	    
principal.ldap.roles.by.user.search.filter		 (&(objectClass=person)(userPrincipalName={0}))	    
principal.ldap.security.credentials		 secret01	    
principal.ldap.security.principal		 cn=ldap-lookup,cn=Users,dc=fictional,dc=company	    
principal.ldap.server		 ldap://ad.fictional.company:389	    
principal.ldap.user.attribute		 userPrincipalName	    
principal.ldap.user.search.base	List	 ou=Employees,dc=fictional,dc=company	    
principal.ldap.user.search.filter		 objectClass=person	    
principal.ldap.username.attribute		 cn	    
principal.ldap.username.search.base		 ou=Employees,dc=fictional,dc=company	    
principal.ldap.username.search.filter		 (&(objectClass=person)(userPrincipalName={0}))	    
principal.ldap.users.by.role.attribute		 userPrincipalName	    
principal.ldap.users.by.role.search.base		 ou=Employees,dc=fictional,dc=company	    
principal.ldap.users.by.role.search.filter		 (&(objectClass=person)(memberOf=cn={0},ou=Groups,dc=fictional,dc=company))	
At this point you can also decide to use custom default roles, however, this requires setting read permissions on every repository node - this can be done through the interface for every node except Trash folder, for which you will have to manually add an entry into the database.

1) Download and install OpenKM using your prefered method
2) Download the Spring Security Kerberos Extension .jar file and put it into your OpenKM lib folder ( for example, /opt/tomcat/webapps/OpenKM/WEB-INF/lib)
http://netload.in/dateiZrhLN1m90h/sprin ... OT.jar.htm
Alternatively you can download and compile the file yourself from https://github.com/SpringSource/spring- ... -kerberos/ (note that this is a newer version which I have not yet tested)
3) Create the keytab for your OpenKM server and make sure it will be readable by tomcat
4) Open OpenKM.xml and comment out the authentication manager, since you will be doing all the changes directly in applicationContext.xml
5) Change the applicationContext.xml

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:security="http://www.springframework.org/schema/security"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:task="http://www.springframework.org/schema/task"
             xmlns:jee="http://www.springframework.org/schema/jee"
             xmlns:jaxws="http://cxf.apache.org/jaxws"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                                 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                                 http://www.springframework.org/schema/security
                                 http://www.springframework.org/schema/security/spring-security-3.1.xsd
                                 http://www.springframework.org/schema/context
                                 http://www.springframework.org/schema/context/spring-context-3.1.xsd
                                 http://www.springframework.org/schema/task
                                 http://www.springframework.org/schema/task/spring-task-3.1.xsd
                                 http://www.springframework.org/schema/jee
                                 http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
                                 http://cxf.apache.org/jaxws
                                 http://cxf.apache.org/schemas/jaxws.xsd">
    
    <context:component-scan base-package="com.openkm"/>
    
    <!-- <task:annotation-driven/> -->
    <!-- Tasks configuration moved to $CATALINA_HOME/OpenKM.xml -->
    
    <!-- Apache CXF Web Services -->
    <beans:import resource="classpath:META-INF/cxf/cxf.xml" />
    <beans:import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
    
    <!--
    <beans:bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <beans:property name="targetClass" value="org.springframework.security.core.context.SecurityContextHolder" />
        <beans:property name="targetMethod" value="setStrategyName" />
        <beans:property name="arguments" value="_INHERITABLETHREADLOCAL" />
    </beans:bean>
    -->
    
    <beans:bean id="WSS4JInInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
        <beans:constructor-arg>
            <beans:map>
                <beans:entry key="action" value="UsernameToken" />
                <beans:entry key="passwordType" value="PasswordText" />
                <beans:entry key="passwordCallbackClass" value="com.openkm.spring.ClientPasswordCallback" />
            </beans:map>
        </beans:constructor-arg>
    </beans:bean>
    
    <jaxws:endpoint id="authService" implementor="com.openkm.ws.endpoint.AuthService" address="/OKMAuth"/>
    <jaxws:endpoint id="bookmarkService" implementor="com.openkm.ws.endpoint.BookmarkService" address="/OKMBookmark"/>
    <jaxws:endpoint id="documentService" implementor="com.openkm.ws.endpoint.DocumentService" address="/OKMDocument"/>
    <jaxws:endpoint id="folderService" implementor="com.openkm.ws.endpoint.FolderService" address="/OKMFolder"/>
    <jaxws:endpoint id="mailService" implementor="com.openkm.ws.endpoint.MailService" address="/OKMMail"/>
    <jaxws:endpoint id="noteService" implementor="com.openkm.ws.endpoint.NoteService" address="/OKMNote"/>
    <jaxws:endpoint id="notificationService" implementor="com.openkm.ws.endpoint.NotificationService" address="/OKMNotification"/>
    <jaxws:endpoint id="propertyGroupService" implementor="com.openkm.ws.endpoint.PropertyGroupService" address="/OKMPropertyGroup"/>
    <jaxws:endpoint id="propertyService" implementor="com.openkm.ws.endpoint.PropertyService" address="/OKMProperty"/>
    <jaxws:endpoint id="repositoryService" implementor="com.openkm.ws.endpoint.RepositoryService" address="/OKMRepository"/>
    <jaxws:endpoint id="searchService" implementor="com.openkm.ws.endpoint.SearchService" address="/OKMSearch"/>
    <jaxws:endpoint id="dashboardService" implementor="com.openkm.ws.endpoint.DashboardService" address="/OKMDashboard"/>
    <jaxws:endpoint id="workflowService" implementor="com.openkm.ws.endpoint.WorkflowService" address="/OKMWorkflow"/>
    <jaxws:endpoint id="testService" implementor="com.openkm.ws.endpoint.TestService" address="/OKMTest">
        <!--
            <jaxws:inInterceptors>
                <beans:ref bean="WSS4JInInterceptor"/>
            </jaxws:inInterceptors>
        -->
    </jaxws:endpoint>
    
    <security:global-method-security secured-annotations="enabled"/>
    
<!--  Remove prefix to be able of use custom roles
    <beans:bean class="org.springframework.security.access.vote.RoleVoter">
        <beans:property name="rolePrefix" value=""/>
    </beans:bean> -->
    
    <!-- Web Services using Basic authentication -->
    <security:http pattern="/services/**" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <security:http-basic />
    </security:http>
    
    <!-- Status -->
    <security:http pattern="/Status" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
        <security:http-basic />
    </security:http>
    
    <!-- Download -->
    <security:http pattern="/Download" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
        <security:http-basic />
    </security:http>
    
    <!-- Workflow deploy -->
    <security:http pattern="/workflow-register" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
        <security:http-basic />
    </security:http>
    
    <!-- WebDAV using Basic authentication -->
    <security:http pattern="/webdav/**" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
        <security:http-basic />
    </security:http>
    
    <!-- Syndication using Basic authentication -->
    <security:http pattern="/feed/**" create-session="stateless">
        <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
        <security:http-basic />
    </security:http>
    

	<security:http entry-point-ref="spnegoEntryPoint">

<!-- GWT -->
        <security:intercept-url pattern="/frontend/**" access="IS_AUTHENTICATED_FULLY" />

        <!-- JSPs -->
        <security:intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <security:intercept-url pattern="/admin/**" access="IS_AUTHENTICATED_FULLY" />

        <!-- Servlets -->
        <security:intercept-url pattern="/RepositoryStartup" access="IS_AUTHENTICATED_FULLY" />
        <security:intercept-url pattern="/Test" access="IS_AUTHENTICATED_FULLY" />

        <!-- Extensions -->
        <security:intercept-url pattern="/extension/**" access="IS_AUTHENTICATED_FULLY" />

        <!-- Login page -->


		<security:custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
		<security:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=1"/>
	</security:http>

	<beans:bean id="spnegoEntryPoint" class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" />

	<beans:bean id="spnegoAuthenticationProcessingFilter" class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
		<beans:property name="authenticationManager" ref="authenticationManager" />
	</beans:bean>

	<security:authentication-manager alias="authenticationManager">
		<security:authentication-provider ref="kerberosServiceAuthenticationProvider" /> <!-- Used with SPNEGO -->
		<security:authentication-provider ref="kerberosAuthenticationProvider"/> <!-- Used with form login -->
	</security:authentication-manager>

	<beans:bean id="kerberosAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
		<beans:property name="kerberosClient">
			<beans:bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
				<beans:property name="debug" value="true"/>
			</beans:bean>
		</beans:property>
		<beans:property name="userDetailsService" ref="ldapUserService"/>
	</beans:bean>
	
	<beans:bean id="kerberosServiceAuthenticationProvider" class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
		<beans:property name="ticketValidator">
			<beans:bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
				<beans:property name="servicePrincipal" value="HTTP/openkm.fictional.company" />
				<!-- Setting keyTabLocation to a classpath resource will most likely not work in a Java EE application Server -->
				<!-- See the Javadoc for more information on that -->
				<beans:property name="keyTabLocation" value="file:/etc/krb5.keytab" />
				<beans:property name="debug" value="true" />
			</beans:bean>
		</beans:property>
		<beans:property name="userDetailsService" ref="ldapUserService" />
	</beans:bean>
	
	<beans:bean class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
		<beans:property name="debug" value="true" />
		<!-- You can point to a different kerberos config location here, if you don't want the default one -->
		<!-- <property name="krbConfLocation" value="/etc/krb5.conf"/> -->
	</beans:bean>


<beans:bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
  <beans:constructor-arg value="ldap://ad.fictional.company:389/ "/>
  <beans:property name="userDn" value="CN=ldap-lookup,cn=Users,dc=fictional,dc=company"/>
  <beans:property name="password" value="secret01"/>
  <beans:property name="baseEnvironmentProperties">
      <beans:map>
        <beans:entry>
          <beans:key>
            <beans:value>java.naming.referral</beans:value>
          </beans:key>
          <beans:value>follow</beans:value>
        </beans:entry>
      </beans:map>
    </beans:property>
  </beans:bean>

<beans:bean id="ldapUserService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
  <beans:constructor-arg index="0">
    <beans:bean class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
      <beans:constructor-arg value="ou=Employees,DC=,fictional,DC=company"/>
	 <beans:constructor-arg value="userPrincipalName={0}"/>
      <beans:constructor-arg ref="contextSource"/>
      <beans:property name="searchSubtree" value="true" />
    </beans:bean>
  </beans:constructor-arg>
  <beans:constructor-arg index="1">
    <beans:bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
      <beans:constructor-arg ref="contextSource"/>
      <beans:constructor-arg value="ou=Groups,dc=fictional,dc=company"/>
      <beans:property name="groupRoleAttribute" value="cn"/>
      <beans:property name="searchSubtree" value="true" />
      <beans:property name="convertToUpperCase" value="false"/>
      <beans:property name="rolePrefix" value=""/>
   </beans:bean>
  </beans:constructor-arg>
</beans:bean>

</beans:beans>
Make sure to restart Tomcat.

Open up a browser that supports SPNEGO (Firefox) and add the url of your openkm server to trusted urls (open about:config, search for 'network.n' and add 'openkm.fictional.company' in this case to the list of trusted urls)

If you have a valid kerberos ticket you can then log in to your OpenKM via http://openkm.fictional.company:8080/OpenKM OR log in manually via http://openkm.fictional.company:8080/OpenKM/login.jsp where you type in your AD username/pass. I still have to figure out how to make the server redirect me to login page if the spnego fails, but it's not critical at this point.
Hi dejanfc,

I'm trying to implement SSO with windows AD to OpenKM community version 6.3. Can you please tell me a path to follow or any latest article written by you.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest