CommunitySolidServer icon indicating copy to clipboard operation
CommunitySolidServer copied to clipboard

Add authorization server (spec evolvement)

Open woutermont opened this issue 4 years ago • 14 comments

The current IDP implementation does not seem fully up to date with the Solid-OIDC specification. Most importantly, the specification now prescribes a separation of responsibility between the IDP itself an a new actor called the Authorization Server (https://github.com/solid/solid-oidc/commit/7997d64bd181559c855514d3b2b19dc0169a5d1a).

These changes boil down to the following (which a.f.a.i.k. are not yet implemented in the CSS).

  • [x] The solid_oidc_supported field is no longer required in the ./well-known/openid-configuration. Discovery now happens by including webid in the scopes_supported of that resource instead.
  • [ ] The IDP should no longer return an Access Token. Instead, it should return an ID Token (and if requested, a Refresh Token). This token, just like the Access Token before it, needs to be DPoP-bound (draft 4), and needs to include the WebID in a webid claim when the webid scope was requested.
  • [x] The ID Token now needs to include an azp claim containing the client/app id (previously in client_id).
  • [ ] A "nonce" claim does not seem to be necessary in the ID Token (not sure if that's normative).
  • [x] The ephemeral client (http:​//www.w3.org/ns/solid/terms#PublicOidcClient) should no longer be supported.
  • [ ] The WWW-Authenticate HTTP header in response to an unauthenticated request to the RS must include an as_uri parameter pointing to the new Authorization Server (AS).
  • [ ] This AS should be a UMA server that allows exchanging an ID Token for an Access Token (this is a SHOULD, but no other options than a UMA server are present). About how exactly this happens, I'm not yet entirely clear (no expert on UMA); hopefully @elf-pavlik and/or @matthieubosquet can chip in.

woutermont avatar Feb 10 '22 22:02 woutermont

  • [ ] The solid_oidc_supported field is no longer required in the ./well-known/openid-configuration. Discovery now happens by including webid in the scopes_supported of that resource instead.

This change has already been done in the 3.0.0 branch.

  • [ ] The IDP should no longer return an Access Token. Instead, it should return an ID Token (and if requested, a Refresh Token). This token, just like the Access Token before it, needs to be DPoP-bound (draft 4), and needs to include the WebID in a webid claim when the webid scope was requested.

This is going to require some deep diving into the oidc provider library probably. How important is it to use draft 4 of dpop? Currently we are using v6 of the oidc library which only supports draft 1. I'm looking into what is necessary to upgrade to v7 which currently supports draft 3.

  • [ ] The ephemeral client (http:​//www.w3.org/ns/solid/terms#PublicOidcClient) should no longer be supported.

This was done by closing the issue saying we still needed to add support for that 😅 #837

joachimvh avatar Feb 11 '22 07:02 joachimvh

Ha, perfect, two down before we even started 👌

How important is it to use draft 4 of dpop? Currently we are using v6 of the oidc library which only supports draft 1.

I don't think it has much of an impact actually, but I did not look into it with much detail.

I'm looking into what is necessary to upgrade to v7 which currently supports draft 3.

We actually have been using v7 for a while now in our Solid-OIDC proxy (currently a private repo, but I'll look into providing access).

woutermont avatar Feb 11 '22 09:02 woutermont

Spending some time with this while I'm updating to OIDC provider v7.

  • [ ] A "nonce" claim does not seem to be necessary in the ID Token (not sure if that's normative).

I'm actually not sure what you mean here but I don't think this is something we do?

Another one that I discovered from the spec:

For an ID token.

aud - The audience claim MUST be an array of values, one of which is the ClientID claim is used to identify the client, another one is the string solid.

Will be part of the investigation of how to make the server only return an ID token and not an access token probably, since the OIDC provider does not allow access tokens to have an array as audience. Similar for the cnf value, since the provider is setting that on the access token right now.

joachimvh avatar Feb 15 '22 10:02 joachimvh

Having a look into the OIDC provider, I'm not sure if it will (easily) be possible to change the audience of an id token as it seems to be fixed: https://github.com/panva/node-oidc-provider/blob/142d5c7872b1d919b156e4cb61317e4dae514551/lib/models/id_token.js#L78

Similarly, the cnf field is done by letting a class extend isSenderConstrained, as the AccessToken class does here: https://github.com/panva/node-oidc-provider/blob/142d5c7872b1d919b156e4cb61317e4dae514551/lib/models/access_token.js#L12 . Seeing as the IdToken class does not extend this, it might be necessary to manually add this.

joachimvh avatar Feb 15 '22 12:02 joachimvh

  • [ ] This AS should be a UMA server that allows exchanging an ID Token for an Access Token (this is a SHOULD, but no other options than a UMA server are present).

Linking to a cached issue since the issues are currently closed off for some reason. But it has been stated that the OIDC provided library does/will not support UMA which makes me wonder if this will be possible with this library.

Edit: cache link no longer works but didn't say much more than the summary above.

joachimvh avatar Feb 16 '22 11:02 joachimvh

  • [ ] This AS should be a UMA server that allows exchanging an ID Token for an Access Token (this is a SHOULD, but no other options than a UMA server are present).

Linking to a cached issue since the issues are currently closed off for some reason. But it has been stated that the OIDC provided library does/will not support UMA which makes me wonder if this will be possible with this library.

I was just wondering the same, going through your links. Also no idea how you would add the Permission endpoint to issue tickets, with this library.

Falx avatar Feb 16 '22 12:02 Falx

azp claim added in #1166

joachimvh avatar Feb 21 '22 09:02 joachimvh

Just to add some resources to this issue, in the context of the SAI panel I looked into developing some modules against the v4.0.0 of the Community Solid Server to enable authorization & authentication using UMA Access Tokens.

The modules can be found here: https://github.com/laurensdeb/interoperability/tree/main/packages/css

Mainly they concern a new CredentialExtractor for the UMA tokens, and a PermissionReader which extracts modes from these access tokens.

Note that this mechanism assumes an external UMA Authorization Service is performing the authorization, and does not explicitly use or depend on the IdP that is in the CSS

Note that we are using the error metadata support from v4.0.0 to more cleanly handle the UMA-style WWW-Authenticates headers that are returned on a 401 in the revised Solid-OIDC spec, and converted into a ticket by the external UMA Authorization Service.

laurensdeb avatar May 03 '22 17:05 laurensdeb

That's great @laurensdeb! I would definitely be interested in adding this to the server if you want to open a PR, although I'm guessing it is probably useful for you to have it separate while you're still experimenting with it. I'm guessing it would also require some changes to make sure it doesn't interfere with the other authentication options.

The one thing that surprises me is to see ACL permissions in the UMA token, especially since it uses URIs such as acl:Create which don't actually exist in the ontology (yet?). Is this part of the spec or just one way to experiment with it?

joachimvh avatar May 04 '22 07:05 joachimvh

I would definitely be interested in opening a PR for this, the next few weeks are however quite busy as I'm finishing the writing part of my thesis (in the context of which some of these modules have been developed). But in june my schedule will (hopefully) clear up a bit.

Indeed, some minor tweaks still needs to be done in order to ensure that the UMA tokens are always considered separately from Solid OIDC tokens. For now, in order to avoid this conflict, we've modified the Waterfall-handler to only support DPoP-bound ID Tokens (and thus disabled the BearerWebIdExtractor). This works because the UMA tokens don't need to be DPoP-bound, and are thus regular Bearer tokens to a client. However ideally the canHandle method would verify if the token presented is of the correct format to be considered by UMA.

In fact the modes used here are part of the Solid Application Interoperability specification. Note that the panel still working on a more normative definition of these modes, which is part of the reason why this "playground" was developed on top of the CSS.

laurensdeb avatar May 04 '22 08:05 laurensdeb

I have created matching issue for Solid-OIDC client in https://github.com/inrupt/solid-client-authn-js/issues/3181 There is also an upcoming Keycloak extension which will implement latest published Solid-OIDC: https://github.com/CarrettiPro/keycloak-solid It would be great if we can get this issue moving forward. I'm planning to bring it up in Solid CG meetings next week to see if there are some chances that someone would be willing to contribute to this effort.

elf-pavlik avatar Oct 12 '23 12:10 elf-pavlik

It would be great if we can get this issue moving forward.

Parsing incoming UMA tokens as RS is something that we are probably looking into in the near(-ish) future.

Also fulfilling the role of AS that generates the necessary tokens I can't give any promises on. I would love to have support for it in CSS but I'm not sure on the immediate feasibility with the library that we use for OIDC.

joachimvh avatar Oct 12 '23 12:10 joachimvh

I will need to check first how @laurensdeb did it in https://github.com/laurensdeb/interoperability/tree/main/packages/css I guess that OIDC responsibility ends once the DPoP bound ID-token gets issued. From there OAuth2+UMA take responsibility of the access tokens. OP (aka IDP) and AS should be fully independent, since OP is End-user associated while AS is RS (and at least indirectly RO) associated.

sequenceDiagram
  autonumber
  box green Alice
  actor Alice
  participant OP as OpenID Provider
  end
  box orange PerformChart
  participant C as Client
  end
  box blue ACME
  participant RS as Resource Server
  participant AS as Authorization Server
  actor ACME
  end
  Note over C: acts on behalf of Alice
  C -->> RS: GET /project-x
  RS -->> C: Project X

CSS's AS should be able to accept IDTokens issued by Keycloak-Solid and any other Solid-OIDC conformant OP.

On the other hand, the RS (Storage) only will need to work with access_tokens issued by it's AS. So CSS could come up with any implementation specific approach here. @woutermont most likely can offer some insights on an approach that can be ready for potential future spec for AS <-> RS interop.

When it comes to the OIDC library, probably it doesn't support DPoP binding of the ID Token. This might be the main challenge on the OP side.

I'm also going to follow up on https://github.com/CommunitySolidServer/access-token-verifier/issues/211 since it will be required for that change.

elf-pavlik avatar Oct 12 '23 13:10 elf-pavlik

Feels almost ominously coincidental, but I started working on this again last week 😃 (very busy a.t.m. so will probably be for November before I have something to show)

woutermont avatar Oct 12 '23 14:10 woutermont