Change default role names

By default application comes with two connection roles named "ROLE_USER" and "ROLE_ADMIN". Any OpenKM user must have assigned one of these roles to loggin.

Change the default roles

Change roles usually is not an easy task, we recommend have a backup before start working on it.

Is a good practice, first test this kind of changes on a development environment before trying on your production.

To change the default roles must be done three actions:

  1. Change the roles name at administration.
  2. Modify the contents of the file applicationContext.xml into the "$TOMCAT/webapp/OpenKM.war".
  3. Update existing database roles name "ROLE_USER" and "ROLE_ADMIN" to new names.

You can modify the file "applicationContext.xml" into the "$TOMCAT_HOME/webapps/OpenKM.war" or modify the exploded war file at "$TOMCAT_HOME/webapp/OpenKM/WEB-INF/applicationContext.xml".

Take in mind each time the "OpenKM.war" file is modified the contents of "$TOMCAT_HOME/webapp/OpenKM" folder will be completely cleaned.

Sections into the "appContext.xml" to be modified:

Mandatory:

<security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />

Optional:

<!-- Remove prefix to be able of use custom roles -->
<beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
    <beans:property name="rolePrefix" value="ROLE_"/>
</beans:bean>

  • Go to Administration > Configuration parameters.
  • Change the values of parameters "default.admin.role" and "default.admin.role". Also can be done from Database query, see the next SQL script.
  • Go to Administration > Utilities > Database query and execute the role name update sql:
-- Optionally the configuration parameters can be set from SQL
UPDATE OKM_CONFIG SET CFG_VALUE='NEW_ROLE_USER_NAME' WHERE CFG_KEY='default.user.role';
UPDATE OKM_CONFIG SET CFG_VALUE='NEW_ROLE_ADMIN_NAME' WHERE CFG_KEY='default.admin.role';
-- Update security table
UPDATE OKM_NODE_ROLE_PERMISSION SET NRP_ROLE='NEW_ROLE_USER_NAME' WHERE NRP_ROLE='ROLE_USER';
UPDATE OKM_NODE_ROLE_PERMISSION SET NRP_ROLE='NEW_ROLE_ADMIN_NAME' WHERE NRP_ROLE='ROLE_ADMIN';
-- Insert new roles
INSERT INTO OKM_ROLE (ROL_ID, ROL_ACTIVE) VALUES ('NEW_ROLE_USER_NAME', 'T');
INSERT INTO OKM_ROLE (ROL_ID, ROL_ACTIVE) VALUES ('NEW_ROLE_ADMIN_NAME', 'T');
-- Update user roles
UPDATE OKM_USER_ROLE SET UR_ROLE='NEW_ROLE_USER_NAME' WHERE UR_ROLE='ROLE_USER';
UPDATE OKM_USER_ROLE SET UR_ROLE='NEW_ROLE_ADMIN_NAME' WHERE UR_ROLE='ROLE_ADMIN';
-- Remove older roles
DELETE FROM OKM_ROLE WHERE ROL_ID IN ('ROLE_USER', 'ROLE_ADMIN');

  • Stop the application.
  • Modify the contents of the file "applicationContext.xml".
  • Start the application.

Sample of appContext.xml file

The "ROLE_USER" has been modified to "OPENKM_ROLE_USER".

The "ROLE_ADMIN" has been modified to "OPENKM_ROLE_ADMIN".

The contents of the "applicationContext.xml" can be modified, take only as a reference.

<?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:jee="http://www.springframework.org/schema/jee"
             xmlns:jaxws="http://cxf.apache.org/jaxws"
             xmlns:jaxrs="http://cxf.apache.org/jaxrs"
             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/jee
                                 http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
                                 http://cxf.apache.org/jaxws
                                 http://cxf.apache.org/schemas/jaxws.xsd
                                 http://cxf.apache.org/jaxrs
                                 http://cxf.apache.org/schemas/jaxrs.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>

  <!-- SOAP -->
  <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>

  <!-- OpenCMIS -->
  <jaxws:endpoint id="cmisNavigationService" implementor="org.apache.chemistry.opencmis.server.impl.webservices.NavigationService" address="/cmis/NavigationService"/>
  <jaxws:endpoint id="cmisPolicyService" implementor="org.apache.chemistry.opencmis.server.impl.webservices.PolicyService" address="/cmis/PolicyService"/>
  <jaxws:endpoint id="cmisDiscoveryService" implementor="org.apache.chemistry.opencmis.server.impl.webservices.DiscoveryService" address="/cmis/DiscoveryService"/>
  <jaxws:endpoint id="cmisMultiFilingService" implementor="org.apache.chemistry.opencmis.server.impl.webservices.MultiFilingService" address="/cmis/MultiFilingService"/>
  <jaxws:endpoint id="cmisRepositoryService" implementor="org.apache.chemistry.opencmis.server.impl.webservices.RepositoryService" address="/cmis/RepositoryService"/>
  <jaxws:endpoint id="cmisRelationshipService" implementor="org.apache.chemistry.opencmis.server.impl.webservices.RelationshipService" address="/cmis/RelationshipService"/>
  <jaxws:endpoint id="cmisVersioningService" implementor="org.apache.chemistry.opencmis.server.impl.webservices.VersioningService" address="/cmis/VersioningService"/>
  <jaxws:endpoint id="cmisObjectService" implementor="org.apache.chemistry.opencmis.server.impl.webservices.ObjectService" address="/cmis/ObjectService"/>
  <jaxws:endpoint id="cmisAclService" implementor="org.apache.chemistry.opencmis.server.impl.webservices.AclService" address="/cmis/ACLService"/>

  <!-- REST -->
  <jaxrs:server id="restAuth" address="/rest/auth">
    <jaxrs:serviceBeans>
      <beans:bean class="com.openkm.rest.endpoint.AuthService"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
      <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true"/>
        <property name="supportUnwrapped" value="true"/>
      </bean>
    </jaxrs:providers>
  </jaxrs:server>
  <jaxrs:server id="restDocument" address="/rest/document">
    <jaxrs:serviceBeans>
      <beans:bean class="com.openkm.rest.endpoint.DocumentService"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
      <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true"/>
        <property name="supportUnwrapped" value="true"/>
      </bean>
    </jaxrs:providers>
  </jaxrs:server>
  <jaxrs:server id="restFolder" address="/rest/folder">
    <jaxrs:serviceBeans>
      <beans:bean class="com.openkm.rest.endpoint.FolderService"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
      <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true"/>
        <property name="supportUnwrapped" value="true"/>
      </bean>
    </jaxrs:providers>
  </jaxrs:server>
  <jaxrs:server id="restMail" address="/rest/mail">
    <jaxrs:serviceBeans>
      <beans:bean class="com.openkm.rest.endpoint.MailService"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
      <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true"/>
        <property name="supportUnwrapped" value="true"/>
      </bean>
    </jaxrs:providers>
  </jaxrs:server>
  <jaxrs:server id="restNote" address="/rest/note">
    <jaxrs:serviceBeans>
      <beans:bean class="com.openkm.rest.endpoint.NoteService"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
      <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true"/>
        <property name="supportUnwrapped" value="true"/>
      </bean>
    </jaxrs:providers>
  </jaxrs:server>
  <jaxrs:server id="restPropertyGroup" address="/rest/propertyGroup">
    <jaxrs:serviceBeans>
      <beans:bean class="com.openkm.rest.endpoint.PropertyGroupService"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
      <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true"/>
        <property name="supportUnwrapped" value="true"/>
      </bean>
    </jaxrs:providers>
  </jaxrs:server>
  <jaxrs:server id="restSearch" address="/rest/search">
    <jaxrs:serviceBeans>
      <beans:bean class="com.openkm.rest.endpoint.SearchService"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
      <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true"/>
        <property name="supportUnwrapped" value="true"/>
      </bean>
    </jaxrs:providers>
  </jaxrs:server>
  <jaxrs:server id="restRepository" address="/rest/repository">
    <jaxrs:serviceBeans>
      <beans:bean class="com.openkm.rest.endpoint.RepositoryService"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
      <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true"/>
        <property name="supportUnwrapped" value="true"/>
      </bean>
    </jaxrs:providers>
  </jaxrs:server>
  <jaxrs:server id="restProperty" address="/rest/property">
    <jaxrs:serviceBeans>
      <beans:bean class="com.openkm.rest.endpoint.PropertyService"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
      <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true"/>
        <property name="supportUnwrapped" value="true"/>
      </bean>
    </jaxrs:providers>
  </jaxrs:server>
  <jaxrs:server id="restTest" address="/rest/test">
    <jaxrs:serviceBeans>
      <beans:bean class="com.openkm.rest.endpoint.TestService"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
      <bean class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="dropRootElement" value="true"/>
        <property name="supportUnwrapped" value="true"/>
      </bean>
    </jaxrs:providers>
  </jaxrs:server>

  <security:global-method-security secured-annotations="enabled"/>

  <!-- Remove prefix to be able of use custom roles -->
  <beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
    <beans:property name="rolePrefix" value="OPENKM_ROLE_"/>
  </beans:bean>

  <!-- OpenCMIS -->
  <beans:bean id="CmisLifecycleBean" class="com.openkm.cmis.CmisLifecycleBean">
    <beans:property name="cmisServiceFactory" ref="CmisServiceFactory"/>
  </beans:bean>
  <beans:bean id="CmisServiceFactory" class="com.openkm.cmis.CmisServiceFactory"/>

  <!-- 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>

  <!-- OpenCMIS (Browser) using Basic authentication -->
  <security:http pattern="/cmis/browser/**" create-session="stateless">
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
    <security:http-basic/>
  </security:http>

  <!-- OpenCMIS (AtomPub) using Basic authentication -->
  <security:http pattern="/cmis/atom/**" create-session="stateless">
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
    <security:http-basic/>
  </security:http>

  <!-- OpenCMIS (AtomPub) using Basic authentication -->
  <security:http pattern="/cmis/atom11/**" create-session="stateless">
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
    <security:http-basic/>
  </security:http>

  <!-- REST -->
  <security:http pattern="/services/rest/**" create-session="stateless">
    <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/>
    <security:http-basic/>
  </security:http>

  <!-- Additional filter chain for normal users, matching all other requests -->
  <!-- http://info.michael-simons.eu/2011/01/28/disable-jsessionid-path-parameter-in-java-web-applications/ -->
  <security:http access-decision-manager-ref="accessDecisionManager" access-denied-page="/unauthorized.jsp">

    <!-- 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="OPENKM_ROLE_ADMIN"/>
    <security:intercept-url pattern="/mobile/**" access="IS_AUTHENTICATED_FULLY"/>

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

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

    <!-- Login page -->
    <security:form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=1"/>

  </security:http>

  <!-- Needed for changing default role prefix -->
  <beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
    <beans:property name="decisionVoters">
      <beans:list>
        <beans:bean class="org.springframework.security.web.access.expression.WebExpressionVoter"/>
        <beans:ref bean="roleVoter"/>
        <beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
      </beans:list>
    </beans:property>
  </beans:bean>

  <!-- Security access logger -->
  <beans:bean id="loggerListener" class="com.openkm.spring.LoggerListener"/>

  <jee:jndi-lookup id="dataSource" jndi-name="jdbc/OpenKMDS" resource-ref="true"/>

  <!-- Security configuration moved to $CATALINA_HOME/OpenKM.xml -->
  <!-- WINFIX
  <security:authentication-manager alias="authenticationManager">
      <security:authentication-provider>
          <security:password-encoder hash="md5"/>
          <security:jdbc-user-service
              data-source-ref="dataSource"
              users-by-username-query="select usr_id, usr_password, 1 from OKM_USER where usr_id=? and usr_active='T'"
              authorities-by-username-query="select ur_user, ur_role from OKM_USER_ROLE where ur_user=?"/>
      </security:authentication-provider>
  </security:authentication-manager>
  WINFIX -->
</beans:beans>

Tools

Download the changeRolesTools.zip.

It includes:

  • change_roles.sh script to modify the applicationContext.xml file.
  • path folder to patch "OpenKM.war" file.

To patch "OpenKM.war" file, copy the file into patch folder and then execute the patch.sh script ( or patch.bat file on Windows ).