You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by cl...@apache.org on 2015/02/15 17:53:49 UTC

jena git commit: Updated fuseki example files added documentation to example code.

Repository: jena
Updated Branches:
  refs/heads/master e0e8dba47 -> beb73c4a7


Updated fuseki example files
added documentation to example code.


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/beb73c4a
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/beb73c4a
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/beb73c4a

Branch: refs/heads/master
Commit: beb73c4a777c69dceb3317900476710399aa6bf0
Parents: e0e8dba
Author: Claude Warren <cl...@apache.org>
Authored: Sun Feb 15 16:52:52 2015 +0000
Committer: Claude Warren <cl...@apache.org>
Committed: Sun Feb 15 16:52:52 2015 +0000

----------------------------------------------------------------------
 .../security/example/ShiroExampleEvaluator.java | 86 +++++++++++++++++++-
 .../jena/security/example/fuseki/config.ttl     | 68 ++++++++++------
 .../jena/security/example/fuseki/shiro.ini      |  2 +-
 3 files changed, 127 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/beb73c4a/jena-security/src/example/java/org/apache/jena/security/example/ShiroExampleEvaluator.java
----------------------------------------------------------------------
diff --git a/jena-security/src/example/java/org/apache/jena/security/example/ShiroExampleEvaluator.java b/jena-security/src/example/java/org/apache/jena/security/example/ShiroExampleEvaluator.java
index 87fca4e..1df5678 100644
--- a/jena-security/src/example/java/org/apache/jena/security/example/ShiroExampleEvaluator.java
+++ b/jena-security/src/example/java/org/apache/jena/security/example/ShiroExampleEvaluator.java
@@ -36,12 +36,15 @@ import com.hp.hpl.jena.vocabulary.RDF;
 
 /**
  * Class to use Shiro to provide credentials.
- * Used for same example as ExampleEvaluator
+ * 
+ * An example evaluator that only provides access to messages in the graph that 
+ * are from or to the principal.
  *
  */
 public class ShiroExampleEvaluator implements SecurityEvaluator {
 
 	private static final Logger LOG = LoggerFactory.getLogger(ShiroExampleEvaluator.class);
+	// the model that contains the messages.
 	private Model model;
 	private RDFNode msgType = ResourceFactory.createResource( "http://example.com/msg" );
 	private Property pTo = ResourceFactory.createProperty( "http://example.com/to" );
@@ -56,14 +59,29 @@ public class ShiroExampleEvaluator implements SecurityEvaluator {
 		this.model = model;
 	}
 	
+	/**
+	 * We allow any action on the graph itself, so this is always true.
+	 */
 	@Override
 	public boolean evaluate(Object principal, Action action, SecNode graphIRI) {
 		// we allow any action on a graph.
 		return true;
 	}
 
+	/**
+	 * This is our internal check to see if the user may access the resource.
+	 * This method is called from the evauate(Object,SecNode) method.
+	 * A user may only access the resource if they are authenticated, and are either the
+	 * sender or the recipient.
+	 * Additionally the admin can always see the messages.
+	 * @param principalObj
+	 * @param r
+	 * @return
+	 */
 	private boolean evaluate( Object principalObj, Resource r )
 	{
+		// cast to the Subject because we know that it comes from Shiro and that
+		// our getPrincipal() method returns a Subject.
 		Subject subject = (Subject)principalObj;
 		if (! subject.isAuthenticated())
 		{
@@ -73,32 +91,49 @@ public class ShiroExampleEvaluator implements SecurityEvaluator {
 		// a message is only available to sender or recipient
 		LOG.debug( "checking {}", subject.getPrincipal());
 		Object principal = subject.getPrincipal();
+		
+		// We put the admin check here but it could have been done much earlier.
 		if ("admin".equals(principal.toString()))
 		{
 			return true;
 		}
+		// if we are looking at a message object then check the restrictions.
 		if (r.hasProperty( RDF.type, msgType ))
 		{
 			return r.hasProperty( pTo, subject.getPrincipal().toString() ) ||
 					r.hasProperty( pFrom, subject.getPrincipal().toString());
 		}
+		// otherwise user can see the object.
 		return true;	
 	}
 	
+	/**
+	 * Check that the user can see a specific node.
+	 * @param principal
+	 * @param node
+	 * @return
+	 */
 	private boolean evaluate( Object principal, SecNode node )
 	{
+		// Access to wild card is false -- this forces checks to the acutal nodes
+		// to be returned.
+		// we could have checked for admin access here and returned true since the admin
+		// can see any node.
 		if (node.equals( SecNode.ANY )) {
-			return false;  // all wild cards are false
+			return false;  
 		}
 		
+		// URI nodes are retrieved from the model and evaluated
 		if (node.getType().equals( SecNode.Type.URI)) {
 			Resource r = model.createResource( node.getValue() );
 			return evaluate( principal, r );
 		}
+		// anonymous nodes have to be retrieved from the model as anonymous nodes.
 		else if (node.getType().equals( SecNode.Type.Anonymous)) {
 			Resource r = model.getRDFNode( NodeFactory.createAnon( new AnonId( node.getValue()) ) ).asResource();
 			return evaluate( principal, r );
 		}
+		// anything else (literals) can be seen.
 		else
 		{
 			return true;
@@ -106,44 +141,91 @@ public class ShiroExampleEvaluator implements SecurityEvaluator {
 
 	}
 	
+	/**
+	 * Evaluate if the user can see the triple.
+	 * @param principal
+	 * @param triple
+	 * @return
+	 */
 	private boolean evaluate( Object principal, SecTriple triple ) {
+		// we could have checked here to see if the principal was the admin and 
+		// just returned true since the admin can perform any operation on any triple.
 		return evaluate( principal, triple.getSubject()) &&
 				evaluate( principal, triple.getObject()) &&
 				evaluate( principal, triple.getPredicate());
 	}
 	
+	/**
+	 * As per our design, users can do anything with triples they have access to, so we just
+	 * ignore the action parameter.  If we were to implement rules restricted access based 
+	 * upon action this method would sort those out appropriately.
+	 */
 	@Override
 	public boolean evaluate(Object principal, Action action, SecNode graphIRI, SecTriple triple) {
+		// we could have checked here to see if the principal was the admin and 
+		// just returned true since the admin can perform any operation on any triple.
 		return evaluate( principal, triple );
 	}
 
+	/**
+	 * As per our design, users can access any graph.  If we were to implement rules that 
+	 * restricted user access to specific graphs, those checks would be here and we would 
+	 * return <code>false</code> if they were not allowed to access the graph.  Note that this
+	 * method is checking to see that the user may perform ALL the actions in the set on the
+	 * graph.
+	 */
 	@Override
 	public boolean evaluate(Object principal, Set<Action> actions, SecNode graphIRI) {
 		return true;
 	}
 
+	/**
+	 * As per our design, users can access any triple from a message that is from or to them.  
+	 * Since we don't have restrictions on actions this is no different then checking access
+	 * for a single action.
+	 */
 	@Override
 	public boolean evaluate(Object principal, Set<Action> actions, SecNode graphIRI,
 			SecTriple triple) {
 		return evaluate( principal, triple );
 	}
 
+	/**
+	 * As per our design, users can access any graph.  If we were to implement rules that 
+	 * restricted user access to specific graphs, those checks would be here and we would 
+	 * return <code>false</code> if they were not allowed to access the graph.  Note that this
+	 * method is checking to see that the user may perform ANY of the actions in the set on the
+	 * graph.
+	 */
 	@Override
 	public boolean evaluateAny(Object principal, Set<Action> actions, SecNode graphIRI) {
 		return true;
 	}
 
+	/**
+	 * As per our design, users can access any triple from a message that is from or to them.  
+	 * Since we don't have restrictions on actions this is no different then checking access
+	 * for a single action.
+	 */
 	@Override
 	public boolean evaluateAny(Object principal, Set<Action> actions, SecNode graphIRI,
 			SecTriple triple) {
 		return evaluate( principal, triple );
 	}
 
+	/**
+	 * As per our design, users can access any triple from a message that is from or to them.  
+	 * So for an update they can only change triples they have access to into other triples 
+	 * they have access to. (e.g. they can not remvoe themself from the messsage). 
+	 */
 	@Override
 	public boolean evaluateUpdate(Object principal, SecNode graphIRI, SecTriple from, SecTriple to) {
 		return evaluate( principal, from ) && evaluate( principal, to );
 	}
 
+	/**
+	 * Return the Shiro subject.  This is the subject that Shiro currently has logged in.
+	 */
 	@Override
 	public Object getPrincipal() {
 		return SecurityUtils.getSubject();

http://git-wip-us.apache.org/repos/asf/jena/blob/beb73c4a/jena-security/src/example/resources/org/apache/jena/security/example/fuseki/config.ttl
----------------------------------------------------------------------
diff --git a/jena-security/src/example/resources/org/apache/jena/security/example/fuseki/config.ttl b/jena-security/src/example/resources/org/apache/jena/security/example/fuseki/config.ttl
index 6f4a3af..a748f01 100644
--- a/jena-security/src/example/resources/org/apache/jena/security/example/fuseki/config.ttl
+++ b/jena-security/src/example/resources/org/apache/jena/security/example/fuseki/config.ttl
@@ -14,62 +14,77 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+##
+## Define all the prefixes 
+##
+
 @prefix fuseki:  <http://jena.apache.org/fuseki#> .
-@prefix tdb:     <http://jena.hpl.hp.com/2008/tdb#> .
 @prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
 @prefix ja:      <http://jena.hpl.hp.com/2005/11/Assembler#> .
 @prefix sec:    <http://apache.org/jena/security/Assembler#> .
 @prefix my:     <http://example.org/#> .
 
-#[] ja:loadClass "com.hp.hpl.jena.tdb.TDB" .
+##
+## Load the SecuredAssembler class from the security library and define 
+## the sec:Model as a subclass of ja:NamedModel.
+##
 [] ja:loadClass    "org.apache.jena.security.SecuredAssembler" .
-
-tdb:DatasetTDB  rdfs:subClassOf  ja:RDFDataset .
-tdb:GraphTDB    rdfs:subClassOf  ja:Model .
 sec:Model       rdfs:subClassOf  ja:NamedModel .
 
-my:dataset rdf:type tdb:DatasetTDB;
-    tdb:location "/tmp/myApp" ;
-    tdb:unionDefaultGraph true ;
-    .
-
-my:baseModel rdf:type tdb:GraphTDB ;
-    tdb:dataset my:dataset .   
+##
+## Define the base model that contains the unsecured data.
+##
+my:baseModel rdf:type ja:MemoryModel;
+    ja:content [ja:externalContent <file:./example.ttl>] 
+    .   
 
+##
+## Define the secured model.  This is where permissions is applied to the 
+## my:baseModel to create a model that has permission restrictions.  Note 
+## that it is using the security evaluator implementation (sec:evaluatorImpl) 
+## called my:secEvaluator which we will define next.
+##
 my:securedModel rdf:type sec:Model ;
     sec:baseModel my:baseModel ;
     ja:modelName "https://example.org/securedModel" ;
     sec:evaluatorImpl my:secEvaluator .
   
+##
+## Define the security evaluator.  This is where we use the example 
+## ShiroExampleEvaluator.  For your production environment you will replace 
+## "org.apache.jena.security.example.ShiroExampleEvaluator"  with your 
+## SecurityEvaluator implementation.  Note that  ShiroExampleEvaluator constructor 
+## takes a Model argument.  We pass in the unsecured baseModel so that the evaluator 
+## can read it unencumbered.  Your implementation of SecurityEvaluator may have different 
+## parameters to meet your specific needs.
+##  
 my:secEvaluator rdf:type sec:Evaluator ;
     sec:args [  
         rdf:_1 my:baseModel ;
     ] ;
     sec:evaluatorClass "org.apache.jena.security.example.ShiroExampleEvaluator" .
 
+##
+## Define the dataset that we will use for in the server.
+##
 my:securedDataset rdf:type ja:RDFDataset ;
    ja:defaultGraph my:securedModel .
 
-my:fuseki rdf:type fuseki:Server ;
-   # Server-wide context parameters can be given here.
-   # For example, to set query timeouts: on a server-wide basis:
-   # Format 1: "1000" -- 1 second timeout
-   # Format 2: "10000,60000" -- 10s timeout to first result, then 60s timeout to for rest of query.
-   # See java doc for ARQ.queryTimeout
-   # ja:context [ ja:cxtName "arq:queryTimeout" ;  ja:cxtValue "10000" ] ;
-
-   # Load custom code (rarely needed)
-   # ja:loadClass "your.code.Class" ;
-
-   # Services available.  Only explicitly listed services are configured.
-   #  If there is a service description not linked from this list, it is ignored.
+##
+## Define the fuseki:Server.
+##
+my:fuskei rdf:type fuseki:Server ;
    fuseki:services (
      my:service1
    ) .
 
-    
+##
+## Define the service for the fuseki:Service.  Note that the fuseki:dataset served by 
+## this server is the secured dataset defined above.    
+##
 my:service1 rdf:type fuseki:Service ;
+    rdfs:label                        "My Secured Data Service" ;
     fuseki:name                       "myAppFuseki" ;       # http://host:port/myAppFuseki
     fuseki:serviceQuery               "query" ;    # SPARQL query service
     fuseki:serviceQuery               "sparql" ;   # SPARQL query service
@@ -80,3 +95,4 @@ my:service1 rdf:type fuseki:Service ;
     fuseki:serviceReadGraphStore      "get" ;      # SPARQL Graph store protocol (read only)
     fuseki:dataset                   my:securedDataset ;
     .
+    

http://git-wip-us.apache.org/repos/asf/jena/blob/beb73c4a/jena-security/src/example/resources/org/apache/jena/security/example/fuseki/shiro.ini
----------------------------------------------------------------------
diff --git a/jena-security/src/example/resources/org/apache/jena/security/example/fuseki/shiro.ini b/jena-security/src/example/resources/org/apache/jena/security/example/fuseki/shiro.ini
index d0ce2c3..a9fbf71 100644
--- a/jena-security/src/example/resources/org/apache/jena/security/example/fuseki/shiro.ini
+++ b/jena-security/src/example/resources/org/apache/jena/security/example/fuseki/shiro.ini
@@ -40,7 +40,7 @@ darla=darla
 /$/ping   = anon
 
 ## restrict access.  Must log in with above.
-/$/** = authcBasic,user[admin]
+/$/** = authcBasic,user
 
 
 # Everything else