Authenticating into OCIS using CAS (v6) and Active Directory

I’m currently looking at migrating our existing OwnCloud deployment to OCIS (deployed on kubernetes provided by k3s), and having some difficulty getting the authentication/login working. We use Active Directory as the LDAP backend, and use Apereo CAS as the OIDC provider. I believe I’ve correctly configured everything, but I still get the error:

Not logged in
This could be because of a routine safety log out, or because your account is either inactive or not yet authorized for use. Please try logging in after a while or seek help from your Administrator.

It’s not clear to me why this is happening, can anyone give any suggestions?

I can’t seem to post or upload the values file, so here’s the subsection on oidc and ldap:

  # External user management
  externalUserManagement:
    # -- Enables external user management (and disables internal user management).
    # Needs an external OpenID Connect Identity Provider and an external LDAP server.
    enabled: true
    # -- UUID of the inital admin user.
    # If the given value matches a user's value from `features.externalUserManagement.oidc.userIDClaim`, the admin role will be assigned.
    # Consider that the UUID can be encoded in some LDAP deployment configurations like in .ldif files. These need to be decoded beforehand.
    # Note: Enabling `roleAssignment` will disable `adminUUID`.
    # This is James' Prod User
    adminUUID: "b091cb4fe8c78449bdd9ba973d7e6af2"
    # OpenID Connect Identity provider related settings.
    oidc:
      # -- Issuer URI of the OpenID Connect Identity Provider.
      # If the IDP doesn't have valid / trusted SSL certificates, certificate validation can be disabled with the `insecure.oidcIdpInsecure` option.
      issuerURI: https://auth-mfa.datacentral.org.au/cas/oidc
      # -- Link to the OIDC provider's user accessible session management. This will be shown to the user on the personal account page.
      # When using Keycloak with the a realm named "ocis" this could point to eg. https://keycloak.owncloud.test/realms/ocis/account/
      sessionManagementLink: https://accounts.datacentral.org.au
      # -- Link to the OIDC provider's user accessible account editing page. This will be shown to the user on the personal account page.
      # When using Keycloak with the a realm named "ocis" this could point to eg. https://keycloak.owncloud.test/realms/ocis/account/
      editAccountLink: https://accounts.datacentral.org.au
      # -- Specify the client ID which the web frontend will use
      webClientID: ofpuU9v7nPHY0ENpdEWZBndUVqtDbcJuNiYH
      # -- Claim to take an unique user identifier from. It will be used to look up the user on the LDAP server.
      userIDClaim: sub
      # -- Attribute mapping of for the userIDClaim.
      # Set to `userid` if the claim specified in `...oidc.userIDClaim` holds the value of the ldap user attribute specified in `...ldap.user.schema.id`.
      # Set to `mail` if the claim specified in `...oidc.userIDClaim` holds the value of the ldap user attribute specified in  `...ldap.user.schema.mail`.
      # Set to `username` if the claim specified in `...oidc.userIDClaim` holds the value of the ldap user attribute specified in `...ldap.user.schema.userName`.
      userIDClaimAttributeMapping: username

      # -- OIDC Acces Token Verify Method
      # Set to "jwt" or "none"
      accessTokenVerifyMethod: "none"

      # -- Configure OIDC role assignment. If activated, oCIS will read the role assigment from the OIDC token, see
      # xref:{s-path}/proxy.adoc#automatic-role-assignments[Automatic Role Assignments]
      roleAssignment:
        enabled: false
        # -- The name of the OIDC claim holding the role assignment
        claim: roles
        # -- Configure the mapping for the role assignment
        mapping:
          - role_name: admin
            claim_value: ocisAdmin
          - role_name: spaceadmin
            claim_value: ocisSpaceAdmin
          - role_name: user
            claim_value: ocisUser
          - role_name: guest
            claim_value: ocisGuest
    # LDAP related settings.
    ldap:
      # -- Writeable configures if oCIS is allowed to write to the LDAP server, to eg. create or edit users.
      writeable: false
      # -- If the LDAP server is set to writable in general, some user attributes can be restricted to read only in the UI.
      # Note: This only disables editing in the UI. The readonly permissions need to be enforced in the LDAP server itself.
      readOnlyAttributes:
        []
        # - user.onPremisesSamAccountName # username
        # - user.displayName # display name
        # - user.mail # mail
        # - user.passwordProfile # password
        # - user.appRoleAssignments # role
        # - user.accountEnabled # login allowed
        # - drive.quota # quota
      # -- URI to connect to the LDAP secure server.
      uri: ldap://10.80.11.2:3268
      # -- Set only to false, if the certificate of your LDAP secure service is not trusted.
      # If set to false, you need to put the CA cert of the LDAP secure server into the secret referenced by "ldapCaRef"
      certTrusted: true
      # -- Disables SSL certificate checking for connections to the LDAP server.
      # -- For self signed certificates, consider to put the CA cert of the LDAP secure server into the secret referenced by "ldapCaRef"
      # Not recommended for production installations.
      insecure: true
      # -- DN of the user to use to bind to the LDAP server.
      # The password for the user needs to be set in the secret referenced by `secretRefs.ldapSecretRef` as `reva-ldap-bind-password`.
      # The user needs to have permission to list users and groups.
      bindDN: cn=adc_connect,dc=asvo,dc=aao,dc=gov,dc=au
      # -- Signals that the LDAP server has the refint plugin enabled, which makes some actions not needed.
      refintEnabled: false
      # -- Use the Password Modify Extended Operation for updating user passwords.
      passwordModifyExOpEnabled: false
      # -- If set to true, rely on the LDAP Server to generate a unique ID for users and groups, like when using 'entryUUID' as the user ID attribute.
      useServerUUID: true
      user:
        schema:
          # -- LDAP Attribute to use as the unique id for users. This should be a stable globally unique id like a UUID.
          id: objectGUID
          # -- Set this to true if the defined `id` attribute for users is of the `OCTETSTRING` syntax. This is e.g. required when using the `objectGUID` attribute of Active Directory for the user ID`s.
          idIsOctetString: true
          # -- LDAP Attribute to use for the email address of users.
          mail: mail
          # -- LDAP Attribute to use for the displayname of users.
          displayName: displayname
          # -- LDAP Attribute to use for username of users.
          userName:  sAMAccountName
          # -- LDAP Attribute to distinguish between 'Member' and 'Guest' users. Default is 'ownCloudUserType'.
          userType: ownCloudUserType
        # -- Search base DN for looking up LDAP users.
        baseDN: ou=Standard,ou=Accounts,dc=asvo,dc=aao,dc=gov,dc=au
        # -- LDAP search scope to use when looking up users. Supported values are `base`, `one` and `sub`.
        scope: sub
        # -- Type of substring search filter to use for substring searches for users. Possible values: `initial` for doing prefix only searches, `final` for doing suffix only searches or `any` for doing full substring searches
        substringFilterType: any
        # -- LDAP filter to add to the default filters for user search like `(objectclass=ownCloud)`.
        filter:
        # -- The object class to use for users in the default user search filter like `inetOrgPerson`.
        objectClass: user
      group:
        schema:
          # -- LDAP Attribute to use as the unique ID for groups. This should be a stable globally unique ID like a UUID.
          id: objectGUID
          # -- Set this to true if the defined `id` attribute for groups is of the `OCTETSTRING` syntax. This is e.g. required when using the `objectGUID` attribute of Active Directory for the group ID`s.
          idIsOctetString: true
          # -- LDAP Attribute to use for the email address of groups (can be empty).
          mail: mail
          # -- LDAP Attribute to use for the displayname of groups (often the same as groupname attribute).
          displayName: cn
          # -- LDAP Attribute to use for the name of groups.
          groupName: cn
          # -- LDAP Attribute that is used for group members.
          member: member
        # -- Search base DN for looking up LDAP groups.
        baseDN: ou=Groups,ou=Accounts,dc=asvo,dc=aao,dc=gov,dc=au
        # -- BaseDN where new groups are created and are considered as editable.
        # All existing groups with a DN outside the `features.externalUserManagement.ldap.group.createBaseDN` will be treated as read-only groups.
        # Defaults to the value `features.externalUserManagement.ldap.group.baseDN`.
        # Only applicable if `features.externalUserManagement.ldap.writeable` is set to `true`
        createBaseDN: ""
        # -- LDAP search scope to use when looking up groups. Supported values are `base`, `one` and `sub`.
        scope: sub
        # -- LDAP filter to add to the default filters for group searches.
        filter:
        # -- The object class to use for groups in the default group search filter like `groupOfNames`.
        objectClass: group
      # -- When using external user management, users can be set as disabled by either belonging to a group or using an ldap attribute.
      disableUsers:
        # -- Enables disabling users if configured as "attribute" or "group"
        disableMechanism: none
        # -- Attribute to use for disabling users.
        userEnabledAttribute: ownCloudUserEnabled
        # -- Group that a user can be added to and by that being marked as disabled.
        disabledUsersGroupDN: "cn=DisabledUsersGroup,ou=groups,o=libregraph-idm"

Did you configure Apereo CAS to send the username / samaccountname as the sub? All OpenID Connect providers I ran into send their own identifier as sub. Try adding a custom claim with the samaccountname, email or the objectguid.

The proxy and users services should log an error why the request could not be authenticated. If not, increase log level to debug and paste anything suspicious!

Sorry, been away for two weeks, I can confirm that sub is the username. It looks like the issue is the format of the user to bind to AD, based on the following logs:

2023-11-16T11:26:38.112586312+11:00 2023-11-16T00:26:38Z DBG GetUserByClaim claim=username line=github.com/cs3org/reva/v2@v2.16.1/pkg/user/manager/ldap/ldap.go:137 pkg=rgrpc service=users traceid=00000000000000000000000000000000 value=jtocknell
2023-11-16T11:26:38.112673902+11:00 2023-11-16T00:26:38Z DBG LDAP Search backend=ldap basedn=ou=Standard,ou=Accounts,dc=asvo,dc=aao,dc=gov,dc=au filter=(&(objectclass=user)(sAMAccountName=jtocknell)) line=github.com/cs3org/reva/v2@v2.16.1/pkg/utils/ldap/identity.go:217 pkg=rgrpc scope=2 service=users traceid=00000000000000000000000000000000
2023-11-16T11:26:38.150416548+11:00 2023-11-16T00:26:38Z DBG Error looking up user by filter error="LDAP Result Code 49 \"Invalid Credentials\": 80090308: LdapErr: DSID-0C09042F, comment: AcceptSecurityContext error, data 52e, v2580\x00" backend=ldap line=github.com/cs3org/reva/v2@v2.16.1/pkg/utils/ldap/identity.go:220 pkg=rgrpc service=users traceid=00000000000000000000000000000000 userfilter=(&(objectclass=user)(sAMAccountName=jtocknell))
2023-11-16T11:26:38.150451588+11:00 2023-11-16T00:26:38Z DBG GetUserByClaim error="error: not found: " line=github.com/cs3org/reva/v2@v2.16.1/pkg/user/manager/ldap/ldap.go:140 pkg=rgrpc service=users traceid=00000000000000000000000000000000

I’m using cn=adc_connect,dc=asvo,dc=aao,dc=gov,dc=au as the bindDN, and I can confirm the password for that user is correct in the secret used to store said password.