Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Account provisioning fails with external OIDC provider if id_token does not contain preferred_username claim. #2644

Closed
coucoulala opened this issue Oct 19, 2021 · 10 comments · Fixed by #2832
Assignees
Labels

Comments

@coucoulala
Copy link

coucoulala commented Oct 19, 2021

Describe the bug

Account provisioning fails when setting PROXY_AUTOPROVISION_ACCOUNTS to true, PROXY_USER_OIDC_CLAIM to email and the external OIDC provider does not support preferred_username.

Steps to reproduce

Steps to reproduce the behavior:

  1. Follow login flow with external OIDC provider which does not support preferred_username.
  2. id_token and /userinfo endpoint of external OIDC are valid.
  3. Account creation fails.

Expected behavior

According to the OIDC specifications the preferred_username claim in an OIDC JWT is the following:

Shorthand name by which the End-User wishes to be referred to at the RP, such as janedoe or j.doe. This value MAY be any valid JSON string including special characters such as @, /, or whitespace. The RP MUST NOT rely upon this value being unique, as discussed in Section 2.5.3.

As far as I understand it, preferred_username is not strictly necessary. In case it is used for a human-readable username, perhaps a fallback to the email claim could be used.

Actual behavior

Account creation fails.

Setup

I've set up the server using the following docker-compose.yml

---
version: "3.7"

services:
  ocis:
    image: "owncloud/ocis:1.13"
    container_name: "ocis"
    entrypoint:
     - /bin/sh
     - /entrypoint-override.sh
    ports:
     - "9200:9200"
    environment:
      # PROXY
      PROXY_AUTOPROVISION_ACCOUNTS: "true"
      PROXY_OIDC_ISSUER: https://auth.example.org
      PROXY_OIDC_INSECURE: "false"
      PROXY_TLS: "false"
      PROXY_USER_OIDC_CLAIM: "email"
      # WEB
      WEB_OIDC_METADATA_URL: https://auth.example.org
      WEB_OIDC_AUTHORITY: https://auth.example.org
      WEB_OIDC_CLIENT_ID: ocis
      WEB_OIDC_SCOPE: "openid profile email"
      # Storage
      STORAGE_OIDC_ISSUER: https://auth.example.org
      STORAGE_LDAP_IDP: https://auth.example.org
      # CIS
      OCIS_URL: https://ocis.example.org
      OCIS_LOG_LEVEL: info
      # Secrets
      #IDP_LDAP_BIND_PASSWORD: [redacted]
      STORAGE_LDAP_BIND_PASSWORD: [redacted]
      OCIS_JWT_SECRET: [redacted]
      OCIS_TRANSFER_SECRET: [redacted]
    restart: always
    user: 1000:1000
    volumes:
      - ./config/ocis/entrypoint-override.sh:/entrypoint-override.sh
      - ./ocis-data:/var/tmp/ocis
Logs: ``` {"level":"warn","service":"storage","pkg":"rhttp","host":"127.0.0.1","method":"GET","uri":"/data/index.cs3/unique.github.com.owncloud.ocis.accounts.pkg.proto.v0.Account.Mail/mail@example.org","url":"/data/index.cs3/unique.github.com.owncloud.ocis.accounts.pkg.proto.v0.Account.Mail/mail@example.org","proto":"HTTP/1.1","status":404,"size":0,"start":"19/Oct/2021:11:49:24 +0000","end":"19/Oct/2021:11:49:24 +0000","time_ns":629028,"time":"2021-10-19T11:49:24Z","message":"http"} {"level":"error","service":"proxy","query":"mail eq 'mail@example.org'","time":"2021-10-19T11:49:24Z","message":"account not found"}{"level":"warn","service":"proxy","time":"2021-10-19T11:49:24Z","message":"Missing preferred_username claim"} {"level":"error","service":"proxy","error":"{\"id\":\"com.owncloud.api.accounts\",\"code\":400,\"detail\":\"preferred_name '' must be at least the local part of an email\",\"status\":\"Bad Request\"}","time":"2021-10-19T11:49:24Z","message":"Could not get user by claim"} ```
OCIS_VERSION=vX.X.X
BRANCH=vX.X.X
STORAGE_FRONTEND_UPLOAD_DISABLE_TUS=false

Additional context

Add any other context about the problem here.

@wkloucek
Copy link
Contributor

Thanks for raising this issue.

I could reproduce this by deleting the preferred_username claim in Keycloak in our oCIS with Keycloak deployment example.

I get an error on the first login / auto provisioning of a user, coming from here:

func validateAccountPreferredName(serviceID string, a *proto.Account) error {
if !isValidUsername(a.PreferredName) {
return merrors.BadRequest(serviceID, "preferred_name '%s' must be at least the local part of an email", a.PreferredName)
}
return nil
}

Which is called on the CreateAccount in the accounts service:

if err = validateAccount(s.id, out); err != nil {
return err
}

I didn't get a clear understanding from the OIDC spec, if the standard claims are expected to be fully implemented or if they are only reserved... "preferred_username" also doesn't seem too important and a fallback to mail could be considered. @rhafer What's your opinion on this?

@coucoulala Just out of interest, what IDP do you use?

@coucoulala
Copy link
Author

coucoulala commented Oct 20, 2021

Thank you for your reply, I'm using Authelia. I saw #2445, but for me the authentication flow is working as expected until this issue, see also the discussion starting from authelia/authelia#2329 (comment).

@rhafer
Copy link
Contributor

rhafer commented Oct 20, 2021

I didn't get a clear understanding from the OIDC spec, if the standard claims are expected to be fully implemented or if they are only reserved...

As far as I understand the spec there is no requirement to have them actually implemented.

"preferred_username" also doesn't seem too important and a fallback to mail could be considered. @rhafer What's your opinion on this?

Yeah. Ideally we'd just make PreferedName an optional attribute in the accounts service. Though I guess what will require changes elsewhere (glauth at least). Just duplicating the mail and add it as PreferedName seems possible as well, but doesn't seem like a nice solution.

@james-d-elliott
Copy link

I'd be inclined to add a configuration option to define which claim has the value you're expecting if it were me. While we will probably add this upstream in Authelia at some stage I would argue generally if the id token already has the value you want, it makes sense to leverage that rather than having to get each individual OP resolved.

I'd also note there are a few other IDP's that do not include this, Auth0 being one, which is part of the reason for this suggestion.

@georglauterbach
Copy link

Any progress here?

@c-nv-s
Copy link

c-nv-s commented Nov 29, 2021

I'm also keen on getting this working
@coucoulala having tried your docker-compose settings and replacing the values with the URLs of my authelia instance, the container isn't even managing to redirect to authelia.
can anyone paste a minimum config to reproduce with authelia?

@rhafer rhafer self-assigned this Nov 30, 2021
rhafer added a commit to rhafer/ocis that referenced this issue Nov 30, 2021
… claim

Some IDPs (e.g. Authelia) don't add the "preferred_username" claim.
Fallback to the "email" claim in that case.

Fixes: owncloud#2644
@rhafer
Copy link
Contributor

rhafer commented Nov 30, 2021

I've created a small patch to fallback to "email" when "preferred_username" is not available as a quick workaround. I only did this quick workaround here as this area of the code is likely to change quite a bit in the near future an we'll need to rework it anyway.
Will open an issue for making the required claims and mappings configurable.

rhafer added a commit to rhafer/ocis that referenced this issue Nov 30, 2021
… claim

Some IDPs (e.g. Authelia) don't add the "preferred_username" claim.
Fallback to the "email" claim in that case.

Fixes: owncloud#2644
@coucoulala
Copy link
Author

Great, works as expected! 👍

@c-nv-s
Copy link

c-nv-s commented Dec 17, 2021

@coucoulala I don't suppose you could confirm it that example docker-compose file you provided is actually still functioning?
I've been struggling to get ocis to even display the login, let alone redirect to the authelia login screen.
are you doing anything special in your entrypoint-override.sh ? because I have erased those lines and still no luck.
I'm also curious how the STORAGE_LDAP* are using authelia? can those settings usefully be omitted too?

@helgeklein
Copy link

For anyone stumbling upon this: I published a full and detailed description of how to set up and configure ownCloud Infinite Scale (oCIS) OpenID Connect authentication to Authelia on my blog:

https://helgeklein.com/blog/owncloud-infinite-scale-with-openid-connect-authentication-for-home-networks/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants