Purpose
Allow for flexible configuration of authorization logic within the framework. The authorization checks should be well exposed (i.e. visible). It should be straight forward to add new checks, or modify existing ones. It should be possible to use GaP as the authorization engine, alternative engines and their combination.
Proposed approach
Use ACEGI declarative authorization proxy factories, providing implementations necessary to support GaP back-end.
Example
Here is a modified example of using ACEGIs' MethodSecurityInterceptor
to configure authorization checks for checking permissions on performing various actions with portlet definition (or its derivatives, like portlet window):
<!-- authorization check proxy factory targeting key methods that handle portlet definitions --> <bean id="portletEntitySecurity" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"> <property name="authenticationManager"><ref bean="authenticationManager"/></property> <property name="portletDefinitionDecisionManager"><ref bean="accessDecisionManager"/></property> <property name="objectDefinitionSource"> <value> org.jasig.portal.portlet.rendering.MultithreadedPortletRenderingModel.*=ACTIVITY_RENDER org.jasig.portal.portlet.registry.general.IPortletDefinitionRegistry.create*=ACTIVITY_CREATE org.jasig.portal.portlet.registry.general.IPortletDefinitionRegistry.get*=ACTIVITY_RENDER org.jasig.portal.portlet.registry.general.IPortletDefinitionRegistry.update*=ACTIVITY_UPDATE </value> </property> </bean> <!-- access decision manager for checking permissions on portlet definitions --> <bean id="portletDefinitionDecisionManager" class="org.acegisecurity.vote.UnanimousBased"> <property name="decisionVoters"> <list> <bean class="org.jasig.portal.security.acegi.PermissionVoter"> <property name="permissionOwner" value="framework"/> <property name="activityPrefix" value="ACTIVITY_"/> <property name="targetResolver"> <bean class="org.jasig.portal.security.acegi.PortletDefinitionIdResolver"/> </property> <property name="authorizationService"> <ref bean="authorizationService"/> </property> </bean> </list> </property> </bean>
Suggested use pattern
The PermissionVoter
is provided with the permissionOwner
property, and a helper bean that can resolve permission targets (targetResolver
). The example above suggests that a given access decision manager should be associated with a single owner and a single target type. This should make configuration more transparent and more efficient. For instance, a different decision manager, portletDeploymentDecisionManager
, would be created to check authorization to publish portlets.
Mixed configurations
The described approach can be very flexible considering that additional permission voters can be configured for the same decision manager. For instance, if the installation maintains alternative set of permission information (let's say a role-based permission information that's entirely separate from GaP), then a second voter, RoleVoter
could be configured in parallel with the existing PermissionVoter
(this would require PermissionVoter
to abstain in situations when it doesn't have enough information to make a decision - right now it defaults to denying access).