VAL's OAuth provider implementation provides an application management page to create, delete, and edit OAuth client application key/secret pairs.
Like most aspects in VAL the creation of OAuth Clients is subject to ACLs and Restrictions. An instance maintainer can define who is allowed to create new OAuth clients and how many they are allowed to create.
http://www.openlinksw.com/ontology/acl#DefaultRealm
and default hostname "HOST"
the graph IRI would be http://HOST/acl/graph/rules/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm
and the groups will be stored in named graph http://HOST/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm
.
Be aware that these graphs can be customized for better readability.The same principle applies to the named graph for restrictions.
Given the default realm http://www.openlinksw.com/ontology/acl#DefaultRealm
and default hostname "HOST"
the graph IRI would be http://HOST/acl/restrictions/rules/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm
.
For the ACL system to work properly the appropriate ontologies need to be loaded into the private named graph urn:virtuoso:val:acl:schema
.
This can be achieved as follows:
sparql load <http://www.openlinksw.com/ontology/acl#> into <urn:virtuoso:val:acl:schema>; sparql load <http://www.openlinksw.com/ontology/restrictions#> into <urn:virtuoso:val:acl:schema>;
By default any authenticated person can create an arbitrary number of OAuth Client Keys.
VAL controls ACL application through ACL scopes which can be enabled and disabled per application realm. Thus, in order to enable ACLs in the default realm the following must be done:
sparql prefix oplacl: <http://www.openlinksw.com/ontology/acl#> with <urn:virtuoso:val:config> delete { oplacl:DefaultRealm oplacl:hasDisabledAclScope oplacl:OAuth . } insert { oplacl:DefaultRealm oplacl:hasEnabledAclScope oplacl:OAuth . };
Creating new OAuth client keys requires one to have oplacl:Write permissions on the virtual resource urn:virtuoso:access:oauth:apps
in ACL scope oplacl:OAuth.
Be aware that the ACL graphs can be customized for better readability.
sparql prefix oplacl: <http://www.openlinksw.com/ontology/acl#> prefix acl: <http://www.w3.org/ns/auth/acl#> prefix foaf: <http://xmlns.com/foaf/0.1/> with <http://HOST/acl/graph/rules/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> insert { <#rule> a acl:Authorization ; oplacl:hasAccessMode oplacl:Write ; acl:accessTo <urn:virtuoso:access:oauth:apps> ; acl:agentClass foaf:Agent ; oplacl:hasScope oplacl:OAuth ; oplacl:hasRealm oplacl:DefaultRealm . };
sparql prefix oplacl: <http://www.openlinksw.com/ontology/acl#> prefix acl: <http://www.w3.org/ns/auth/acl#> prefix foaf: <http://xmlns.com/foaf/0.1/> with <http://HOST/acl/graph/rules/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> insert { <#rule> a acl:Authorization ; oplacl:hasAccessMode oplacl:Write ; acl:accessTo <urn:virtuoso:access:oauth:apps> ; acl:agent <http://www.linkedin.com/in/test> ; oplacl:hasScope oplacl:OAuth ; oplacl:hasRealm oplacl:DefaultRealm . };
oplacl:hasRealm
and foaf:maker
)There are two types of groups: static and conditional ones. The former is a simple list of individuals as see below, the latter is a set of conditions which define a dynamic group of individuals.
sparql prefix oplacl: <http://www.openlinksw.com/ontology/acl#> prefix foaf: <http://xmlns.com/foaf/0.1/> with <http://HOST/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> insert { <#group> a foaf:Group, oplacl:StaticGroup ; foaf:name "Some people" ; foaf:member <http://dduck.wordpress.com> , <http://peterparker.tumblr.com/> . };
sparql prefix oplacl: <http://www.openlinksw.com/ontology/acl#> prefix foaf: <http://xmlns.com/foaf/0.1/> with <http://HOST/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> insert { <#group> a oplacl:ConditionalGroup ; foaf:name "Valid Identifiers" ; oplacl:hasCondition [ a oplacl:GroupCondition, oplacl:GenericCondition ; oplacl:hasCriteria oplacl:NetID ; oplacl:hasComparator oplacl:IsNotNull ; oplacl:hasValue 1 ] . };
sparql prefix oplacl: <http://www.openlinksw.com/ontology/acl#> prefix foaf: <http://xmlns.com/foaf/0.1/> with <http://HOST/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> insert { <#group> a oplacl:ConditionalGroup ; foaf:name "Valid WebIDs" ; oplacl:hasCondition [ a oplacl:GroupCondition, oplacl:GenericCondition ; oplacl:hasCriteria oplacl:WebIDVerified ; oplacl:hasComparator oplacl:EqualTo ; oplacl:hasValue 1 ] . };
sparql prefix oplacl: <http://www.openlinksw.com/ontology/acl#> prefix foaf: <http://xmlns.com/foaf/0.1/> with <http://HOST/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> insert { <#group> a oplacl:ConditionalGroup ; foaf:name "Valid X.509 Certificates" ; oplacl:hasCondition [ a oplacl:GroupCondition, oplacl:GenericCondition ; oplacl:hasCriteria oplacl:CertVerified ; oplacl:hasComparator oplacl:EqualTo ; oplacl:hasValue 1 ] . };
sparql prefix oplacl: <http://www.openlinksw.com/ontology/acl#> prefix foaf: <http://xmlns.com/foaf/0.1/> with <http://HOST/acl/graph/groups/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> insert { <#group> a oplacl:ConditionalGroup ; foaf:name "Valid WebIDs" ; oplacl:hasCondition [ a oplacl:GroupCondition, oplacl:GenericCondition ; oplacl:hasCriteria oplacl:WebIDVerified ; oplacl:hasComparator oplacl:EqualTo ; oplacl:hasValue 1 ] , [ a oplacl:GroupCondition, oplacl:OAuthCondition ; oplacl:hasQuery """ask where { graph ^{graph}^ { ^{uri}^ a foaf:Person } }""" ] };
In addition to controlling who can create OAuth clients the instance maintainer can define how many OAuth clients can be created. By default whoever has the right to create applications can create as many as they like.
In order to limit that number a restriction on resource urn:virtuoso:restrictions:oauth:apps
needs to be defined.
As always with VAL restrictions the least restrictive value will be used.
sparql prefix oplres: <http://www.openlinksw.com/ontology/restrictions#> prefix foaf: <http://xmlns.com/foaf/0.1/> with <http://HOST/acl/graph/restrictions/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> insert { <#res1> a oplres:Restriction ; rdfs:label "Max 2 OAuth Apps for Everyone" ; oplres:hasResource <urn:virtuoso:restrictions:oauth:apps> ; oplres:hasAgentClass foaf:Agent ; oplres:hasMaxValue "2"^^xsd:decimal . };
sparql prefix oplres: <http://www.openlinksw.com/ontology/restrictions#> prefix foaf: <http://xmlns.com/foaf/0.1/> with <http://HOST/acl/graph/restrictions/http%3A%2F%2Fwww.openlinksw.com%2Fontology%2Facl%23DefaultRealm> insert { <#res1> a oplres:Restriction ; rdfs:label "Max 10 OAuth Apps" ; oplres:hasResource <urn:virtuoso:restrictions:oauth:apps> ; oplres:hasAgent <http://peterparker.tumblr.com/> ; oplres:hasMaxValue "10"^^xsd:decimal . };
Like all applications using VAL's authentication pages one can make use of VAL's request for access feature which allows to easily send a message to the owner of the resource asking for permission to use it.
All VAL requires to know is who owns the resource. This is easily done by using the VAL API. If, for example, "dba" should be the owner of the OAuth Client Management, then the following call will save that fact:
VAL.DBA.set_resource_ownership ( scope=>VAL.DBA.oplacl_uri('OAuth'), resource=>'urn:virtuoso:access:oauth:apps', serviceId=>VAL.DBA.user_personal_uri ('dba') );
This call will add a triple like the following into a private graph which is then added to a graph group containing all ownership graphs for the given scope:
@prefix foaf: <http://xmlns.com/foaf/0.1/> . http://HOST/dataspace/person/dba#this foaf:made <urn:virtuoso:access:oauth:apps> .