Closed tailnet-h-usky-io closed 8 months ago
I understand these conditions are not easy to reproduce, and don't expect anyone here to try. I'm just looking for debugging suggestions or other ideas!
You probably want to look at the logs for the ocis proxy
service first (ideally with log level "debug"). If you don't see the /api/v0/settings/values-list
request anywhere it that log, there is likely something wrong with you reserve proxy's setup (I fear I can't really help you with debugging that).
If you see anything about that values-list
request in the ocis proxy
service log, it should also give you hints about why it fails to authenticate the request. If possible, please attach the log here.
Thanks for your suggestion, @rhafer!
I found the log entries for two the denied requests in the logs for OwnCloud's proxy
service, just as you suggested:
It says failed to verify access token: token contains an invalid number of segments
2024-02-23T02:53:30Z DBG director found line=github.com/owncloud/ocis/v2/services/proxy/pkg/router/router.go:222 method=POST path=/api/v0/settings/values-list policy=ocis prefix=/api/v0/settings routeType=prefix service=proxy
2024-02-23T02:53:30Z ERR failed to authenticate the request error="failed to verify access token: token contains an invalid number of segments" authenticator=oidc line=github.com/owncloud/ocis/v2/services/proxy/pkg/middleware/oidc_auth.go:165 path=/api/v0/settings/values-list service=proxy
2024-02-23T02:53:30Z INF access-log bytes=0 duration=0.262592 line=github.com/owncloud/ocis/v2/services/proxy/pkg/middleware/accesslog.go:31 method=POST path=/api/v0/settings/values-list proto=HTTP/1.1 remote-addr=10.1.24.21 request-id=0e4f18d3-d270-4d12-85b1-d35cd5a31f90 service=proxy status=401
2024-02-23T02:53:30Z DBG director found line=github.com/owncloud/ocis/v2/services/proxy/pkg/router/router.go:222 method=GET path=/ocs/v1.php/cloud/user policy=ocis prefix=/ocs/ routeType=prefix service=proxy
2024-02-23T02:53:30Z ERR failed to authenticate the request error="failed to verify access token: token contains an invalid number of segments" authenticator=oidc line=github.com/owncloud/ocis/v2/services/proxy/pkg/middleware/oidc_auth.go:165 path=/ocs/v1.php/cloud/user service=proxy
2024-02-23T02:53:30Z INF access-log bytes=0 duration=0.164137 line=github.com/owncloud/ocis/v2/services/proxy/pkg/middleware/accesslog.go:31 method=GET path=/ocs/v1.php/cloud/user proto=HTTP/1.1 remote-addr=10.1.24.21 request-id=53d571c0-dbe5-4dac-a9da-c6f9709803af service=proxy status=401
If I right-click on the failed request in the JS Console and select Copy object
(Chrome/Macos), I get:
{
"message": "Request failed with status code 401",
"name": "AxiosError",
"stack": "AxiosError: Request failed with status code 401\n at pSe (https://oc.h.usky.io/js/chunks/vendor-163bae29.mjs:16:966)\n at XMLHttpRequest.f (https://oc.h.usky.io/js/chunks/vendor-163bae29.mjs:16:4125)",
"config": {
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
},
"adapter": [
"xhr",
"http"
],
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"env": {},
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json",
"Accept-Language": "en",
"Authorization": "Bearer 6afb5667-2a96-448c-a9e2-5ac6c40e538f",
"X-Requested-With": "XMLHttpRequest",
"X-Request-ID": "83f0f03b-9d40-423f-8f87-d0019359f409"
},
"baseURL": "https://oc.h.usky.io/",
"cancelToken": {
"promise": {},
"_listeners": []
},
"method": "post",
"url": "/api/v0/settings/values-list",
"data": "{\"account_uuid\":\"me\"}"
},
"code": "ERR_BAD_REQUEST",
"status": 401
}
Three questions arise immediately...
The code at middleware/oidc_auth.go:165
(from the proxy log) looks like it's trying to decode the OIDC claims from the auth token using the function getClaims(token, r)
– is that right?
When the proxy service says failed to verify access token: token contains an invalid number of segments
, is it referring to this value: Bearer 6afb5667-2a96-448c-a9e2-5ac6c40e538f
? Is there a way to check this value in some kind of token decoder?
Is the expected return value of the failing function getClaims(token, r)
somehow related to the OIDC claims that are already being returned from the (successful) request made immediately before the failing request (to the IDP's user-info
endpoint)? Do they contain similar / overlapping info? For reference, here's the corresponding response body from user-info
:
{
"sub": "d48378e5-4f53-406d-afe9-9d58234f66f2",
"updated_at": 1708658900,
"user_name": "test",
"jans_status": "active",
"name": "Test User",
"nickname": "testy",
"user_permission": [
"ocisUser"
],
"given_name": "Test",
"family_name": "User",
"email": "testuser@h.usky.io"
}
I tried to tweak the Janssen IDP server to match this JSON to the OwnCLoud's OIDC config:
oidc:
issuerURI: https://sso.h.usky.io
webClientID: [xxxxxxx]...
userIDClaim: sub
userIDClaimAttributeMapping: userid
accessTokenVerifyMethod: "jwt"
roleAssignment:
enabled: true
claim: user_permission
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
... so, I've tried to set the config so this test user has the claim ocisUser
, which should map to the OCIS role user
. Does that look correct?
Um..... try to decode the token value externally? Update to OCIS version 5 (looks like my container images are v4.0.1
)?
Again, thanks for your suggestion!
OK, after trying both my Next Steps, I determined that the Janssen OIDC provider server was sending something called a "Reference Token", not "value token" / JWT. Here's the relevant client config setting:
^^ set this to JWT for OwnCloud!
For future reference, here is the basic client setup in Janssen for OCIS:
^^ I added the permission
scope so that the user_permission
OIDC claim can be used to map the default Janssen admin user into the OCIS admin Role, but that's not really the correct way to apply custom claims when using Janssen LDAP, so I'll probably fiddle with this some more to setup my other users.
Anyway, once I fixed the token format and nailed down the LDAP settings, I can log in with the admin
user created by the Janssen Helm charts. Closing this issue.
Describe the bug
Hello, OCIS users.
I am attempting to integrate OwnCloud Infinite Scale (
v4.0.x
) with the [Janssen open-source IDP][1], and have gotten as far as completing the OpenID Connect token authorization + user info response. But then, OwnCloud tries to post some user data to itself and gets a401
, so login fails and I wind up at the path/access-denied
:Here are the specifics of the requests and responses:
username
,email
, andprofile
, I think?) for approval, as per usual. So far, so good...oidc-callback
), which then requests the Access Token. This succeeds...admin
account, more OIDC claims are returned than for this test user. Not sure why yet, or whether that's related, but if anyone knows what OCIS requires in order to login from this IDP response, I'd love to know...POST
request to itself, specifically to/api/v0/settings/values-list
with the following payload:{"account_uuid": "me"}
(huh?) . This request is denied (or blocked? - the browser shoes no actual bytes in the Response...) but I'm not sure why./ocs/v1.php/cloud/user
with typeapplication/x-www-form-urlencoded
is similarly blocked/denied.Initial clues
The main clues which I think I have so far are that:
Response Headers
in the screenshot above shows theServer
value ofrpxy
; andfrontend
service does log the token exchange)This makes me suspect that the
POST
tovalues-list
might be blocked by the [rpxy
proxy server][3] which I have set up in front of OwnCloud, and might not be reaching OCIS at all.Why the extra proxy, when OCIS already has a
proxy
Service? There are two reasons: to terminate TLS; and to acquire an overlay IP address.You see, what makes this setup a little unusual is that all the software services are running on an overlay ([Tailscale][2]) network, so nothing is reachable from the internet. Both OwnCloud and Janssen are deployed with Helm onto a microk8s setup, and Tailscale provides a custom [Kubernetes Operator][4] that attaches an overlay address to any existing K8s
Service
resource. The Tailscale K8s Operator can also create anIngress
resource with an overlay IP, but in that case the Operator uses the Tailscale-assigned DNS name and generates a TLS certificate on-the-fly. I prefer to use my own internal, private sub-domain with my own DNS servers and a purchased wildcard cert.So, the inbound traffic for OwnCloud first arrives at the
rpxy
proxyService
's Tailscale-assigned IP, where it's forwarded to therpxy
container.rpxy
then terminates HTTPs and forwards the request to the K8s-assigned Service IP for OwnCloud'sproxy
Service
(via its CoreDNS-assigned DNS name). Here's therpxy
config:^^ note that
proxy.ocis.svc.cluster.local
is the name CoreDNS assigns to OwnCloud'sproxy
service when deployed via Helm charts.This traffic flow seems to work fine, until the request from the OIDC redirect page to
/api/v0/settings/values-list
- at which point it fails, perhaps blocked byrpxy
(?). This is puzzling, since the blocked requests are not cross-domain - they're fromhttps://oc.h.usky.io
tohttps://oc.h.usky.io
, so I don't see that CORS rules should apply here.Steps to reproduce
externalDomain: oc.[some domain]
features: basicAuthentication: false demoUsers: false
externalUserManagement: enabled: true adminUUID: "xxxxxxxxxxxxxxxxxxxxx" oidc: issuerURI: https://sso.[some domain] webClientID: [OIDC client ID] userIDClaim: inum userIDClaimAttributeMapping: userid