Open SimonShapiro opened 5 years ago
So, let's take a step back to see what it is that you really want to do.
It seem to me that you want a server to be able to perform authenticated resource access, right?
Down the road, this will be addressed with OAuth2 application tokens. But this has not been implemented yet.
In the meantime, you can use this hack: https://github.com/jeff-zucker/solid-file-client
I am trying to re-use the
solid-auth-client
object from the browser by passing it on to the server
Security measures (token expiration) will purposely prevent you from doing that.
Down the road, this will be addressed with OAuth2 application tokens.
can you elaborate or link to what you mean here? i'm not sure what an "OAuth2 application token" is. are you talking about offline refresh tokens, "service accounts", some kind of privileged meta-account that can act as another/any user at that OP, ...?
@RubenVerborgh sorry, i still don't understand. assuming you're referring to the "Application-only authentication" mode on that page (since the "Application-user authentication" case is substantially the same as OIDC), for the decentralized Solid use case, wouldn't "app-only" access just be implemented by the app having a webid (that is, it's a bot), and granting access to the app's webid in ACLs? that also works for acl:AuthenticatedAgent
cases, where you want some access token to access a substantially-public resource/API (perhaps for rate-limiting by webid). this (bots have webids) can be done today already, and could be done with less friction with #22. :)
also the "app-only" case on that page doesn't address the "app wants to act as the user even if the user is offline" situation, which i believe is the use case @SimonShapiro is talking about.
To be honest, I'm not (trying to be) an expert in this matter; I'm merely echoing the high-level plan that I've heard.
Bots with WebIDs already sound good, but we haven't figured out the auth details for them (currently it's username/password with cookies).
But even if a bot has its own WebID, it would still be good if they could use something like an app token and secret, such that they act on behalf of a user.
So application-user authentication is the way (or something along those lines).
Bots with WebIDs already sound good, but we haven't figured out the auth details for them (currently it's username/password with cookies).
all you need is for the app/bot's webid to list a solid:oidcIssuer
URI that has a <URI>/.well-known/openid-configuration
that answers with Content-type application/json, that has a jwks_uri
entry that, when dereferenced, answers (with content-type application/json) a JWKS with a public key that your bot signs its own id_tokens with. the bot doesn't need to authenticate with its (potentially imaginary) OP because it just signs its own id_tokens (and POPTokens) without ever talking to an OP.
that should work today.
Good point, indeed. Should work, just needs implementation.
it looks like NSS (at least running on solid.community) only does an OPTIONS
on the webid URI (presumably looking for the rel="http://openid.net/specs/connect/1.0/issuer"
link), and does not actually retrieve the full profile document to look for the ?webid solid:oidcIssuer ?issuer
triple.
this looks like an NSS bug. it will probably affect anyone whose webid document is hosted somewhere that didn't answer the expected Link
to an OPTIONS
(like me). specifically i saw this:
HTTP/1.1 401 Could not verify Web ID from token claims
and saw only this in my web server logs (duplicate fetches removed):
165.227.231.225 - - [11/Jul/2019:18:45:24 -0700] "GET /bot/oidc//.well-known/openid-configuration HTTP/1.1" 200 167 "-" "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" "zenomt.zenomt.com:443" 0.000 "-"
165.227.231.225 - - [11/Jul/2019:18:45:25 -0700] "GET /bot/oidc/jwks.json HTTP/1.1" 200 427 "-" "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" "zenomt.zenomt.com:443" 0.000 "-"
165.227.231.225 - - [11/Jul/2019:18:45:25 -0700] "OPTIONS /bot/card.ttl HTTP/1.1" 204 0 "-" "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" "zenomt.zenomt.com:443" 0.000 "-"
when trying to use my "bot" https://zenomt.zenomt.com/bot/card.ttl#me
and for the curious, here is the (expired) bearer token used with the above exchange:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJub25jZSI6ImQyM2Y5ZmQ3LWYxYmItNGIzYi1hNjc2LTEzNjY2NjgxMmU4YSIsInRva2VuX3R5cGUiOiJwb3AiLCJqdGkiOiIzNjIwZGYzMi01NTM2LTRlMmQtODU5MS0zZjBhNmE0NjM0ZjkiLCJhdWQiOiJodHRwczovL3plbm9tdC5zb2xpZC5jb21tdW5pdHkiLCJleHAiOjE1NjI4OTYwNDMsImlhdCI6MTU2Mjg5NTkyMywiaXNzIjoiaHR0cHM6Ly9hcHAuZXhhbXBsZS9vYXV0aC9jb2RlIiwiaWRfdG9rZW4iOiJleUpoYkdjaU9pSlNVekkxTmlJc0luUjVjQ0k2SWtwWFZDSXNJbXRwWkNJNklrc2lmUS5leUp1YjI1alpTSTZJakJtWkRZME9ETTRMV05qWlRFdE5ESTJPUzFoTmpOaExXWTBaRGRtWkdNeE9XWTJZaUlzSW5kbFltbGtJam9pYUhSMGNITTZMeTk2Wlc1dmJYUXVlbVZ1YjIxMExtTnZiUzlpYjNRdlkyRnlaQzUwZEd3amJXVWlMQ0poZFdRaU9sc2lZMnhwTFhSdmIyd2lMQ0pvZEhSd2N6b3ZMMkZ3Y0M1bGVHRnRjR3hsTDI5aGRYUm9MMk52WkdVaVhTd2ljM1ZpSWpvaWFIUjBjSE02THk5NlpXNXZiWFF1ZW1WdWIyMTBMbU52YlM5aWIzUXZZMkZ5WkM1MGRHd2piV1VpTENKcGMzTWlPaUpvZEhSd2N6b3ZMM3BsYm05dGRDNTZaVzV2YlhRdVkyOXRMMkp2ZEM5dmFXUmpMeUlzSW1OdVppSTZleUpxZDJzaU9uc2lhMlY1WDI5d2N5STZXeUoyWlhKcFpua2lYU3dpWlNJNklrRlJRVUlpTENKcmRIa2lPaUpTVTBFaUxDSmhiR2NpT2lKU1V6STFOaUlzSW00aU9pSTJMVEYxZFVwaVYyUXhjV05SWW5jeVYydFNhVGRvYm5wb1MyNDVkekp2Y1VSNVVEWlRXSFpOTjFkeU5tNUZSblU0UkRNd1kwMUdhbFZGVEY5M1kybEJTWFIxVWpKUVJWQlVTblJsZG5GWWEwTmhRbFI2TFRVMFVYUnlTekYzVWxScU4ySTVTM041WkRSWk4wUnZiRVJ3TVZVeFJtbEtObU16Y1hScGExVnhhbUppVTFReU1rb3djSGhMWWt4U2RHOVhSWFZ5V0VkWWJUVlRZVkZFYlMxSldsUnllRGROWmpSNlZXVTBWWFJqU2pORVRGbFZVVEJ4Vm1KbFFXbzRTV3MwTTBWM1lYVm1VblZIV0hOcFNqYzVSVlpQVFV0bVpUUlhVVTF3VFhsNExXUmtTemhqUzA0eFlqVjJORlJQZW5CWWVERjNOVmhaU2pVNFVsODBkR3RMWlRNNWVVeENjekY2VEZKeE4weE5SSEZ5YjBSNWRXaElTV2R6Y1ROd2JtNUNYMWxDWjJSeFFXVTNjR1pCYkZjNVR6aGFWWGRsVW1KRmJWOVNZVjkyWjNsNk1VNVBORWRVVmxOWk5rNHRjblJHZGtkVlYxRWlMQ0pyYVdRaU9pSkxJbjE5TENKaFkzSWlPaUl3SWl3aWFuUnBJam9pWkROaU5HVXhOR1l0T0dZMFpTMDBNalk1TFdFM05qY3RORE0wTkdFeVpESXdZelJqSWl3aVpYaHdJam94TlRZeU9EazVOVEl6TENKaGRYUm9YM1JwYldVaU9qRTFOakk0T1RVNU1qTXNJbUY2Y0NJNkltTnNhUzEwYjI5c0lpd2lhV0YwSWpveE5UWXlPRGsxT1RJemZRLnpfX2g1SC1RTlEzNWZSc0NLV2lLOG9nS2FIbXUyeWhsLTFXaW1pQkFSMjRvSnEwcFFVdG56TDZrbEZCNVhlRTlMMjZ6U0hSQnFaNDdUY1N3blZZSlRhR0pJNXJWRkhfdS1DVEgwbmFqUnNSdXB3ajBFS3hXUzM0U0d4NldpaHF4d0NkQXM3VlVoblgwUTdraTFVSzBESTFyMS1PR2VrMXZWbmt0WTNtekNPVlNJMXBUVkZNNVE1Vy1kVDN6bkdYUkFEWm5ObkpjcTFWR3NsUWF0SUZMX0ZvdnAwZlBDZnN4RnhYQ3NCZUU2LUNzM1NSU1NxMzB3V0RIY3ZNQXFzVXo4Q2JQVTFST1VCVlFJa2xxMlpqZnVZV2pvZzIxZ2REU1BhRkNYRWVzd2hoUVdTZG1Ud1c1MTV0NTA1TFNoZjRma19mcEtNRjNpTGNLaWZkVjVlM3RSZyJ9.W4y8flAWh6bqSDnDcM7HZUztzma66j2IJeQNzKWSBi7auH7PG85_x-aLNk6kYX-X-GIZG26iBIa-yP7GiWvwrAEm--hYzWTpRl6e0NGG3yFA42LbR-HzaXIenv_FKbh7YoLujoltDA1lYje8PJZvH5DRfga8MVLMiVBSwNJ5iY7DrNUZmOVTg6Cfr-HPWksxCJvT6TeTihxhK6u1cqBV2WiY7YSo9__YAsjN9O42bsBeN-MMqJU0J7OOdMyOueoR1H_rjbNGYg5-wkKMEYDTIkIkNCbHKPlgONzcmFhzqs1dO9eKNbA140NtMXrM9rL_dqQMzwcpL7_sVxaeGF2IlQ
this is the tool i whipped up to generate the above token.
luckily it looks like NSS didn't mind that the .well-known/openid-configuration was application/octet-stream instead of application/json. :) nginx doesn't have a way to set a content-type on a file without an extension (without setting the default content-type for everything in a directory).
i plan to do some more checking before i open a bug against NSS, to make sure i'm not doing something wrong.
from source code inspection, i've found at least one bug in NSS (oidc-auth-manager) and one misfeature.
bug: oidc-auth-manager https://github.com/solid/oidc-auth-manager/blob/5827449e0d1d287668fff667661003e529eb8f9d/src/preferred-provider.js#L70-L73 drops any path part of an OIDC issuer URI, so it can never successfully match an id_token's iss
if that claim has a path part (as my regular webid does, as well as the bot example above). issuers are allowed to have path parts, see (among other references) https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest .
misfeature: only one solid:oidcIssuer
is properly supported. if a profile lists more than one, the results are nondeterministic: https://github.com/solid/oidc-auth-manager/blob/5827449e0d1d287668fff667661003e529eb8f9d/src/preferred-provider.js#L105 . i had hoped this wasn't the case at https://github.com/solid/webid-oidc-spec/issues/30#issuecomment-497854769 .
i'll open a bug and enhancement for these two against oidc-auth-manager this weekend.
just from code inspection i still don't know why it won't load my profile document after doing an OPTIONS on it.
i plan to do some more checking before i open a bug against NSS, to make sure i'm not doing something wrong.
the tool i wrote can generate a usable access token if the issuer URI has no path part.
as another annoyance: NSS seems to cache some representations (like for the openid-configuration and jwks_uri) for way too long, and appears to ignore the Cache-control header. i have "Cache-control: max-age=60" on responses for those but NSS doesn't seem to reload them even after a day+.
I use
solid-auth-client
as the mechanism to authenticate users and the app to access their PODs. I understand that once authenticatedsolid-auth-client
places an object that is used later for interacting with their PODs into local storage. When I interact with the POD from the client usingsolid-auth-client
everything works ok in spite of the app being built in Python and compiled to Javascript via Skulpt.I am trying to re-use the
solid-auth-client
object from the browser by passing it on to the server so that the server can independently access the POD. There are many obvious use cases for this pattern. For example, I log in to the app and ask it to access my POD every night and send watermarked thumbnails of all new photos to an aggregator.My choice of using Python wherever possible may have inter-op issues with the object in local storage, but theoretically shouldn't. I have been trying to follow the pattern set out in the updated spec for
Sending a Request
.The authentication details are retrieved from
localStorage
with a javascript function:When the authentication details are passed to the Python server from local storage, it is held in a variable called
solid_auth_client
. First I set up the pop_token as a json object:I then retrieve the
private_key
fromsolid_auth_client
and convert it toPEM
format:I use the PEM version of the key to sign the
jwt
of thepop_token
:Finally, I use the
pop_token
as an authorization header in thehttp GET
from the PODs private area.This results in
HTTP error 401
.