You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2015/02/17 13:42:53 UTC
[44/50] [abbrv] jena git commit: Updated fuseki example files added
documentation to example code.
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/eliminate-assignments
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