ory / network

Ory runs a global end-to-end security infrastructure for humans, robots, and servers. We build and use open source software.
Apache License 2.0
80 stars 6 forks source link

OAuth2 Clients with the "skip consent" flag fail to execute `prompt=none` flows #317

Open aeneasr opened 1 year ago

aeneasr commented 1 year ago

Preflight checklist

Describe the bug

OIDC clients, that have "skip consent" setting enabled, fail to find a previous suitable consent, and instead silently create a new one. This does not make the consent UI pop-up, but fail prompt=none auth requests with consent_required error. Explicitly remembered consents do not have this problem.

The problem is that skip consent is only used in the UI and is not respected in the "find previous consent" logic in Ory Hydra.

Reproducing the bug

  1. Create client with skip consent flag set to true
  2. Perform oauth2 flow with prompt=none
  3. Get consent_required error

Relevant log output

No response

Relevant configuration

No response

Version

master

On which operating system are you observing this issue?

None

In which environment are you deploying?

None

Additional Context

No response

brandonkeymatt commented 10 months ago

I have been getting some problems that may be related to this issue. Steps to reproduce:

  1. Make a fresh ory project and enable login after registration.

  2. Run the react-spa ory example and follow the README in creating an oauth 2 client, enable skip consent on this client.

  3. Initialise the flow with the registration prompt and max-age as 3600:

    ory perform authorization-code \
         --client-id  66e1djcc-1d85-4e2e-acbe-d182e1a47b35 \
         --client-secret Q-9g8eUzaZ2N~aRzuaikJHE4hZ \
         --project c084c430-f68f-4374-b929-085e4b840db6 \
         --port 5555 \
         --scope openid,offline \
         --prompt registration \
         --max-age 3600 

This will redirect you to localhost:3000/registration with a flowId. Fetch this flow object and then look at its oauth2_login_request object. request_url will be the same as generated by ory perform but if you immediately redirect to this after registration you will just be redirected back to localhost:3000 (without completing the authorization code flow).

  1. If however you change the prompt from registration to none when you redirect, you will end up back at localhost:3000/signup with a flowId, that prompts you to enter your password again:
image
Benehiko commented 10 months ago

@brandonkeymatt What happens when you go through the login screen with the skip enabled on the client?

I have a PR open that fixes some of the behavior for the registration flow. Right now it seems the registration flow does not accept the login request when the skip flag is true. So it just redirects to the logout URL which takes you to the application base URL or /ui/welcome page if you are using the Account Experience. https://github.com/ory/kratos/pull/3592

brandonkeymatt commented 10 months ago

@Benehiko thanks for looking into this and pushing a PR 🙏

If you initialise the flow with prompt=none and max-age=3600 you cant get to the login screen with an oauth flow?

ory perform authorization-code \
         --client-id  66e1dccc-1d85-4e2e-acbe-d182e1a47b35 \
         --client-secret Q-9g8eUzaZ2N~aRzuaikJHE4hZ \
         --project c084c438-f68f-4374-b929-085e4b840db6 \
         --port 5555 \
         --scope openid,offline_access \
         --prompt none \
         --max-age 3600

You get the following error:

image

This is with persistent: false set in the project session config, as per this part of the docs for max-age?

Benehiko commented 10 months ago

Hi @brandonkeymatt,

So I think there are a couple of things to consider with OAuth flows depending on the scenario you want.

  1. For first party clients, you might not want to even show a consent page.
  2. Third party clients want to remember consent from a previous flow
  3. Previous OAuth flows should be forced to re-authenticate (login again)
  4. Previous OAuth flows should skip login if there was a previous successful OAuth flow

So I assume you want option 1 and 4. In this case, you cannot completely skip the login/registration flow with prompt=none since you do not have a session it seems - hence the error you received. prompt=none is only useful if the user already logged in and you have set your project to session.cookie.persistent: true. Creating a client with the skip: true would still redirect you to the Consent page, but it will automatically accept the consent and redirect the user back to the client.

Benehiko commented 10 months ago

I have also found the reason why users are left on the AX /welcome page when they have a session and they are in an OAuth flow with prompt=registration. This might also be the case for some of the examples.

We do a session check in a middleware and automatically redirect the user to the /welcome route or base root of the application before redirecting to the Ory Identity (Kratos) service. This means that in OAuth flows, we are intercepting the request in the UI before it is passed along and handled by the Ory Identity service.

See this PR https://github.com/ory/kratos-selfservice-ui-node/pull/304

brandonkeymatt commented 10 months ago

Ah nice thank you! I can see https://github.com/ory/kratos-selfservice-ui-node/pull/304 has been merged, do you guy have any idea when these changes will be released to production?

Benehiko commented 10 months ago

@brandonkeymatt

They are in production for a week now I believe. https://github.com/ory/kratos-selfservice-ui-node/releases/tag/v0.13.0-20

https://changelog.ory.sh/announcements/improved-oauth2-registration-flow