Chapter 13. Security

Julien Viet

13.1. Securing Portal Objects

This section describes how to secure portal objects (portal instances, pages, and portlet instances), using the JBoss Portal *-object.xml descriptor OR portlet-instances.xml descriptor. View the User Guide for information on how to secure objects using the Management Portlet.

Securing portal objects declaratively, is done through the *-object.xml ( Section 6.2.1, “*-object.xml” ), for Portal Instances and Pages, or the portlet-instances.xml ( Section 6.2.2, “portlet-instances.xml” ) for Portlet Instances. The portion you will be adding to each object is denoted by the <security-constraint> tag:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE deployments PUBLIC
   "-//JBoss Portal//DTD Portal Object 2.6//EN"
   "http://www.jboss.org/portal/dtd/portal-object_2_6.dtd">
<deployments>
   <deployment>
      <parent-ref>default</parent-ref>
      <if-exists>overwrite</if-exists>
      <properties/>
      <page>
         <page-name>MyPage</page-name>
         <window>
            <window-name>HelloWorldPortletPageWindow</window-name>
            <instance-ref>HelloWorldPortletPageInstance</instance-ref>
            <region>center</region>
            <height>0</height>
         </window>
         <security-constraint>
            <policy-permission>
               <action-name>viewrecursive</action-name>
               <unchecked/>
            </policy-permission>
         </security-constraint>
      </page>
   </deployment>
</deployments>

The based principle of the security mechanism is that everything is restricted unless you grant privileges. You grant privilege on a portal node by adding a security constraint as explained here:

<security-constraint>
   <policy-permission>
      <unchecked/>
      <action-name>viewrecursive</action-name>
   </policy-permission>
</security-constraint>

The example above will grant the view privilege to anyone (unchecked role) to the current object and any child object recursively.

The security contraint portion is worth taking a look at, in an isolated fashion. It allows you to secure a specific window/page/portal-instance based on a user's role.

Role definition: You must define a role that this security constraint will apply to. Possible values are:

  • <unchecked/> Anyone can view this page.
  • <role-name>SOMEROLE</role-name> Access to this page is limited to the defined role.

Access Rights: You must define the access rights given to the role defined. Possible values are:

  • view Users can view the page.
  • viewrecursive Users can view the page and child pages.
  • personalize Users are able to view AND personalize the page.
  • personalizerecursive Users are able to view AND personalize the page AND its child pages.

Restricting access

Out of the box the default portal as a viewrecursive right for all the users, it means that whenever a page is added, this page will be seen by any user. To restrict access to this page, the default portal security constraint must be changed from viewrecursive to view, and viewrecursive security constraints must be added to its children so that they can be viewed except the one you want to restrict access to.

We provide three live samples of this descriptor, here Section 6.2.2, “portlet-instances.xml” , Section 6.4.1, “Defining a new portal page” ,and Section 6.4.2, “Defining a new portal instance”

13.2. Securing the Content Management System

The JBoss Portal CMS system consists of a directory structure of Files organized unto their respective Folders. Both Files and Folders are considered to be CMS resources that can be secured based on portal Roles and/or Users.

The following features are supported by the fine grained security system of Portal CMS:

  • You can associate "Read", "Write", and "Manage" Permissions at the CMS node level. (Both Files and Folders are treated as CMS nodes)
  • The Permissions are propagated recursively down a folder hierarchy
  • Any Permissions specified explicitly on the CMS Node overrides the policy inherited via recursive propagation
  • You can manage the Permissions using the CMS Admin GUI tool via the newly added "Secure Node" feature

Table 13.1.  Portal CMS Permission Matrix:

PermissionsAllowed ActionsImplies
Read Read Contents of Folder, File and its versions N/A
Write Create and Update new Folder and File Read Access
Manage Delete/Copy/Move/Rename Folders and Files Read and Write Access

13.2.1. CMS Security Configuration

The configuration for the CMS Security service is specified in the jboss-portal.sar/portal-cms.sar/META-INF/jboss-service.xml file. The portion of the configuration relevant for securing the CMS service is listed as follows:

<!--  interceptor factory where all cms interceptors are registered -->
<mbean
	code="org.jboss.portal.server.impl.invocation.JBossInterceptorStackFactory"
	name="portal:service=InterceptorStackFactory,type=Cms" xmbean-dd=""
	xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
	<xmbean />
	<depends-list optional-attribute-name="InterceptorNames">
		<depends-list-element>
			portal:service=Interceptor,type=Cms,name=ACL
		</depends-list-element>
		<depends-list-element>
			portal:service=Interceptor,type=Cms,name=ApprovalWorkflow
		</depends-list-element>
	</depends-list>
</mbean>

<!-- CMS Authorization Security Service -->
<mbean code="org.jboss.portal.cms.security.AuthorizationManagerImpl"
	name="portal:service=AuthorizationManager,type=cms" xmbean-dd=""
	xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
	<xmbean />
	<attribute name="JNDIName">
		java:portal/cms/AuthorizationManager
	</attribute>
	<depends optional-attribute-name="Provider"
		proxy-type="attribute">
		portal:service=AuthorizationProvider,type=cms
	</depends>
</mbean>
<mbean code="org.jboss.portal.cms.security.AuthorizationProviderImpl"
	name="portal:service=AuthorizationProvider,type=cms" xmbean-dd=""
	xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
	<xmbean />
	<depends optional-attribute-name="IdentityServiceController"
		proxy-type="attribute">
		portal:service=Module,type=IdentityServiceController
	</depends>
</mbean>

<!-- ACL Security Interceptor -->
<mbean code="org.jboss.portal.cms.impl.interceptors.ACLInterceptor"
	name="portal:service=Interceptor,type=Cms,name=ACL" xmbean-dd=""
	xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
	<xmbean />
	<attribute name="JNDIName">
		java:/portal/cms/ACLInterceptor
	</attribute>
	<attribute name="CmsSessionFactory">
		java:/portal/cms/CMSSessionFactory
	</attribute>
	<attribute name="IdentitySessionFactory">
		java:/portal/IdentitySessionFactory
	</attribute>
	<attribute name="DefaultPolicy">
		<policy>
			<!-- permissions on the root cms node -->
			<criteria name="path" value="/">
				<permission name="cms" action="read">
					<role name="Anonymous" />
				</permission>
				<permission name="cms" action="write">
					<role name="User" />
				</permission>
				<permission name="cms" action="manage">
					<role name="Admin" />
				</permission>
			</criteria>
			<!-- permissions on the default cms node -->
			<criteria name="path" value="/default">
				<permission name="cms" action="read">
					<role name="Anonymous" />
				</permission>
				<permission name="cms" action="write">
					<role name="User" />
				</permission>
				<permission name="cms" action="manage">
					<role name="Admin" />
				</permission>
			</criteria>
			<!-- permissions on the private/protected node -->
			<criteria name="path" value="/default/private">
				<permission name="cms" action="manage">
					<role name="Admin" />
				</permission>
			</criteria>
		</policy>
	</attribute>
	<depends optional-attribute-name="AuthorizationManager"
		proxy-type="attribute">
		portal:service=AuthorizationManager,type=cms
	</depends>
	<depends>portal:service=Hibernate,type=CMS</depends>
	<depends>
		portal:service=Module,type=IdentityServiceController
	</depends>
</mbean>
      		

13.3. Authentication with JBoss Portal

JBoss Portal relies on Java EE for the authentication of users. The Java EE authentication has its advantages and drawbacks. The main motivation for using Java EE security is the integration with the application server and the operational environment in which the portal is deployed. The servlet layer provides already the authentication functionnality and obviously it is not a responsibility of the portal. Whenever a user is authenticated by the servlet layer its security identity is propagated throughout the call stack in the different layers of the Java EE stack. The weaknesses are the lack of an explicit logout mechanism and the lack of dynamicity in the mapping of URL as security resources. However JBoss Portal improves that behavior when it is possible to do so.

13.3.1. Authentication configuration

JBoss Portal can be seen before all as a web application and therefore inherits all the configuration mechanisms related to web applications. The main entry point of the whole portal is the jboss-portal.sar/portal-server.war deployment which is the web application that defines and maps the portal servlet. Here you can configure various things

  • In the WEB-INF/web.xml you can change the authentication mode. The default authentication mechanism uses the form based authentication, however you can change it to any of the mechanism provided by the servlet specification.
  • In the WEB-INF/jboss-web.xml you can change the security domain used by the portal. The default security domain used by the portal is java:/jaas/portal. That setting is specific to the JBoss Application Server and how it binds the Java EE security to the operational environment. A security domain is a scope defined at the Application Server Level and defines usually a JAAS authentication stack. The portal security domain authentication stack is defined in the jboss-portal.sar/conf/login-config.xml and is dynamically deployed with the portal. The JBoss Application Server documentation is certainly the best reference for that topic.
  • The files login.jsp and error.jsp provide the pages used the form based authentication process. More information can be found in any good servlet documentation.

13.3.2. The portal servlet

The portal defines a single servlet to take care of all portal requests. The class name of that servlet is org.jboss.portal.server.servlet.PortalServlet. That servlet needs to be declared two times with different configurations otherwise the portal would not be able to know about some request details which are importants.

  • PortalServletWithPathMapping is used for path mapping mappings.
  • PortalServletWithDefaultServletMapping is used for the default servlet mapping.

The portal servlet is mapped four times with different semantics, the differences between the semantics are related to the transport layer. Each one of those for mappings will have the same request meaning for the portal beside the transport aspect. By default those mappings are

  • /* : the default access, does not define any security constraint. This is the default access that everybody uses.
  • /sec/* : the secured access, requires https usage. It is triggered when a portlet is defined as secure or when a secure portlet link is created. It requires the configuration of the https connector in JBoss Web. The JBoss Application Server documentation provides more information about it.
  • /auth/* : the authenticated access, requires the user to be authenticated to be used.
  • /authsec/* : combine thet two previous options into a single one.

Usually ones should not care much about those mappings as the portal will by itself switch to the most appropriate mapping.

13.4. Authorization with JBoss Portal

JBoss Portal defines a framework for authorization. The default implementation of that framework is based on the Java Authorization Contract for Containers (JACC) which is implemented by J2EE 1.4 Application Servers. This section of the documentation focuses on defining the framework and its usage and is not an attempt to define what authorization is or is not because it is out of scope of this context. Instead we will try to straightforwardly describe the framework and how it is used. No specific knowledge is expected about JACC although it is a recommanded read.

13.4.1. The portal permission

The org.jboss.portal.security.PortalPermission object is used to describe a permission for the portal. It extends the java.security.Permission class and any permission checked in the portal should extend the PortalPermission as well. That permission adds two fields to the Permission class

  • uri : is a string which represents an URI of the resource described by the permission.
  • collection : an object of class org.jboss.portal.security.PortalPermissionCollection which is used when the permission act as a container for other permissions. If that object exists then the uri field should be null as a portal permission represents an uri or acts as a container in an exclusive manner.

13.4.2. The authorization provider

The org.jboss.portal.security.spi.provider.AuthorizationDomain is an interface which provides access to several services.

public interface AuthorizationDomain
{
   String getType();
   DomainConfigurator getConfigurator();
   PermissionRepository getPermissionRepository();
   PermissionFactory getPermissionFactory();
}
            

  • org.jboss.portal.security.spi.provider.DomainConfigurator provides configuration access to an authorization domain. The authorization schema is very simple as it consists of bindings between URI, roles and permissions.
  • org.jboss.portal.security.spi.provider.PermissionRepository provides runtime access to the authorization domain. Usually it is used to retrieves the permissions for a specific role and URI. It is used at runtime by the framework to take security decisions.
  • org.jboss.portal.security.spi.provider.PermissionFactory is a factory to instantiate permissions for the specific domain. It is used at runtime to create permissions objects of the appropriate type by the security framework.

13.4.3. Making a programmatic security check

Making a security check is an easy thing as it consists in created a permission of the appropriate type and make a check against the org.jboss.portal.spi.auth.PortalAuthorizationManager service. That service is used by the portal to make security checks. It is connected to the different authorization providers in order to take decisions at runtime based on the type of the permission. Access to that service is done through the org.jboss.portal.spi.auth.PortalAuthorizationManagerFactory. The factory is a portal service which is usually injected in other services like that

<?xml version="1.0" encoding="UTF-8"?>
<server>
   ...
   <mbean
      code='MyService"
      name="portal:service=MyService">
	   <depends
         optional-attribute-name="PortalAuthorizationManagerFactory"
         proxy-type="attribute">portal:service=PortalAuthorizationManagerFactory</depends>
      ...
   </mbean>
   ...
</server>

It be injected in the servlet context of a war file in the file WEB-INF/jboss-portlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE portlet-app PUBLIC
   "-//JBoss Portal//DTD JBoss Portlet 2.6//EN"
   "http://www.jboss.org/portal/dtd/jboss-portlet_2_6.dtd">
<portlet-app>
   ...
   <service>
      <service-name>PortalAuthorizationManagerFactory</service-name>
      <service-class>
      org.jboss.portal.security.spi.auth.PortalAuthorizationManagerFactory
      </service-class>
      <service-ref>:service=PortalAuthorizationManagerFactory</service-ref>
   </service>
   ...
</portlet-app>

Here is an example of how a security check is made for a specific page

PortalAuthorizationManager pam = factory.getManager();
PortalObjectId id = page.getId();
PortalObjectPermission perm = new PortalObjectPermission(id, PortalObjectPermission.VIEW_MASK);
if (pam.checkPermission(perm) == false)
{
   System.out.println("Current is not authorization to view page " + id);
}

13.4.4. Configuring an authorization domain

Configuring a domain can be done through the DomainConfigurator interface

public interface DomainConfigurator
{
   Set getSecurityBindings(String uri);
   void setSecurityBindings(String uri, Set securityBindings)
           throws SecurityConfigurationException;
   void removeSecurityBindings(String uri) throws SecurityConfigurationException;
}

The various methods of that interface allows to configure security bindings for a given resource where a resource is naturally identified by an URI. The org.jboss.portal.security.RoleSecurityBinding object is an object which encapsulate a role name and a set of actions bound to this role.

RoleSecurityBinding binding1 = new RoleSecurityBinding(Collections.singleton("view"), "Admin");
RoleSecurityBinding binding2 = new RoleSecurityBinding(Collections.singleton("view"), "User");
Set bindings = new HashSet();
bindings.add(binding1);
bindings.add(binding2);
configurator.setSecurityBinding(pageURI, bindings);