Solid Authentication
You are unauthenticated.
This is a static client application following the OIDC authentication flow outlined in the Solid OIDC Primer.
The code for this exampe app is available on GitHub.
Step One ☞
This app is solid-authentication.rdf.systems
. It contains the JavaScript that will help with the authentication process.
Step Two ☞
I have a WebID over at Inrupt's dev portal: https://id.inrupt.com/nikolaswise
.
Step Two point 1 ☞
Grab the WebID from the form submit, and fetch the url. Request JSON with the accept: application/ld+json
header and grab the provider url out: let provider = json["http://www.w3.org/ns/solid/terms#oidcIssuer"]["@id"]
.
Step Three ☞
fetch(`${provider}/.well-known/openid-configuration`)
To go ahead and grab the provider configuation object. This only comes back as JSON so no need to content negotiate. We want to grab the authorization_endpoint
from the config.
Step Four ☞
One: Create a cryptographically random string with like, crypto.randomUUID()
Two: Base 64 URL Encode the S256 hash of the that rando string. Aaron's answer hereis unsuprisingly good.
Step Five ☞
Stuff the challenge only into sessio storage.
Step Six ☞
Make a reqeest to the authorization_endpoint
with some extra query params at the end:
- response_type
- "code"
- redirect_uri
- some.callback.url.example/callback
- scope
- openid%20webid%20offline_access
- client_id
- http://solid-authentication.rdf.systems/webid
- code_challenge_method
- S256
- code_challenge
- generated_challenge_here
Once the app makes that request, the Provider will make a call to `client_id` provided to make sure that it's a real thing. This means your app needs to expose a JSON blob like the one in the example. Ours is a static blob.
Note: the redirect URI in your request has to match exactly the one provided by the JSON blob. Trailing slashes matter!
Note: I got a CORS error now? Because we're not fetch
ing this URL, we're redirecting to it! Set it to the window.location
.
Step Seven — Eleven ☞
Hand-wavey server magic that's not our problem today.
Step Twelve ☞
We're back at our application screen with a lot of neat shit in the query! We Generate A DPoP Token. Somehow. I'm gonna do what IBM says to do.
Step Thirteen ☞
Now that we have a generated Key pair, both Public and Private I guess, we Generate the DPoP Header?? This was Very Hard but the friends at Use.ID helped.
Step Fourteen ☞
Once we have our fancy DPoP token we can get an Access Token and a Refresh Token hooray. We put those into Session Storage, clean out the qquery params in our URL, then call whatever side effects we want to happen if we're authenticated. In this case we update our dom and remove the login button!