decentralized-identity / jsonld-common-java

Shared JSON-LD Java library.
Apache License 2.0
8 stars 6 forks source link

Problem loading custom context #10

Closed fabrii closed 1 year ago

fabrii commented 1 year ago

Hi! I am having an error trying to load custom contexts. I am using this library through https://github.com/danubetech/verifiable-credentials-java

I tried publishing them in different several ways with no luck (http, https, with localhost, domain, etc).

In the log I see the following warning:

2022-11-21 10:43:57,544 WARNING [fou.ide.jso.ConfigurableDocumentLoader] (executor-thread-0) Cannot load context: originated in this line: https://github.com/decentralized-identity/jsonld-common-java/blob/632c989ab0698433dfa27c87ec13440df4aef0a1/src/main/java/foundation/identity/jsonld/ConfigurableDocumentLoader.java#L113

After that, I get Imported context is null.: foundation.identity.jsonld.JsonLDException: Imported context is null.

You can reproduce this issue with the following context: https://w3id.org/dcc/v1

List<URI> uris = new ArrayList<>();
uris.add(new URI("https://w3id.org/dcc/v1"));

com.danubetech.verifiablecredentials.VerifiableCredential.Builder builder = VerifiableCredential.builder()
       .contexts(uris)
       .type(credentialType)
       .id(new URI(credentialId))
       .issuer(new URI(issuerDID))
       .issuanceDate(new Date())
       .credentialSubject(credentialSubject);

What is really weird is that it works ok with https://www.w3.org/2018/credentials/v1 (may be it is cached?), but if I publish the same context in my localhost, it does not work.

Any hints? Thanks!

peacekeeper commented 1 year ago

Hello, thanks for the detailed problem report!

You need a document loader that knows how to load your custom context. If you create a VerifiableCredential (which is a subclass of JsonLDObject), then a default context loader is used, which has several contexts already cached locally. This explains why https://www.w3.org/2018/credentials/v1 is working fine.

To enable loading of your custom context, you have two options:

  1. Turn on loading contexts via http/https (quick&easy, but this has security risks and is therefore disabled by default):
VerifiableCredential vc = builder.build();
((ConfigurableDocumentLoader) vc.getDocumentLoader()).setEnableHttp(true);
((ConfigurableDocumentLoader) vc.getDocumentLoader()).setEnableHttps(true);
  1. Add your custom context to the local cache (better):
VerifiableCredential vc = builder.build();
((ConfigurableDocumentLoader) vc.getDocumentLoader()).getLocalCache().put(URI.create("https://w3id.org/dcc/v1"), JsonDocument.of(MediaType.JSON_LD, ... yourcontextfile ...));

Let me know if this works or if you still have problems.

fabrii commented 1 year ago

Thanks for the fast response! Both options worked perfectly.

I have one last question: why do we need to load the context when signing the VC?

peacekeeper commented 1 year ago

The context is needed for canonicalizing the VC into a list of RDF quads, which then get signed. See the following resources for some more technical information. Both specs are under active development, perhaps it would be interesting for you to contribute!

https://w3c.github.io/rdf-canon/spec/ https://w3c.github.io/vc-data-integrity/