openanalytics / containerproxy

Manage HTTP proxy routes into Docker containers
Apache License 2.0
45 stars 66 forks source link

Q: What would be required to consume special access token claim in role-claim or access expression? #79

Closed jhhhnikt closed 5 months ago

jhhhnikt commented 1 year ago

We have a customer that is considering an OIDC Provider that have a custom claim consisting of a list of json objects. The custom claim lives in the access token. The immediate solution we think will work is to let the applications themself read the SHINYPROXY_OIDC_ACCESS_TOKEN environment variable and manage how to act on the custom claim. The drawback is that all applications will be available on the landing page in ShinyProxy since the only data that indicate what applications an authenticated user have access to exists in the access token in the form of json objects. We'll need to trust the applications to manage access to data instead letting ShinyProxy control access, which can be both good and bad in this case.

Do you have suggestions on how to:

  1. Access the information in an access token and use it for role-claim or access expression to limit the available applications on the landing page.
  2. Parse the list in the custom claim in an another way than full string match, for instance using json or regex.

I recon a native solution might require introduction of a new authentication object, as far as I can tell oidcUser is based off DefaultOidcUser. And we're a bit unsure if clients should read access tokens in the first place.

psolymos commented 1 year ago

We have a similar use case where some custom claims used for authorization are part of the access token which is not available for SpEL as far as I can tell. The problem I see is that the access token can be a string in any format not just JWT, which would make its use unpredictable across OIDC providers.

jhhhnikt commented 1 year ago

The documentation points out how to use static methods and I've verified that it's possible to add your own classes into a separate namespace, and rebuild the ShinyProxy jar file from source. That way custom code will be available from SpEL expression.

But if the "access token" is not available for SpEL, or at least not in a documented way, it'll be difficult to pass the token to static methods in your custom build.

If ShinyProxy could provide a way to get the "access token" in SpEL, and maybe (?) add a convenience method for parsing and securely verifying JWT tokens from an OIDC provider, that would've been of great help for these kind of scenarios I think.

LEDfan commented 1 year ago

Hi, the access token is indeed not accessible from the SpEL context. In general it was difficult to get the access token in Spring, but we implemented this in shinyproxy already, so it is possible to add the access token to the spel context.

I checked and in Spring the access token is not automatically parsed as a JWT token, since (as mentioned) it's not by definition a JWT. However, it should be relatively easy to parse this as a JWT token and add the parsed token to the spel as well (but only if it's actually a JWT). The token is already validated by ShinyProxy, so there is no need to implement this again.

However, when using OpenID connect, the best way to provide additional information to the client is using the ID token or the userinfo endpoint. Usually every OIDC provider supports adding these additional claims to either the ID token or userinfo endpoint. Once you did that, these claims can be used in SpEL using #{oidcUser.attributes.my-claim}.

I'll keep this issue open as a feature request for accessing the access-token in SpEL, but I still advice to use the id token.

LEDfan commented 5 months ago

Hi, this is now part of the ShinyProxy 3.1.0 we released today, see https://shinyproxy.io/documentation/spel/#openid-connect. Thanks again for your suggestion!