Return-Path: X-Original-To: apmail-jena-commits-archive@www.apache.org Delivered-To: apmail-jena-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 30E1410D06 for ; Sat, 24 Jan 2015 21:44:24 +0000 (UTC) Received: (qmail 52681 invoked by uid 500); 24 Jan 2015 21:44:24 -0000 Delivered-To: apmail-jena-commits-archive@jena.apache.org Received: (qmail 52659 invoked by uid 500); 24 Jan 2015 21:44:24 -0000 Mailing-List: contact commits-help@jena.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jena.apache.org Delivered-To: mailing list commits@jena.apache.org Received: (qmail 52649 invoked by uid 99); 24 Jan 2015 21:44:24 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 24 Jan 2015 21:44:24 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id 3807DAC0110 for ; Sat, 24 Jan 2015 21:44:24 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r937566 - in /websites/staging/jena/trunk/content: ./ documentation/security/assembler.html documentation/security/evaluator.html documentation/security/index.html Date: Sat, 24 Jan 2015 21:44:24 -0000 To: commits@jena.apache.org From: buildbot@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20150124214424.3807DAC0110@hades.apache.org> Author: buildbot Date: Sat Jan 24 21:44:23 2015 New Revision: 937566 Log: Staging update by buildbot for jena Modified: websites/staging/jena/trunk/content/ (props changed) websites/staging/jena/trunk/content/documentation/security/assembler.html websites/staging/jena/trunk/content/documentation/security/evaluator.html websites/staging/jena/trunk/content/documentation/security/index.html Propchange: websites/staging/jena/trunk/content/ ------------------------------------------------------------------------------ --- cms:source-revision (original) +++ cms:source-revision Sat Jan 24 21:44:23 2015 @@ -1 +1 @@ -1653226 +1654582 Modified: websites/staging/jena/trunk/content/documentation/security/assembler.html ============================================================================== --- websites/staging/jena/trunk/content/documentation/security/assembler.html (original) +++ websites/staging/jena/trunk/content/documentation/security/assembler.html Sat Jan 24 21:44:23 2015 @@ -142,28 +142,53 @@

Jena Security - Assembler For a Secured Model

-

Jena Security provides a standard Jena assembler making it easy to use the SecuredModel in an Assembler based -environment. To use the security assembler the assembler file must contain the lines:

-
<>; ja:loadClass "org.apache.jena.security.SecuredAssembler" .
-sec:Model rdfs:subClassOf ja:NamedModel .
+  

Jena Security provides a standard Jena assembler making it easy to use the SecuredModel in an Assembler based environment. To use the security assembler the assembler file must contain the lines:

+
[] ja:loadClass    "org.apache.jena.security.SecuredAssembler" .
+ sec:Model       rdfs:subClassOf  ja:NamedModel .
 
-

and a model definition something like:

-
[] a ja:Model ;
-   sec:baseModel jena:model ;
-   ja:modelName "modelName";
-   sec:evaluatorFactory "javaclass";
-   .
+

The secured assembler provides XXXXXXXXXXXx properties for the assembler files.

+

Assuming we define

+
 @prefix sec:    <http://apache.org/jena/security/Assembler#> .
 
-

where: -- jena:model is a model defined in the assembler file. In this example there would be a like in the file -something like jena:model a ja:Model.
-- modelName is the name of the model as identified in the security manager. -- javaclass is the java class name that implements an Evaluator Factory. The Factory must have static method -getInstance() that returns a SecurityEvaluator instance.

+

Then the following resources are defined

+

sec:Model - A secured model. One against which the security evaluator is running access checks. All sec:Model instances must have a ja:ModelName to identify it to the SecurityEvaluator

+

sec:Evaluator - An instance of SecurityEvaluator.

+

The following are properties are also defined:

+

sec:evaluatorFactory - Identifies the class name of a factory class that implements a no-argument getInstance() method that returns an instance of SecurityEvaluator.

+

sec:baseModel - Identifies the ja:Model that is to have security applied to it.

+

sec:evaluatorImpl - Identifies an instance of SecurityEvaluator.

+

sec:evaluatorClass - Identifies a class that implements SecurityEvaluator

+

sec:args - Identifies arguments to the sec:evaluatorClass constructor.

+

The secured assembler provides two (2) mechanisms to create a secured graph. The first is to use a SecurityEvaluator factory

+
my:securedModel rdf:type sec:Model ;
+    sec:baseModel my:baseModel ;
+    ja:modelName "https://example.org/securedBaseModel" ;
+    sec:evaluatorFactory "the.evaluator.factory.class.name" .
+
+ + +

In the above example static method getInstance() is called on the.evaluator.factory.class.name and the result is used as the SecurityEvaluator. This is used to create a secured model (my:securedModel) that wraps the model my:baseModel and identifies itself to the SecurityEvaluator with the URI "https://example.org/securedBaseModel".

+

The second mechanism is to use the sec:Evaluator method.

+
my:secEvaluator rdf:type sec:Evaluator ;
+    sec:args [  
+        rdf:_1 my:secInfoModel ;
+    ] ;
+    sec:evaluatorClass    "your.implementation.SecurityEvaluator" 
+.
+
+my:securedModel rdf:type sec:Model ;
+    sec:baseModel my:baseModel ;
+    ja:modelName "https://example.org/securedBaseModel" ;
+    sec:evaluatorImpl  my:secEvaluator .
+
+ + +

In the above example my:secEvaluator is defined as a sec:Evaluator implemented by the class "your.implementation.SecurityEvaluator". When the instance is constructed the constructor with one (1) argument is used and it is passed my:secInfoModel as an argument. my:secInfoModel may be any type supported by the assembler. If more than one argument is desired then rdf:_2, rdf:_3, rdf:_4, etc. may be added to the sec:args list. The "your.implementation.SecurityEvaluator" with the proper number of arguments will be called. It is an error to have more than one argument with the proper number of arguments.

+

After constructon the value of my:securedModel is used to construct the my:securedModel instance. This has the same properties as the previous example other than that the SecurityEvaluator instance is different.

Modified: websites/staging/jena/trunk/content/documentation/security/evaluator.html ============================================================================== --- websites/staging/jena/trunk/content/documentation/security/evaluator.html (original) +++ websites/staging/jena/trunk/content/documentation/security/evaluator.html Sat Jan 24 21:44:23 2015 @@ -174,46 +174,46 @@ triple:

  • SecTriple.ANY = new SecTriple(SecNode.ANY, SeccNode.ANY, SecNode.ANY)` Matches any SecTriple.
  • Evaluator Methods

    -
    public boolean evaluate( Action action, SecNode graphIRI );
    +
    public boolean evaluate( Object principal, Action action, SecNode graphIRI );
     

    Determine if the action is permitted within the graph.

    -
    public boolean evaluate( Action action, SecNode graphIRI, SecTriple triple );
    +
    public boolean evaluate( Object principal, Action action, SecNode graphIRI, SecTriple triple );
     

    Determine if the action is allowed on the triple within the graph.

    -
    public boolean evaluate( Set<Action> actions, SecNode graphIRI );
    +
    public boolean evaluate( Object principal, Set<Action> actions, SecNode graphIRI );
     

    Determine if all actions are allowed on the graph.

    -
    public boolean evaluate( Set<Action> actions, SecNode graphIRI, SecTriple triple );
    +
    public boolean evaluate( Object principal, Set<Action> actions, SecNode graphIRI, SecTriple triple );
     

    Determine if all the actions are allowed on the triple within the graph.

    -
    public boolean evaluateAny( Set<Action> actions, SecNode graphIRI );
    +
    public boolean evaluateAny( Object principal, Set<Action> actions, SecNode graphIRI );
     

    Determine if any of the actions are allowed on the graph.

    -
    public boolean evaluateAny( Set<Action> actions, SecNode graphIRI, SecTriple triple );
    +
    public boolean evaluateAny( Object principal, Set<Action> actions, SecNode graphIRI, SecTriple triple );
     

    Determine if any of the actions are allowed on the triple within the graph.

    -
    public boolean evaluateUpdate( SecNode graphIRI, SecTriple from, SecTriple to );
    +
    public boolean evaluateUpdate( Object principal, SecNode graphIRI, SecTriple from, SecTriple to );
     

    Determine if the user is allowed to update the "from" triple to the "to" triple.

    -
    public Principal getPrincipal();
    +
    public Object getPrincipal();
     
    -

    returns the current principal or null if there is no current principal.

    +

    Returns the current principal or null if there is no current principal.

    Sample Implementation

    This sample is for a graph that contains a set of messages, access to the messages are limited to principals that the messages are to or from. Any triple that is not a message is not affected. This @@ -221,6 +221,7 @@ implementation simply has a setPri user principal or name from the authentication system. This implementation also requires access to the underlying model to determine if the user has access, however, that is not a requirement of the SecurityEvaluator in general. Determining access from the information provided is an exercise for the implementer.

    +

    See the example jar for another implementation example.

    public class ExampleEvaluator implements SecurityEvaluator {
    @@ -241,13 +242,14 @@ Determining access from the information
         }
     
         @Override
    -    public boolean evaluate(Action action, SecNode graphIRI) {
    +    public boolean evaluate(Object principal, Action action, SecNode graphIRI) {
             // we allow any action on a graph.
             return true;
         }
     
    -    private boolean evaluate( Resource r )
    +    private boolean evaluate( Object principalObj, Resource r )
         {
    +        Principal principal = (Principal)principalObj;
             // a message is only available to sender or recipient
             if (r.hasProperty( RDF.type, msgType ))
             {
    @@ -257,7 +259,7 @@ Determining access from the information
             return true;    
         }
     
    -    private boolean evaluate( SecNode node )
    +    private boolean evaluate( Object principal, SecNode node )
         {
             if (node.equals( SecNode.ANY )) {
                 return false;  // all wild cards are false
    @@ -265,11 +267,11 @@ Determining access from the information
     
             if (node.getType().equals( SecNode.Type.URI)) {
                 Resource r = model.createResource( node.getValue() );
    -            return evaluate( r );
    +            return evaluate( principal, r );
             }
             else if (node.getType().equals( SecNode.Type.Anonymous)) {
                 Resource r = model.getRDFNode( NodeFactory.createAnon( new AnonId( node.getValue()) ) ).asResource();
    -            return evaluate( r );
    +            return evaluate( principal, r );
             }
             else
             {
    @@ -278,42 +280,42 @@ Determining access from the information
     
         }
     
    -    private boolean evaluate( SecTriple triple ) {
    -        return evaluate( triple.getSubject()) &&
    -                evaluate( triple.getObject()) &&
    -                evaluate( triple.getPredicate());
    +    private boolean evaluate( Object principal, SecTriple triple ) {
    +        return evaluate( principal, triple.getSubject()) &&
    +                evaluate( principal, triple.getObject()) &&
    +                evaluate( principal, triple.getPredicate());
         }
     
         @Override
    -    public boolean evaluate(Action action, SecNode graphIRI, SecTriple triple) {
    -        return evaluate( triple );
    +    public boolean evaluate(Object principal, Action action, SecNode graphIRI, SecTriple triple) {
    +        return evaluate( principal, triple );
         }
     
         @Override
    -    public boolean evaluate(Set<Action> actions, SecNode graphIRI) {
    +    public boolean evaluate(Object principal, Set<Action> actions, SecNode graphIRI) {
             return true;
         }
     
         @Override
    -    public boolean evaluate(Set<Action> actions, SecNode graphIRI,
    +    public boolean evaluate(Object principal, Set<Action> actions, SecNode graphIRI,
                 SecTriple triple) {
    -        return evaluate( triple );
    +        return evaluate( principal, triple );
         }
     
         @Override
    -    public boolean evaluateAny(Set<Action> actions, SecNode graphIRI) {
    +    public boolean evaluateAny(Object principal, Set<Action> actions, SecNode graphIRI) {
             return true;
         }
     
         @Override
    -    public boolean evaluateAny(Set<Action> actions, SecNode graphIRI,
    +    public boolean evaluateAny(Object principal, Set<Action> actions, SecNode graphIRI,
                 SecTriple triple) {
    -        return evaluate( triple );
    +        return evaluate( principal, triple );
         }
     
         @Override
    -    public boolean evaluateUpdate(SecNode graphIRI, SecTriple from, SecTriple to) {
    -        return evaluate( from ) && evaluate( to );
    +    public boolean evaluateUpdate(Object principal, SecNode graphIRI, SecTriple from, SecTriple to) {
    +        return evaluate( principal, from ) && evaluate( principal, to );
         }
     
         public void setPrincipal( String userName )
    
    Modified: websites/staging/jena/trunk/content/documentation/security/index.html
    ==============================================================================
    --- websites/staging/jena/trunk/content/documentation/security/index.html (original)
    +++ websites/staging/jena/trunk/content/documentation/security/index.html Sat Jan 24 21:44:23 2015
    @@ -149,7 +149,7 @@ framework for developers or integrators
     
    @@ -165,6 +165,7 @@ SecurityEvaluator the developer may appl
     optionally triples within the graphs. 

    The javadocs have additional annotations that specify what permissions at graph and triple levels are required for the user to execute the method.

    +

    There is an example jar that contains configuration examples for both a stand alone application and a fuseki configuration option.

    Usage Notes

    When the system is correctly configured the developer creates a SecuredGraph by calling Factory.getInstance( SecurityEvaluator, String, Graph );. Once created the resulting graph automatically @@ -183,115 +184,6 @@ permissions, not the update -

    How it Works

    -

    Jena-security does not specify how to determine who the user is, just that a Principal identifying the user is -available. It does not specify how to determine what the user has access to.

    -

    It does require that a developer or integrator implement the SecurityEvaluator so that when the -system asks if the current user can perform an action (say read graph X) there is a yes or no answer.

    -

    The framework does all the work of intercepting the calls to the graph (or model) and making appropriate calls -to the Evaluator before allowing the call to go ahead. There are numerous unit tests to ensure that -this is done correctly. The required permissions are specified in the javadoc for object classes -(e.g. SecuredGraph, SecuredModel).

    -

    Conceptually the framework implements 2 levels of security: graph and triple.

    -

    The graph restrictions are applied before triple restrictions. So the system will call

    -
    evaluate( Action action, SecNode graphIRI );
    -
    - - -

    to ask can the current user "Read" (Action) graph X (graphIRI) as evaluate( Action.READ, X ).

    -

    if the answer is yes then the system will call

    -
    evaluate( Action action, SecNode graphIRI, SecTriple triple );
    -
    - - -

    to ask if the current user can "Read" (Action) from graph X (graphIRI) all triples (SecTriple) as -evaluate( Action.READ, X, SecTriple.ALL ).

    -

    if the answer is yes then the system will execute the call, if the answer is no then for each -potential triple the user might read the system will call

    -
    evaluate( Action action, SecNode graphIRI, SecTriple triple );
    -
    - - -

    to ask if the current user can "Read" (Action) from graph X (graphIRI) the triple in question -() as evaluate( Action.READ, X, <triple> ).

    -

    Jena-security performs similar checks for all creates, reads, updates and deletes. (CRUD). It also does this -for all classes that can be returned from the secured classes. For example an RDFList returned -from a SecuredModel is secured so that the filtering above is performed against the items in the -list.

    -

    Use of special nodes

    -

    Jena-security provides three special nodes to facilitate evaluation of security policy constraints.

    -

    SecNode.ANY

    -

    This is similar to the Jena Node.ANY node. It matches any node. In general the system will ask if -the user can access a graph by executing

    -
    evaluate( Action, GraphIRI )
    -
    - - -

    if the user can access the graph then the system will execute

    -
    evaluate( Action, GraphIRI, <SecNode.ANY, SecNode.ANY, SecNode.ANY> )
    -
    - - -

    to determine if the user can perform the action on all triples. If not then the system will attempt to -determine if the user perform the action on each specific triple. In some cases the system can determine that -the range of nodes involved in the action a sub set of all nodes and will call evaluate with some constant -nodes.

    -
      -
    • -

      <SecNode.ANY, SecNode.ANY, SecNode.ANY> - Asks if the user may perform the action on any triple.

      -
    • -
    • -

      <X, SecNode.ANY, SecNode.ANY> - Asks if the user may perform the action against -any triple where X is the subject.

      -
    • -
    • -

      <SecNode.ANY, X, SecNode.ANY> - Asks if the user may perform the action against -any triple where X is the predicate.

      -
    • -
    • -

      <SecNode.ANY, SecNode.ANY, SecNode.X> - Asks if if the user may perform the action against -any triple where X is the object.

      -
    • -
    -

    The SecNode.ANY node may occur multiple times and may occur with the SecNode.VARIABLE and/or - SecNode.FUTURE nodes.

    -

    SecNode.VARIABLE

    -

    This differs from SecNode.ANY in that the system is asking "if there are any prohibitions" not "if the user -may perform". Thus queries with the SecNode.VARIABLE nodes should return true where SecNode.ANY returns -false. In general this type is used in the query to determine if triple level filtering of results must be -performed.

    -
      -
    • -

      <SecNode.VARIABLE, X, Y> - Asks if there are any prohibitions against the user seeing all subjects -that have property X and object Y.

      -
    • -
    • -

      <X, SecNode.VARIABLE, Y> - Asks if there are any prohibitions against the user seeing all predicates -hat have subject X and object Y.

      -
    • -
    • -

      <X, Y, SecNode.VARIABLE> - Asks if there are any prohibitions against the user seeing all objects -that have subject X and predicate Y.

      -
    • -
    -

    The SecNode.VARIABLE may occur multiple times and may occur with the SecNode.ANY node.

    -

    SecNode.FUTURE

    -

    Insertions pose a different set of problems in that in some cases the system does not know what value will be -inserted. For example when concatenating one RDFList with another (rdfList.concatenate( rdfList2 )) the system -will create a series of anonymous nodes. To check for these the SecNode.FUTURE is used. Initially the system will -call

    -
    evaluate( Action.CREATE, X, <SecNode.FUTURE, RDF.first, SecNode.ANY> )
    -
    - - -

    to ascertain if the user can create a triple in graph X that has an anonymous node (SecNode.FUTURE) as the subject, -RDF.first as the predicate and any node as the object. If this is not allowed then for every node in rdfList2 -the system will call

    -
    evaluate( Action.CREATE, X, <SecNode.FUTURE, RDF.first, node> )
    -
    - - -

    where node is the node from rdfList2 to be added.