Pending link with manual completion
-
I want to allow a logged in user to link with a third-party identity provider so my app can get a token for that provider. I'm trying to use a pending link, but the problem I am running into is that FusionAuth wants the complete the pending link instead of allowing my application to complete it. Is it possible to do what I want? When I call fusionauth/oauth2/authorize I already have the user's FusionAuth ID, so I just want the pending link ID to finish the link myself.
Current setup:
I have a non-browser client application that is not using hosted login, but is instead using api/login.
I have an existing user in Fusion Auth (self hosted) with no linked accounts and registered to my application.
I created an OIDC identity provider with the link strategy of Pending Link and set Create Registration to false. No reconcile lambda.
An identity provider with the same client id/secret and endpoints works to create FusionAuth accounts when linking strategy is "Link on email" and Create Registration is true.
I have a web server that exposes endpoints for the client and makes requests to FusionAuth.What I tried/expected:
- Client app opens browser to mysite/authorizelink, passing the FusionAuth token returned by /api/login and an Identity Provider ID.
- mysite calls fusionauth/oauth2/authorize with idp_hint and response type "code".
- Browser is redirected to provider/oauth2/authorize
- User logs in to provider & authorizes
- Provider redirects browser to fusionauth/oauth2/callback with authorization code
- FusionAuth redirects browser to mysite/authorizelinkcallback
- mysite calls fusionauth/api/identity-provider/login with application ID, authorization code, redirect uri, and IdP ID.
- If a pending link id is retrieved, mysite calls fusionauth/api/identity-provider/link with the FusionAuth user ID and pending link ID.
What happens:
Steps 1 through 5 go as expected.
After being redirected to fusionauth/oauth2/callback, instead of being redirected to mysite/authorizelinkcallback, the browser is instead redirected to fusionauth/oauth2/start-idp-link, which prompts the user to login or cancel the link request. -
@justing said in Pending link with manual completion:
I want to allow a logged in user to link with a third-party identity provider so my app can get a token for that provider.
I'm not sure I understand.
Say you are using the OIDC identity provider. You want your user to log in with OIDC, and later be able to get am access token.
If that is what you are trying to do, you can use the normal linking strategy (link on email) and a long lived refresh token will be stored on the link object.
From https://fusionauth.io/docs/v1/tech/apis/identity-providers/openid-connect
FusionAuth will also store the refresh_token returned from the external OpenID Connect provider, if such a token is provided, in the identityProviderLink object. This object is accessible using the Link API.
Later, in your app, you can then retrieve that token for the user using the Link API, present the refresh token to the OIDC provider and then get your access token.
Each identity provider tries to store a long lived token, but they all differ slightly in terms of what is available. Consulting the API documentation is your best bet.
Pending links are used when you are trying to link a fusionAuth user user with an account managed by an idp, but you don't have a convenient way to tie them together (like an email address or username that is the same in both systems).
Does this help?
-
@dan Thanks for the response.
Basically I want to do third party service authorization like described here: https://fusionauth.io/learn/expert-advice/oauth/modern-guide-to-oauth#third-party-service-authorization
The workflow for this mode looks like this:
- A user visits TWGTL and logs into their account.
- They click the “My Profile” link.
- On their account page, they click the “Connect your WUPHF account” button.
- This button takes them over to WUPHF’s OAuth server.
- They log in to WUPHF.
- WUPHF presents the user with the “permission grant screen” and asks if TWGTL can WUPHF on their behalf.
- The user grants TWGTL this permission.
- WUPHF redirects the browser back to TWGTL where it calls WUPHF’s OAuth server to get an access token.
- TWGTL stores the access token in its database and can now call WUPHF APIs on behalf of the user. Success!
I don't have a web user interface for the user to log in at, instead it is a custom application. But I do have a web service to handle the OAuth flow so when the user click's the "Connect to third-party" button in the application it opens a browser window for them to go through the authorization process.
According to https://fusionauth.io/docs/v1/tech/apis/identity-providers/openid-connect#complete-an-openid-connect-login, I need an authorization code from the OIDC identity provider. The problem I'm stuck on is that calling fusionauth/oauth2/authorize is trying to complete the link instead of returning the authorization code.
I'm guessing the way I am trying to use the authorize endpoint is not the intended way. I was trying to use FusionAuth to acquire the authorization code from the OIDC identity provider so that I would not have to maintain my client code and secret in two places. Am I just supposed to get the authorization code myself without going through FusionAuth?
-
@justing hmmm
If you are trying to avoid duplicating the client secret and client id, you could pull them from FusionAuth using the application API.
From looking at your first post, I'm not quite clear whether you are using the FusionAuth hosted login pages or not. You say you are not, but you also have a user end up at the pending link hosted login page.
I don't understand why the user is, in step 5, redirected back to FusionAuth. What is the redirect_uri you are providing in step 2 and step 3?
If you are outside the hosted login pages, you want to use https://fusionauth.io/docs/v1/tech/apis/identity-providers/openid-connect#complete-an-openid-connect-login after step 4.
Does this help?
-
@dan
Thank you for pointing out that client id and secret are available from the api. I missed that when I looked before.I do not want to use the hosted login page.
Maybe this is a more direct way of asking what I want:
Can I use FusionAuth to get an authorization code from a third party OIDC provider without the user having a FusionAuth account first?If so, it looks like I can do what I want with /api/identity-provider/login and /api/identity-provider/link. I just need to get that authorization code first.
-
@justing said in Pending link with manual completion:
Can I use FusionAuth to get an authorization code from a third party OIDC provider without the user having a FusionAuth account first?
I guess I don't understand.
Why would you use FusionAuth to do this? You can send the user to the third party OIDC provider (maybe pulling the client id/secret from FusionAuth if you want it to be the repository for such things), let the user log in, and the third party will send you back an authorization code.
-
@dan Thanks for the help, I was able to get it working.
If it helps anyone else, my problem was misunderstanding how to properly do custom login/linking. I was trying to get FusionAuth to acquire the authorization code from the third-party provider and then return it to my code, where I would call further api functions. Everything works fine now that I acquire the authorization code directly and pass it to the FusionAuth api calls.
-