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 pass in
a CredentialFilter object CredentialFilter<AccessRequest>
that
specifies the query filter values (i.e., a combination of the resource, creator,
recipient, purpose, and type).
You can use CredentialFilter.Builder and its methods to build an CredentialFilter for access requests:
Method |
Descriptions |
---|---|
Optional. Include a credential status in the query object. The following values are supported for access requests:
|
|
Optional. Include the creator of the access request in the
query filter. This is the requestor.
In the example, the creator value is the ExamplePrinter’s WebID
|
|
Optional. Include the recipient of the access request in the query filter. This is the resource owner. |
|
Optional. Include the resource in the query object. Use this filter to return access requests bound to a specific resource. |
|
Optional. Include a purpose in the query object. Use this filter to return access requests bound to a specific purpose. |
|
Optional. Include a time constraint on the issuance date in the query object. All matched credentials will have been issued within the provided duration value. Certain time constraints are available for use with this method, including: |
|
Optional. Include a time constraint on the revocation date in the query object. All matched credentials will have been revoked or canceled within the provided duration value. Certain time constraints are available for use with this method, including: |
|
Builds the CredentialFilter object. 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 CredentialFilter.Builder and its methods to:
Specify the Pending status
.status(...)
and the request creator.fromAgent(...)
, andBuild
.build(AccessRequest.class)
aCredentialFilter<AccessRequest>
.
Calls AccessGrantClient.query with the built
CredentialFilter<AccessRequest>
object.CredentialFilter<AccessRequest> accessRequestFilter = CredentialFilter .newBuilder() .status(CredentialFilter.CredentialStatus.PENDING) .fromAgent(URI.create("https://id.example.com/ExamplePrinter")) .build(AccessRequest.class); CredentialResult<AccessRequest> result = agClientForUser .query(accessRequestFilter) .toCompletableFuture().join();
Navigate through the response CredentialResult object.
List<AccessRequest> items = result.getItems(); if (result.nextPage().isPresent()) { CredentialResult<AccessRequest> page2 = agClientForUser .query(result.nextPage().get()) .toCompletableFuture().join(); }
From the list, the agent 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();