Author: sohil.shah(a)jboss.com
Date: 2009-09-18 18:05:48 -0400 (Fri, 18 Sep 2009)
New Revision: 800
Added:
authz/trunk/documentation/reference-guide/en/modules/getting-started.xml
Modified:
authz/trunk/documentation/reference-guide/en/master.xml
authz/trunk/documentation/reference-guide/en/modules/framework.xml
Log:
more documentation
Modified: authz/trunk/documentation/reference-guide/en/master.xml
===================================================================
--- authz/trunk/documentation/reference-guide/en/master.xml 2009-09-17 18:17:49 UTC (rev
799)
+++ authz/trunk/documentation/reference-guide/en/master.xml 2009-09-18 22:05:48 UTC (rev
800)
@@ -17,9 +17,8 @@
<xi:include
xmlns:xi="http://www.w3.org/2001/XInclude"
href="modules/concepts.xml"/>
<xi:include
xmlns:xi="http://www.w3.org/2001/XInclude"
href="modules/architecture.xml"/>
- <!--
- <xi:include
xmlns:xi="http://www.w3.org/2001/XInclude"
href="modules/sample.xml"/>
- -->
+ <xi:include
xmlns:xi="http://www.w3.org/2001/XInclude"
href="modules/getting-started.xml"/>
+
<xi:include
xmlns:xi="http://www.w3.org/2001/XInclude"
href="modules/framework.xml"/>
<xi:include
xmlns:xi="http://www.w3.org/2001/XInclude"
href="modules/authz-component-spec.xml"/>
<!--
Modified: authz/trunk/documentation/reference-guide/en/modules/framework.xml
===================================================================
--- authz/trunk/documentation/reference-guide/en/modules/framework.xml 2009-09-17 18:17:49
UTC (rev 799)
+++ authz/trunk/documentation/reference-guide/en/modules/framework.xml 2009-09-18 22:05:48
UTC (rev 800)
@@ -178,6 +178,18 @@
is composed of. It is processed by the
<emphasis>PolicyComposer</emphasis> service. The
<emphasis>PolicyComposer</emphasis> generates the low-level policy instance.
The <emphasis>PolicyComposer</emphasis> shields the Application
Developer from low-level policy processing and representation details.
</para>
+ <para>
+ Provisioning is an open ended aspect of authorization. It spans from
<emphasis>static xml based provisioning</emphasis> on one end to a fully
dynamic/centralized management tool based provisioning.
+ Here are some of the provisioning scenarios that are possible:
+ <itemizedlist>
+ <listitem>
+ </listitem>
+ <listitem>
+ </listitem>
+ <listitem>
+ </listitem>
+ </itemizedlist>
+ </para>
<sect3>
<title>Provisioning Phase Life Cycle</title>
<para>
Added: authz/trunk/documentation/reference-guide/en/modules/getting-started.xml
===================================================================
--- authz/trunk/documentation/reference-guide/en/modules/getting-started.xml
(rev 0)
+++ authz/trunk/documentation/reference-guide/en/modules/getting-started.xml 2009-09-18
22:05:48 UTC (rev 800)
@@ -0,0 +1,439 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<chapter id="getting-started">
+ <chapterinfo>
+ <author>
+ <firstname>Sohil</firstname>
+ <surname>Shah</surname>
+ <email>sshah(a)redhat.com</email>
+ </author>
+ </chapterinfo>
+ <title>Getting Started</title>
+ <sect1>
+ <title>End-to-End Development Process</title>
+ <para>
+ The Development Process for the framework is split into three steps.
+ </para>
+ <sect2>
+ <title>Core Application/Infrastructure Development</title>
+ <para>
+ This is where the <emphasis role="bold">Application
Developers</emphasis> develop their applications without any concern of embedding
any security checking logic inside their implementation.
+ Basically, think of it as developing an application that does not have any
knowledge of security functionality.
+ </para>
+ <para>
+ <programlisting>
+ <![CDATA[
+public class Pojo
+{
+ private String sensitiveData;
+
+ public Pojo()
+ {
+
+ }
+
+ public String getSensitiveData()
+ {
+ return this.sensitiveData;
+ }
+
+ public void setSensitiveData(String sensitiveData)
+ {
+ this.sensitiveData = sensitiveData;
+ }
+}
+ ]]>
+ </programlisting>
+ </para>
+ <para>
+ This shows a very simple POJO that carries some sensitive data within one of its
fields named: <emphasis>sensitiveData</emphasis>.
+ This data is private and is accessible via standard get/set methods.
+ <emphasis role="bold">Note:</emphasis> This is simple
application code and it has no knowledge about the existence of a security service
+ </para>
+ </sect2>
+ <sect2>
+ <title>Enforcement Layer</title>
+ <para>
+ This is the <emphasis>cross cutting</emphasis> layer of the
application that introduces <emphasis>authorization functionality</emphasis>
to an otherwise authorization agnostic application. This layer makes the "Enforcement
Phase" possible.
+ </para>
+ <para>
+ Development of this layer is primarily the responsibility of a <emphasis
role="bold">System Integrator</emphasis> or a <emphasis
role="bold">Platform Developer</emphasis>.
+ The <emphasis role="bold">Application Developer</emphasis>
typically integrates it via
+ configuration as a <emphasis>container service</emphasis>.
+ </para>
+ <para>
+ The <emphasis>Enforcement Layer</emphasis> is integrated as a
<emphasis>JBoss AOP Interceptor</emphasis>, for the POJO application in this
example.
+ </para>
+ <para>
+ <programlisting>
+ <![CDATA[
+<aop>
+ <bind pointcut="execution(*
org.jboss.security.authz.samples.pojo.Pojo->*(..))">
+ <interceptor
class="org.jboss.security.authz.samples.pojo.enforcement.SecurityInterceptor"/>
+ </bind>
+</aop>
+ ]]>
+ </programlisting>
+ </para>
+ <para>
+ This <emphasis>jboss-aop.xml</emphasis> specifies the scope of code
weaving to integrate the <emphasis>SecurityInterceptor</emphasis>. In this
case it says,
+ intercept all method calls on
<emphasis>org.jboss.security.authz.samples.pojo.Pojo</emphasis>. The scope of
interception can be increased/decreased based
+ on application requirements/design
+ </para>
+ <para>
+ <emphasis role="bold">Security Interceptor</emphasis>
explanation:
+ <programlisting>
+ <![CDATA[
+MethodInvocation methodInvocation = (MethodInvocation)invocation;
+Object pojoBeingAccessed = methodInvocation.getTargetObject();
+Method methodBeingCalled = methodInvocation.getMethod();
+ ]]>
+ </programlisting>
+ </para>
+ <para>
+ Gets information about the POJO instance being accessed <emphasis
role="bold">Resource</emphasis>, and the method being invoked
<emphasis role="bold">Action</emphasis>
+ </para>
+ <para>
+ <programlisting>
+ <![CDATA[
+Identity identity = new Identity();
+identity.setName(session.getUsername());
+
+Roles roles = new Roles();
+if(session.getRoles() != null)
+{
+ for(String roleName: session.getRoles())
+ roles.addName(roleName);
+}
+
+//Resource Component
+URIResource resource = new URIResource();
+resource.setUri(new URI(pojoBeingAccessed.getClass().getName()));
+
+//Action Component
+Object action = null;
+if(methodBeingCalled.getName().startsWith("get"))
+{
+ action = new Read();
+}
+else if(methodBeingCalled.getName().startsWith("set"))
+{
+ action = new Write();
+}
+ ]]>
+ </programlisting>
+ Populating <emphasis role="bold">Authz Components</emphasis>
with runtime application state. In this example, its populating the Identity
<emphasis>(Subject)</emphasis>, Roles
<emphasis>(Subject)</emphasis>,
+ URIResource <emphasis>(Resource)</emphasis>, and Read/Write
<emphasis>(Action)</emphasis> components.
+ </para>
+ <para>
+ <programlisting>
+ <![CDATA[
+//Create an EnforcementContext and start the "Enforcement Phase" with the
security framework
+EnforcementContext context = new EnforcementContext();
+context.setIgnoreCache(true);
+context.setAttribute("pojo", resource);
+context.setAttribute("method", action);
+context.setAttribute("identity", identity);
+context.setAttribute("roles", roles);
+
+//Process the result from Enforcement Phase execution
+EnforcementResponse response = this.getEnforcer().checkAccess(context);
+
+if(response.isAccessGranted())
+{
+ //Access to the Pojo is granted.....Proceed..
+ return invocation.invokeNext();
+}
+else
+{
+ //Throw appropriate exception or handle it according to what the requirements
are.........
+ throw new IllegalAccessException("Pojo Access Denied!!!");
+}
+ ]]>
+ </programlisting>
+ Creates an <emphasis
role="bold">EnforcementContext</emphasis> populated with the above
<emphasis role="bold">Authz Components</emphasis>, uses the
<emphasis role="bold">Enforcer</emphasis>
+ to perform a security check, and finally depending upon
<emphasis>Permit</emphasis> or <emphasis>Deny</emphasis> result,
either propagates the method call further or throws an
<emphasis>IllegalAccessException</emphasis>
+ </para>
+ </sect2>
+ <sect2>
+ <title>Provisioning Layer</title>
+ <para>
+ This is the provisioning aspect of authorization. This layer provides
<emphasis>policy management</emphasis>
+ capabilities within the context of functional requirements of the application in
question. This layer makes the "Provisioning Phase" possible.
+ </para>
+ <para>
+ <programlisting>
+ <![CDATA[
+// SetUp Resource
+URIResource resource = new URIResource();
+resource.setUri(new URI(Pojo.class.getName()));
+
+Read read = new Read();
+Roles readRoles = new Roles();
+readRoles.setMustMatchAll(false);
+readRoles.addName("regular");
+readRoles.addName("/blah1/blah2/blah3");
+
+Write write = new Write();
+Roles writeRoles = new Roles();
+writeRoles.setMustMatchAll(false);
+writeRoles.addName("admin");
+ ]]>
+ </programlisting>
+ The above code sets up the state of the <emphasis
role="bold">Authz Components</emphasis> used to generate a specific
<emphasis>policy</emphasis>.
+ <itemizedlist>
+ <listitem>
+ Step 1: Specifies that the resource
"org.jboss.security.authz.samples.pojo.POJO" needs to be protected
+ </listitem>
+ <listitem>
+ Step 2: Specfies that the "getSensitiveData" method should be
accessible <emphasis>only</emphasis> by the specified roles
+ </listitem>
+ <listitem>
+ Step 3: Specifies that the "setSensitiveData" method should be
accessible <emphasis>only</emphasis> by the specified roles
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ <programlisting>
+ <![CDATA[
+// Setup the Context for the Composition with these components
+CompositionContext context = new CompositionContext();
+context.setPolicyTarget(resource);
+context.addPolicyRule(Effect.PERMIT, read, readRoles,"allowExpression");
+context.addPolicyRule(Effect.PERMIT, write, writeRoles,"allowExpression");
+
+// Store the policy into the Policy Server
+this.getProvisioner().deploy(context);
+ ]]>
+ </programlisting>
+ Generates a <emphasis>CompositionContext</emphasis> populated with the
proper <emphasis role="bold">Authz Components</emphasis>.
+ The <emphasis>CompositionContext</emphasis> is then handed over to the
policy deployer to provision the single policy rule, that meets the
+ above criteria specified by the components.
+ </para>
+ </sect2>
+ <sect2>
+ <title>Full Picture</title>
+ <sect3>
+ <title>Sample Code: Core Application/Infrastructure
Development</title>
+ <para>
+ <programlisting>
+ <![CDATA[
+package org.jboss.security.authz.samples.pojo;
+
+/**
+ * This is the core application level component.
+ *
+ * Notice there is absolutely no security code here....It does not even know the security
service exists
+ *
+ * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
+ */
+public class Pojo
+{
+ private String sensitiveData;
+
+ public Pojo()
+ {
+
+ }
+
+ public String getSensitiveData()
+ {
+ return this.sensitiveData;
+ }
+
+ public void setSensitiveData(String sensitiveData)
+ {
+ this.sensitiveData = sensitiveData;
+ }
+}
+ ]]>
+ </programlisting>
+ </para>
+ </sect3>
+ <sect3>
+ <title>Sample Code: Enforcement Layer</title>
+ <para>
+ jboss-app.xml
+ <programlisting>
+ <![CDATA[
+<aop>
+ <bind pointcut="execution(*
org.jboss.security.authz.samples.pojo.Pojo->*(..))">
+ <interceptor
class="org.jboss.security.authz.samples.pojo.enforcement.SecurityInterceptor"/>
+ </bind>
+</aop>
+ ]]>
+ </programlisting>
+ </para>
+ <para>
+ <programlisting>
+ <![CDATA[
+/**
+ * A sample Enforcement Interceptor used to inject the security service into the
application
+ *
+ * The scope of interception can be increased/decreased depending upon the
application's security requirements
+ *
+ * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
+ */
+public class SecurityInterceptor implements Interceptor
+{
+ private static Logger log = Logger.getLogger(SecurityInterceptor.class);
+
+ public String getName()
+ {
+ return this.getClass().getName();
+ }
+
+ private PolicyEnforcementPoint getEnforcer()
+ {
+ return
(PolicyEnforcementPoint)ServiceContainer.lookup("/agent/LocalEnforcementPoint");
+ }
+ public Object invoke(Invocation invocation) throws Throwable
+ {
+ try
+ {
+ MethodInvocation methodInvocation = (MethodInvocation)invocation;
+
+ Object pojoBeingAccessed = methodInvocation.getTargetObject();
+ Method methodBeingCalled = methodInvocation.getMethod();
+
+ //Get the runtime application state (AuthenticatedSession) from ThreadLocal
+ AuthenticatedSession session =
(AuthenticatedSession)AuthenticatedSession.activeSession.get();
+ if(session == null)
+ {
+ //Anonymous access
+ session = new AuthenticatedSession();
+ session.setUsername("anonymous");
+ session.addRole("anonymous");
+ }
+
+ //Properly propagate runtime application state to the state of appropriate "Authz
Components"
+ //Subject Components
+ Identity identity = new Identity();
+ identity.setName(session.getUsername());
+
+ Roles roles = new Roles();
+ if(session.getRoles() != null)
+ {
+ for(String roleName: session.getRoles())
+ roles.addName(roleName);
+ }
+
+ //Resource Component
+ URIResource resource = new URIResource();
+ resource.setUri(new URI(pojoBeingAccessed.getClass().getName()));
+
+ //Action Component
+ Object action = null;
+ if(methodBeingCalled.getName().startsWith("get"))
+ {
+ action = new Read();
+ }
+ else if(methodBeingCalled.getName().startsWith("set"))
+ {
+ action = new Write();
+ }
+
+ //Create an EnforcementContext and start the "Enforcement Phase" with the
security framework
+ EnforcementContext context = new EnforcementContext();
+ context.setIgnoreCache(true);
+ context.setAttribute("pojo", resource);
+ context.setAttribute("method", action);
+ context.setAttribute("identity", identity);
+ context.setAttribute("roles", roles);
+
+ //Process the result from Enforcement Phase
execution-------------------------------------------------------------------------------------------------------------
+ EnforcementResponse response = this.getEnforcer().checkAccess(context);
+
+ if(response.isAccessGranted())
+ {
+ //Access to the Pojo is granted.....Proceed..
+ return invocation.invokeNext();
+ }
+ else
+ {
+ //Throw appropriate exception or handle it according to what the requirements
are.........
+ throw new IllegalAccessException("Pojo Access Denied!!!");
+ }
+ }
+ finally
+ {
+ }
+ }
+}
+ ]]>
+ </programlisting>
+ </para>
+ </sect3>
+ <sect3>
+ <title>Sample Code: Provisioning Layer</title>
+ <para>
+ <programlisting>
+ <![CDATA[
+/**
+ * The Provisioning component that is in charge of managing the security policies of the
application
+ *
+ * This is usually accessed via a GUI tool or the application's security dashboard
etc
+ *
+ * @author <a href="mailto:sshah@redhat.com">Sohil Shah</a>
+ */
+public class SecurityProvisioning
+{
+ private static Logger log = Logger.getLogger(SecurityProvisioning.class);
+
+ public void bootup()
+ {
+ try
+ {
+ // Provision POJO Policy
+ this.provisionPOJOPolicy();
+
+ Set<Policy> policies = this.getProvisioner().readAllPolicies();
+ for(Policy policy: policies)
+ {
+ log.info("------------------------------------------------------------------------------");
+ log.info(policy.generateSystemPolicy());
+ }
+ }
+ catch(Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ private void provisionPOJOPolicy() throws Exception
+ {
+ // SetUp Resource
+ URIResource resource = new URIResource();
+ resource.setUri(new URI(Pojo.class.getName()));
+
+ Read read = new Read();
+ Roles readRoles = new Roles();
+ readRoles.setMustMatchAll(false);
+ readRoles.addName("regular");
+ readRoles.addName("/blah1/blah2/blah3");
+
+ Write write = new Write();
+ Roles writeRoles = new Roles();
+ writeRoles.setMustMatchAll(false);
+ writeRoles.addName("admin");
+
+ // Setup the Context for the Composition with these components
+ CompositionContext context = new CompositionContext();
+ context.setPolicyTarget(resource);
+ context.addPolicyRule(Effect.PERMIT, read, readRoles,"allowExpression");
+ context.addPolicyRule(Effect.PERMIT, write, writeRoles,"allowExpression");
+
+ // Store the policy into the Policy Server
+ this.getProvisioner().deploy(context);
+ }
+
+ private PolicyProvisioner getProvisioner()
+ {
+ return (PolicyProvisioner)
ServiceContainer.lookup("/agent/LocalPolicyProvisioner");
+ }
+}
+ ]]>
+ </programlisting>
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>