Create Access Requests/Grants#
AccessGrantClient
#
The inrupt-client-accessgrant
module provides an
AccessGrantClient that interacts with the ESS
Access Grant Service to
create/verify/query/fetch access requests and grants.
To interact with the service, the AccessGrantClient has the following methods:
Method |
Description |
---|---|
Creates access requests. |
|
Creates access grants. |
|
Updates the status of the access requests/grants to revoked. |
|
Queries for access requests and grants. |
|
Creates access request denials. |
|
Performs validation checks on access requests/grants, such as signature validation, date validation, etc. |
To instantiate an AccessGrantClient, you need to pass in the URI of
the ESS Access Grant Service. For example, the Access Grant service
for Inrupt’s PodSpaces runs at https://vc.inrupt.com
.
Create an Access Request#
An application can use AccessGrantClient.requestAccess to create an access request.
For example, a user visits an ExamplePrinter’s website which provides photo printing services. When the ExamplePrinter’s web application asks for the photos to print, the user enters the URLs of the photos that are located in the user’s Pod. To continue, the ExamplePrinter’s backend server uses AccessGrantClient.requestAccess to create access requests to read the photos.
1. Instantiate the Requestor’s AccessGrantClient#
To instantiate an AccessGrantClient, call the constructor with the following parmeters:
Parameters |
Descriptions |
---|---|
Access Grant Service URI |
The root URL of the ESS Access Grant service (in the example,
|
Authenticated Session |
The authenticated session of the requestor (in the example, the authenticated session of ExamplePrinter). |
For example, the following instantiates an AccessGrantClient for ExamplePrinter using the Inrupt PodSpaces Access Grant Service URI and ExamplePrinter’s authenticated session (logic to initialize an authenticated session for ExamplePrinter has been omitted for brevity):
public class ExamplePrinterRequestingClass {
private final URI PS_ACCESS_GRANT_URI = URI.create("https://vc.inrupt.com");
private Session session; // Session for ExamplePrinter.
// ... Logic to initialize the ExamplePrinter's session has been omitted for brevity.
private final AccessGrantClient accessgrantClient = new AccessGrantClient(PS_ACCESS_GRANT_URI)
.session(session);
// ...
// ...
}
2. Create the Access Request#
To create an access request, call AccessRequest.requestAccess
with the request details:
Parameters |
Descriptions |
---|---|
Resource Owner |
The WebID of the agent who controls access to the requested resource(s). |
Requested resource(s) |
Resource(s) to which the access is being requested. |
Requested access mode(s). |
Requested access modes. Available modes are:
|
Optional. Purpose(s) for the request. |
URI(s) indicating the stated purpose(s) for the request. |
Optional (but Recommended) Expiration Date. |
Expiration date of the access request and subsequent access grant, if approved. Note ESS Access Grant Service may be
|
The AccessRequest.requestAccess
accepts:
request details as AccessRequest.RequestParameters, which is a collection of the request parameters; or
request details as individual parameters.
AccessGrantClient.requestAccess(AccessRequest.RequestParameters) accepts the access request details as AccessRequest.RequestParameters. To build the AccessRequest.RequestParameters object, you can use AccessRequest.RequestParameters.Builder and its methods.
For example, the following code uses:
AccessRequest.RequestParameters.Builder to specify the request details (i.e., the resource owner, the resources, the modes, the purposes, and the expiration); and
ExamplePrinter’s instantiated AccessGrantClient to create the request (i.e., the requestor is ExamplePrinter).
public AccessRequest createReadRequest(List<String> resourceURLs, String resourceOwner) {
URI resourceOwnerURI = URI.create(resourceOwner);
Set<URI> resourcesURIs = resourceURLs.stream().map(URI::create).collect(Collectors.toSet());
Set<String> modes = Set.of("Read"); // Available modes are "Read", "Write", and "Append".
Set<URI> purposes = Set.of(
URI.create("https://purpose.example.com/PhotoPrinting"),
URI.create("https://purpose.example.com/ServiceProvision"));
Instant currentInstant = Instant.now();
Instant expiration = currentInstant.plus(30, ChronoUnit.MINUTES);
AccessRequest.RequestParameters requestParams = AccessRequest.RequestParameters.newBuilder()
.recipient(resourceOwnerURI)
.resources(resourcesURIs)
.modes(modes)
.purposes(purposes)
.expiration(expiration)
.build();
AccessRequest accessRequest = accessgrantClient.requestAccess(requestParams).toCompletableFuture().join();
return accessRequest;
}
AccessGrantClient.requestAccess(URI recipient, Set<URI> resources, Set<String> modes, Set<URI> purposes, Instant expiration) can accept the request details as individual parameters:
For example, the following code uses ExamplePrinter’s instantiated AccessGrantClient to create a Read request:
public AccessRequest createReadRequest(List<String> resourceURLs, String resourceOwner) {
URI resourceOwnerURI = URI.create(resourceOwner);
Set<URI> resourcesURIs = resourceURLs.stream().map(URI::create).collect(Collectors.toSet());
Set<String> modes = Set.of("Read"); // Available modes are "Read", "Write", and "Append".
Set<URI> purposes = Set.of(
URI.create("https://purpose.example.com/PhotoPrinting"),
URI.create("https://purpose.example.com/ServiceProvision"));
Instant currentInstant = Instant.now();
Instant expiration = currentInstant.plus(30, ChronoUnit.MINUTES);
AccessRequest accessRequest = accessgrantClient.requestAccess(
resourceOwnerURI,
resourcesURIs,
modes,
purposes,
expiration).toCompletableFuture().join();
return accessRequest;
}
Create an Access Grant#
Resource owners can use their access management application to view access requests made to them and decide whether to grant the requested access or not. If the resource owner decides to grant an access request, the access management application can call AccessGrantClient.grantAccess to create an access grant. Optionally, the application can also call AccessGrantClient.verify to verify the access request before displaying it to the user.
For example, the user (the resource owner) who visited ExamplePrinter’s website to print pictures can login to a trusted access management application. The access management application can display the access request made to the user by the ExamplePrinter. If the user decides to grant the requested access, the application can create an access grant. The access manage application has a backend server that uses various AccessGrantClient methods, namely:
1. Instantiate the Grantor’s AccessGrantClient#
To instantiate an AccessGrantClient for the grantor/resource owner, call the constructor with the following parmeters:
Parameters |
Descriptions |
---|---|
Access Grant Service URL |
The root URL of the ESS Access Grant service (in the example,
|
Authenticated Session |
The authenticated session of the user (the resource owner). |
For example, the following instantiates an AccessGrantClient using Inrupt PodSpaces Access Grant Service URI and the resource owner’s session (logic to initialize an authenticated session for the resource owner has been omitted for brevity):
public class AccessManagementAppRequestHandler {
private final URI PS_ACCESS_GRANT_URI = URI.create("https://vc.inrupt.com");
private Session userSession; // Session for a resource owner.
// ... Logic to initialize a session for a resource owner has been omitted for brevity.
AccessGrantClient agClientForUser = new AccessGrantClient(PS_ACCESS_GRANT_URI)
.session(userSession);
// ...
// ...
}
2. Get the Access Request(s) Made to the User#
Note
The user can only retrieve access requests where the user is either the requestor (creator of the access request) or the resource owner (recipient of the access request).
If the Access Request’s id is known, the application can directly retrieve the access request using AccessGrantClient.fetch with the Access Request’s id.
Note
The fetch
operation can return expired or future access requests.
// String requestID = "https://vc.{ESS DOMAIN}/vc/xxxxxx...";
AccessRequest accessRequest = agClientForUser.fetch(URI.create(requestID), AccessRequest.class)
.toCompletableFuture()
.join();
The application can use AccessGrantClient.query to query for active (i.e., current and not expired) access requests made to a user. To use AccessGrantClient.query for access requests, you can either:
Pass in an AccessCredentialQuery object
AccessCredentialQuery<AccessRequest>
that specifies the query field values (i.e., a combination of the resource, creator, recipient, purpose(s), and mode(s)); orPass in query field values directly; that is, a combination of the resource, creator, recipient, purpose, mode, and the class (
AccessRequest.class
when querying for access requests).
You can use AccessCredentialQuery.Builder and its methods to build an AccessCredentialQuery for access requests:
Method |
Descriptions |
---|---|
Optional. Include the resource in the query object. To match a query that specifies a resource, access requests must include the specified resource in their list of resource(s). |
|
Optional. Include the access request creator, (i.e.,
the requestor) in the query object. In the example,
the creator values is the ExamplePrinter’s WebID
|
|
Optional. Include the request recipient (i.e., the resource owner to whom the access request is made) in the query object. |
|
Optional. Include a purpose in the query object. To match the query that specifies a purpose, access requests must include the specified purpose in their list of purpose(s). You can call this method multiple times to specify additional purposes. To match the query that specifies multiple purposes, access requests must include all specified purposes. |
|
Optional. Include the access mode in the query object. To match the query that specifies a mode, access requests must include the specified access mode in their list of mode(s). You can call this method multiple times to specify multiple access modes. To match the query that specifies multiple modes, access requests must include all specified modes. For example, you can call
|
|
Builds the AccessCredentialQuery. To build a query object for access requests (i.e.,
|
The following example queries for active access requests made by ExamplePrinter for a given resource. Specifically,
The example uses the AccessCredentialQuery.Builder and its methods to:
Specify the requested resource
.resource(...)
and the request creator.creator(...)
, andBuild
.build(AccessRequest.class)
anAccessCredentialQuery<AccessRequest>
.
Calls AccessGrantClient.query with the built
AccessCredentialQuery<AccessRequest>
object.
AccessCredentialQuery<AccessRequest> accessRequestQuery = new AccessCredentialQuery.Builder()
.resource(URI.create("https://storage.example.com/container/someResource"))
.creator(URI.create("https://id.example.com/ExamplePrinter"))
.build(AccessRequest.class);
List<AccessRequest> requests = agClientForUser.query(accessRequestQuery).toCompletableFuture().join();
From the list, the resource owner can select the access request to act upon.
You can use AccessGrantClient.query for access requests
by passing the query field values as parameters. Pass in
AccessRequest.class
as the access credential class
parameter and any combination of the following parameters:
Parameters |
Descriptions |
---|---|
Requested resource. |
Optional. A resource referred to in the request. To match the query, access requests must include the specified resource in their list of requested resource(s). |
Request creator. |
Optional. The creator of the access request; i.e., the
requestor. (In the example, the ExamplePrinter’s WebID
|
Request recipient. |
Optional. Recipient of the access request; i.e., the resource owner to whom the access request is made. |
Purpose for the request. |
Optional. A purpose stated in the request. To match the query, access requests must include the specified purpose in their list of requested purpose(s). To specify multiple purposes to match, use the AccessCredentialQuery instead. |
Requested access mode. |
Optional. An access mode stated in the request. To match the query, access requests must include the specified access mode in their list of requested mode(s). To specify multiple modes to match, use the AccessCredentialQuery instead. |
The following example queries for active access requests made by ExamplePrinter for a resource to the resource owner. That is, the query specifies non-null values for the:
Requested resource,
Request creator, and
Access credential class of
AccessRequest.class
.
All other parameters are passed null
values.
List<AccessRequest> requestsByExamplePrinter = agClientForUser.query(
URI.create("https://storage.example.com/container/someResource"),
URI.create("https://id.example.com/ExamplePrinter"),
null, // Recipient of the access request (resource owner)
null, // Purpose
null, // Access Mode
AccessRequest.class).toCompletableFuture().join();
From the list, the resource owner can select the access request to act upon.
3. Verify the Requested Access#
To verify the access request, use AccessGrantClient.verify, passing it the access request.
For example, the following example uses AccessGrantClient.verify to verify an access request, checking for errors and warning.
// AccessRequest accessRequest = ...;
AccessCredentialVerification verification = agClientForUser.verify(accessRequest).toCompletableFuture().join();
if (verification.getChecks().isEmpty() || !verification.getErrors().isEmpty()) {
// Handle invalid access request
}
if (!verification.getWarnings().isEmpty()) {
// Handle warnings
}
4. Create the Access Grant#
For a valid access request, if the resource owner decides to grant the requested access [1], the application can call AccessGrantClient.grantAccess, passing in the specific access request to grant.
For example:
AccessGrant accessGrant = agClientForUser.grantAccess(accessRequest).toCompletableFuture().join();