SSO next version

Ideas and fully working prototytpe of an SSO update. The required spec changes are numbered and indicated in bold.

discover authentication

The plan is to use www-authenticate headers so we can use existing challenges and ivoa challenges (that convey more info). The basic form, as defined by RFC7235, is

   www-authenticate: {auth-scheme} {scheme-specific-params}
An implemented example:
   curl --head https://ws.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/argus/capabilities
   HTTP/1.1 200
   www-authenticate: ivoa_bearer standard_id="ivo://ivoa.net/sso#tls-with-password", access_url="https://ws-cadc.canfar.net/ac/login"
   www-authenticate: ivoa_bearer standard_id="ivo://ivoa.net/sso#OpenID", access_url="https://ws-cadc.canfar.net/ac"
   www-authenticate: Bearer
   www-authenticate: ivoa_x509 standard_id="ivo://ivoa.net/sso#BasicAA", access_url="https://ws.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/cred/auth/priv"
   www-authenticate: ivoa_x509

Each www-authenticate challenge tells the client about different methods that can be used to authenticate. I'll try to explain each:

  • "www-authenticate: Bearer" is the standard Oauth2 challenge; it means you can authenticate with a (bearer) token (but you have to know out-of-band how to get one).
  • "www-authenticate: ivoa_bearer" means the same thing, except that since we will define the ivoa_bearer scheme we can add params to convey extra info: how to get that bearer token. There are two methods for getting a token described above. The first is a normal http form POST (standard_id="ivo://ivoa.net/sso#tls-with-password") and the second is the standard OpenID mechanism; clients can chose whichever one they understand.
  • "www-authenticate: ivoa_x509" is an indication that you can authenticate with an X509 client certificate (including self-signed proxy certificates as described in SSO-1.0). There are two variants above: one with optional extra params and one without. The one with params tells the client they can get an acceptable client cert via the described mechanism (for sites that provide their own cert certificate authority) and the second, without params, says that the service accepts client certificates from external CAs. Since CADC provides internally generated client certs and accepts externally signed client certs, we include both headers. NOTE: the use of #BasicAA in the CADC ivoa_x509 challenge: that endpoint already exists and that's how it is currently implemented so this simply describes what CADC does right now. It does not mean everyone has to use BasicAA for that feature and we'll likely augment that service to support #tls-with-password as soon as possible.
  • "www-authenticate: ivoa_cookie"? Although CADC/CANFAR does not have a readily usable cookie issuing endpoint, we have also considered/designed an ivoa_cookie challenge that works as above but gives the client a cookie instead of a bearer token or cert. It would work more or less the same way.

So far, the additions/modifications to standards required are as follows:

1. VOSI augmented to require http HEAD support for /capabilities endpoints
2. SSO augmented to define ivoa_bearer, ivoa_cookie, and ivoa_x509 challenges
3. SSO ivo://ivoa.net/sso#tls-with-password extended to specify the form params

In all the above cases, once you have a (bearer) token, you use it with a standard http header: "Authorization: Bearer {token}". If you got a cookie, you would use it with the standard "Cookie: {cookie}".

login: acquiring a token (or cookie or certificate)

For standard_id="ivo://ivoa.net/sso#tls-with-password", the form params are simply "username" and "password" and can be used like this:

   curl -v -d 'username=????&password=????' https://ws-cadc.canfar.net/ac/login
   < x-vo-authenticated: pdowler
   < x-vo-bearer: {token}
   {token}

We currently return the token in both the "x-vo-bearer" header and the body to show that either work and allow client writers to see which is preferred. The #tls-with-password standard defines the input (form params) and the challenge (ivoa_bearer) defines the output.

For an ivoa_cookie challenge, the response would be a normal "set-cookie: {cookie}" header.

For an ivoa_x509 challenge, output pretty much needs to be in the body because pem encoded certs span multiple lines - intended to be a file format - and I think we will cause pain if we make up a way to return them in a header. Parsers tend to open and read (an InputStream in java) and that works fine with body; there is code in OpenCADC to do this that has been working for years :-)

Additional standards modifications:

4. SSO challenges describe/specify response form of the login endpoint (access_url), possibly including an "x-vo-bearer" response header.

using: perform authenticated service calls

Using the authentication information is scheme-specific; for bearer tokens it would look like:

   curl --head -H 'authorization: bearer {token}' https://ws.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/argus/capabilities
   HTTP/1.1 200
   x-vo-authenticated: pdowler
At a minimum, the same "authorization" header can be used with any other endpoint in the service. Neither "authorization" or "bearer" are case sensitive.

A new response header "x-vo-authenticated", giving the authenticated user identity, should be included in all responses for which authentication has succeeded. This enables clients to tell that they are using a service in an authenticated way, which might not be possible otherwise e.g. for a service with optional authentication.

5. SSO requires/recommends authenticated services to include "x-vo-authenticated" header in all authenticated responses

scope

We discussed how a client would know the scope of a token: which other services at that site can it also use the token to access?

For CADC/CANFAR, the same token can be used with all services across both the cadc-ccda.hia-iha.nrc-cnrc.gc.ca and canfar.net domains, but we do not really know how to convey that... our multiple domain setup is probably only one complicating use case so it would be good to find out what complications other providers have before thinking too much about this. It is an optimisation to re-use tokens more widely. It may or may not simplify client usage. I think Mark considered that topcat could re-use a token with other services that advertised the same login access_url, but that's not safe because a rogue service could advertise someone else's login access_url and trick the client into re-using tokens. So we do need to figure out something to get past the default of "token for service X only". TBD

Cookie scope would have to be "the domain of the login service" to be consistent with normal http usage.

Client certificate scope would be safe if the client considered all certs as globally usable; the cert would fail in all the ways it can already if that's not true (eg. unknown CA if you try to use a CADC cert at some other site) but it wouldn't be insecure per se since the client only sends the public part when authenticating. It would just be annoying to fail with really poor error messages. It would help clients to know that a cert-issuer is "local" or not (eg the CADC endpoint above is "local" to CADC/CANFAR since the CA cert is internal, so we could in principle add something to tell clients that we don't distribute our CA cert) or "local" could be the default interpretation for that scenario. Maybe not worth worrying about now/ever. TBD.

bootstrap and no-auth vs optional auth vs required auth

Finally, how does a client start and how does a service signal that there is no/optional/required authentication? First, it must be noted that the above www-authenticate challenges can be returned in any response, but typically in 200, 401, or 403. And it must be emphasized that any endpoint can respond with those challenges if something changes (token expires, attempt to access a protected resource, etc).

For the bootstrap, we have implemented this in all /capabilities endpoints (both HEAD and GET) and clients can use an anon http HEAD request to /capabilities as the lightweight method to see what authentication looks like:

  • 200 with no www-authenticate headers: anon
  • 200 with www-authenticate headers: authentication optional
  • 401 with www-authenticate headers: authentication required
Clients can also check current credentials with http HEAD to /capabilities and then look for "x-vo-authenticated" in the response (see above). Since we are essentially replacing use of securityMethod inside capabilities documents with http headers, I don't see any problem with this final spec change:

6. Modify VOSI to allow /capabilities to respond with 401 (or 403) (also affects TAP 1.1 sec 2; & others?)

Since the purview of VOSI-capabilities is to describe service functionalities, I don't see any need to add another endpoint when this one can serve the purpose and is already "mandatory".

Topic revision: r2 - 2022-01-06 - MarkTaylor
 
This site is powered by the TWiki collaboration platformCopyright © 2008-2022 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback