Coder Social home page Coder Social logo

Comments (7)

NoelDeMartin avatar NoelDeMartin commented on September 23, 2024 1

Thanks, I'll check it out! I'm going to start a new app soon, and I'll try it there first. If that goes well I'll update Media Kraken afterwards.

from media-kraken.

NoelDeMartin avatar NoelDeMartin commented on September 23, 2024 1

TLDR: Media Kraken should work with new servers now :). Let me know if there's any issues.


After some more tinkering, I decided to use DPoP by default and allow users to switch the authentication method if they want. It seems like it is too difficult to know whether a server supports DPoP or not, and most servers should already support it so I think this is a good compromise.

As per the refresh problem, I still haven't seen any movement in Inrupt's issue and I'm not sure of when it'll be fixed. So I decided to go ahead with a simple UI that remembers the url so that users can log in again without too much hassle.

Since we're talking about Inrupt's PODs, I'll also mention a problem I found that could be an issue for heavy users of the application. It seems like listing container resources doesn't return their modified date, and that's what I was using to know whether a movie has been updated or not since the last log in. The consequences of this is that I have to request all the movies every time the application starts, and if a user's got many movies that will make the app unusable. I'll see what I can do about this.

from media-kraken.

NoelDeMartin avatar NoelDeMartin commented on September 23, 2024

@megoth I've done a small app as a proof of concept using the new authentication libraries, can you confirm that it works properly for you? If all's well, I'll move that code into Media Kraken.

Here it is: https://ramen.noeldemartin.com

I've done my own tests and it should work, but there are a couple of things I'd like to ask you.

You mentioned Inrupt's auth client works for old Solid servers as well, but for me it didn't work for node-solid-server v5.2.2. Is there something I am doing wrong? Or you meant to say that it works with the latest version of old servers?

Related to that, since I am falling back to solid-auth-client for servers that don't support DPoP (like NSS v5.2.2), do you know how can I tell if a server supports DPoP? For example, I know that Inrupt's servers support it, but looking at the response from this url it doesn't seem like they do: https://broker.pod.inrupt.com/.well-known/openid-configuration. In constrast to that, latest versions of NSS and other servers that support DPoP include "dpop" within a token_types_supported key that is missing in this response.

from media-kraken.

megoth avatar megoth commented on September 23, 2024

@NoelDeMartin sorry for late response, have had a vacation for the last three weeks ^_^

I've tested with Inrupt's Solid servers, and the app works with the following:

But it fails with pod-compat.inrupt.com:

bilde

I'm not quite sure what goes wrong here, but I noticed that you haven't given a clientName in https://github.com/NoelDeMartin/ramen/blob/main/src/authentication/DPoPAuthenticator.ts#L29-L32 (as compared to what I've done in https://github.com/megoth/dnd5e/blob/main/src/models/session/index.tsx#L20-L22, or using the Solid UI React Login Button at https://github.com/inrupt/pod-browser/blob/master/components/login/provider/index.jsx#L155). I thought clientName was optional, but it's worth a try.

from media-kraken.

megoth avatar megoth commented on September 23, 2024

And to answer more of your questions, yes, I did mean the newest versions of the old servers. I don't know to much about the auth algorithms in general, so I'll ping @NSeydoux on this in hopes that he knows more about this.

from media-kraken.

NSeydoux avatar NSeydoux commented on September 23, 2024

Hi @NoelDeMartin, hi @megoth ! Unfortunately, there is no standard way to know if an identity provider and/or a resource server supports DPoP or not a priori. The token_types_supported entry in the NSS Solid Identity Provider's openid-configuration is not part of the OpenID spec, which is why it doesn't appear in https://broker.pod.inrupt.com/.well-known/openid-configuration.

You are absolutely right @megoth, clientName is optional, so that's not what causes the issue. Actually, I'm not even sure what is the problem here, because while being two separate resource servers, pod.inrupt.com and pod-compat.inrupt.com should use the same Solid identity provider (as far as I can tell)...

From what I can see, it looks like Ramen is trying to see if the identity that's provided is either an IdP or a Pod root, to which it appends /profile/card#me. That's not an ideal solution, since a WebID can take any form as long as it's a valid URL that dereferences to a FOAF profile (e.g. Sarven's infamous https://csarven.ca/#i). We are looking at adding a convenience function for this in our libraries, but basically the best way to authenticate a user based on a given IRI that may be either its Solid identity provider or its WebID is:

  • Dereference the URI. If you get RDF back (the Content-Type should tell you that), that's a WebID. You can look for a triple using the predicate http://www.w3.org/ns/solid/terms#oidcIssuer: that should give you the user's Solid Identity Provider (as mandated by the spec). Then you can use the provider's IRI in the auth library.
  • If you don't get RDF back, you can try to dereference <IRI>/.well-known/openid-configuration. This path should always exist for an OIDC-compliant identity provider. It that works, you can use the provider's IRI with the auth library.

I'm not sure that this is causing the issue, but after two failed requests against https://broker.pod-compat.inrupt.com/ (there seems to be some CORS errors, because the IdP is only expecting foreign requests on its defined endpoints, and not on https://broker.pod-compat.inrupt.com/profile/card for instance), another authentication attempt happens, which tries to go through the implicit login flow, which isn't supported by https://broker.pod-compat.inrupt.com/ because it has some security issues. It's not a flow that is implemented by our library, so I guess at this point Ramen switched to solid-auth-client, the legacy library, which explains the failure.

So in a nutshell, what's the rule to try the different auth libraries, and is my explanation making any sense ^^ ?

from media-kraken.

NoelDeMartin avatar NoelDeMartin commented on September 23, 2024

@megoth pod-compat should work now, read below for details (TLDR: I hard-coded the domain :/).

@NSeydoux Yes, your explanation makes sense! As you guessed, the problem was that it was using solid-auth-client. I am already doing something similar to what you mention, here's what I'm doing exactly:

First, I try to obtain the webId. I am doing this to obtain the solid:oidcIssuer, before doing this app I was not too familiar with the distinction between idp/webId and I just sent whatever the user introduced as the idp (that's how media-kraken works at the moment). So now I try to get the solid:oidcIssuer and if I can't find it, I use the domain of the url introduced as the idp.

Then, I try to guess if the server supports DPoP. I do this with some heuristics, because I haven't found a way to know for sure, and seems like there isn't. At the moment, I am reading /.well-known/openid-configuration to search for the token_types_supported, if that doesn't work I make a request to the solid:privateTypeIndex url (obtained from the webId) using an invalid DPoP token. If the server supports DPoP I should get a 401 error and if it doesn't a different error code. If both of these fail, I fall back to a regular expression for known DPoP providers.

Finally, depending on the information I got from these two steps, I use a @inrupt/client-authn-client-browser or solid-auth-client.

If you want to see the actual code doing this, it's here: src/services/Auth.ts:74

And sadly, it seems like I'm not able to guess that Inrupt's servers support DPoP authentication. The only reason why the others worked was that their domains are hard-coded in my code, and I've fixed pod-compat by hard-coding it as well. The regex I'm using now is this one: /^https?:\/\/broker\.(pod|pod-compat|demo-ess)\.inrupt\.com/. If you think I could improve it by just looking for inrupt.com or adding some other subdomains, let me know.

You may be wondering why is solid-auth-client the fallback and not the other way around, since it'd make more sense to use the modern authentication paradigm by default. The problem with that is that I have no way of knowing for sure that a server does not support DPoP authentication (as we've discussed). So if I decide to fall back to DPoP, I'd never use solid-auth-client because I wouldn't be able to distinguish between a server that doesn't support DPoP and a server that supports DPoP but I couldn't tell.


So, to summarize the current status of this issue. I have been working on the new authentication strategy in the Ramen app, and once I'm confident with that I'll add those improvements to Media Kraken.

Right now I have two blockers:

  • inrupt/solid-client-authn-js#423: Until this is not fixed, I won't update Media Kraken because it has an important impact in the UX. I guess if months go by and that issue is still open I'll finally do it anyways, but I'd rather not.

  • DPoP vs Legacy authentication: As mentioned above, the heuristics I'm using right now are not foolproof. If there's really no better way, I'll have to do something else in Media Kraken because I don't think the current approach is acceptable for a real application. And dropping support for legacy servers is not something I'm contemplating at the moment. So maybe I'll end up adding some UI affordance to force legacy authentication. I'm open to suggestions!

from media-kraken.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.