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:
Access Rights: You must define the access rights given to the role defined. Possible values are:
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”
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:
Table 13.1. Portal CMS Permission Matrix:
Permissions | Allowed Actions | Implies |
---|---|---|
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 |
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>
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.
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
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.
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
Usually ones should not care much about those mappings as the portal will by itself switch to the most appropriate mapping.
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.
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
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(); }
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); }
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);