Closed yvesonline closed 6 months ago
I do not have any experience with FusionAuth, so I can not really help you with that. If I find time later, I will try to give that a look, no promises, though.
However, regarding the 403, have you set up a local proxy that attaches the X-Auth-Header for the Gematik IDP for requests from your local machine? If not, that is one reason for 403 responses from them.
Instructions on how you can set this up are here.
The header value can be requested from Gematik.
Thanks for the pointer @eduardOrthopy , I somehow thought that setting the GEMATIK_AUTH_HEADER
environment variable would be enough. I'll have a look into that later and test it. Will report back here.
Again, as I said, I have 0 experience with FusionAuth and I have not done any test setup experiments, so take all of this with a rather large grain of salt.
Here are some things that I think you could try to reconfigure:
Not sure, that any of this will help wrt. the nonce issue you described, but those are some things I noticed.
Thanks for the valuable pointers (especially the proxy hint) @eduardOrthopy , I'm a step further!
The flow is now working until it comes back to auth/token
where it returns with a 401
in the relying party. I'm not sure why, I'm still debugging but I assume something is not right with signing. But it's a hunch, I'm still investigating.
I've noticed two items while testing with FusionAuth:
nonce
not being sent by FusionAuth. As a workaround I'm currently pasting this manually in but I'm not sure if this is causing problems downstream. Mainly because I'm not sure how the nonce
is exactly used and verified against (still checking the source code here). Question here is what I could do about this because I don't seem to be able to make FusionAuth generate this. Could I generate this is in the AuthEndpoint
if it's not set?Second item is the userinfo
endpoint. When I switch to auto-discover with FusionAuth it complains about the userinfo
endpoint missing in the .well-known/openid-configuration
(see screenshot).
Further digging around in the FusionAuth documentation shows that the userinfo
is used to retrieve the email address, see here:
FusionAuth will also leverage the /userinfo API that is part of the OpenID Connect specification. The email address returned from the Userinfo response will be used to create or lookup the existing user. Additional claims from the Userinfo response can be used to reconcile the User in FusionAuth by using an OpenID Connect Reconcile Lambda. Unless you assign a reconcile lambda to this provider, on the email address will be used from the available claims returned by the OpenID Connect identity provider.
This seems to be also relevant for verifying signatures as mentioned here:
The token has been signed using an asymmetric key-pair and the public key used to verify the signature has been published using the JSON Web Key Set (JWKS) and is correctly advertised by the jwks_uri in the .well-known/openid-configuration discovery document. In order for FusionAuth to correctly resolve this public key, you must configure the IdP using the Issuer and allow FusionAuth to discover the OpenID Connect configuration using the OpenID Connect discovery document. If you manually configure the Authorize, Token and Userinfo endpoints, automatic discovery of the JSON Web Key Set uri will not occur.
(Weirdly enough I can't specify the JSON Web Key Set uri manually.)
Question here is, could the userinfo
be implemented? What steps would be necessary?
I'm more than happy to provide PRs for both items if this is helpful at all but I'd need some guidance in implementing it.
Maybe @thomasrichner-oviva or someone from the Oviva team has pointers/notes?
And btw thanks for making this available @thomasrichner-oviva and team, so helpful and such good work 💪🏻 🎉 🙂
I'm a bit lost now debugging the 401
to the auth/token
endpoint. I'm trying to replay this locally because the flow always puts me back to our deployed relying party. I've got the debug level set to DEBUG
there but I can't see anything in the logs. I assume that it fails somewhere in TokenEndpoint
in line 45 (as far as I can see only in authenticate
AuthenticationException
s are thrown). How do I get the client_assertion
to replay this locally? Which JWT from which step is this? Do you have any pointers how to debug this?
Hey @yvesonline !
First off, it seems your IDP is trying to run a PKCE flow as indicated by code_challenge_method=S256
in your initial URL. At the moment the RP only supports the authorization_code
flow. Would be neat though to support PKCE.
The nonce is just forwarded to the GesundheitsID sektoraler IDP, i.e. the Gematik IDP. It enforces its presence. An option would be to just generate one in the RP in case it's missing. Somewhere here probably: https://github.com/oviva-ag/ehealthid-relying-party/blob/a0e3c2b0bd310aa064387f1882dc58ef4265e438/ehealthid-rp/src/main/java/com/oviva/ehealthid/relyingparty/svc/AuthService.java#L79
auth/token
is the last call in the flow, are you sure you are getting this far? If you get a 401 you probably fail here somewhere: https://github.com/oviva-ag/ehealthid-relying-party/blob/a0e3c2b0bd310aa064387f1882dc58ef4265e438/ehealthid-rp/src/main/java/com/oviva/ehealthid/relyingparty/svc/ClientAuthenticator.java#L49
Reg. debugging, you can set the JAVA_DEBUG
environment variable to true
. After that you can attach a remote debugger. See also https://github.com/fabric8io-images/run-java-sh/blob/master/fish-pepper/run-java-sh/readme.md
Thank you for your answer @thomasrichner-oviva !
You're right, FusionAuth is initiating a PKCE flow. I don't seem to be able to explicitly disable it. The doc says it automatically falls back:
Proof Key for Code Exchange, more commonly referred to as PKCE (pronounced pixy) is an extension to the Authorization Code grant. This extension is intended to help secure the code exchange workflow utilized by this OpenID Connect configuration. This extension is used by default on all OpenID Connect IdP configurations, and it cannot be disabled. The use of this extension is backwards compatible with identity providers that either do not require or support PKCE. FusionAuth will pass along the required PKCE request parameters to the OpenID Connect identity provider and if the provider supports PKCE, the extension will be utilized, and if it is not supported it will be ignored.
From: https://fusionauth.io/docs/lifecycle/authenticate-users/identity-providers/overview-oidc
However this doesn't seem to work. When the flow comes back FusionAuth complains that it can't determine the code_verifier
, pointing towards that it's trying to do PKCE.
Any idea why FusionAuth thinks that the RP supports PKCE? I see code fragments called PKCE in the code but I'm not sure I understand why they're called PKCE?
What would be necessary to support PKCE? (Disclaimer: I'm no OpenID Connect expert.)
The relying party uses PKCE between itself and the OpenID federation. That's why there is code related to it.
Not sure why FusionAuth would think it supports it though, the /.well-known/openid-configuration
is very clear in what it supports.
It would not be a huge amount of work to actually support it. Handling and verifying a few more query params should be it.
@yvesonline can we close this?
@thomasrichner-oviva Yes, can be closed, we couldn't make it work together with FusionAuth.
Instead of Keycloak I'm trying to make this work with FusionAuth but I'm running into a couple of problems.
The RP is running under
rp.d.uhhq.dev
and registered with the TU and I'm now initiating a login from FusionAuth.FusionAuth redirects me to the URL:
https://rp.d.uhhq.dev/auth?code_challenge=...&code_challenge_method=S256&client_id=admin&redirect_uri=<FusionAuth callback URL>&response_type=code&scope=openid&state=...
Which brings me to the page where I can select the provider:
Now when I execute a login it fails with a
500
because the request to the Gematik fails with a400
:"unexpected exception: http request failed: bad status 'POST https://gsi.dev.gematik.solutions/PAR_Auth' status=400"
When I print the
parBody
withSystem.out.println(new String(parBody.build()));
inredirectToSectoralIdp
I see that thenonce
is missing:client_id=https%3A%2F%2Frp.d.uhhq.dev&code_challenge=...&code_challenge_method=S256&redirect_uri=<RP callback URL>&nonce&state=...&scope=openid+urn%3Atelematik%3Aemail+urn%3Atelematik%3Aversicherter+urn%3Atelematik%3Adisplay_name&acr_values=gematik-ehealth-loa-high&response_type=code
Shouldn't FusionAuth send the
nonce
?If I manually inject the
nonce
for testing purposes the400
disappears and I run into a403
with the Gematik sectoral IdP (I haven't further investigated why).The configuration in FusionAuth looks like this:
I'm aware that this is new territory as you're using Keycloak but was wondering if you have any pointers/thoughts? I'm stepping a bit in the dark at the moment.