Commit Graph

284 Commits

Author SHA1 Message Date
Ryan Richard
95093ab0af Use kube storage for the supervisor callback endpoint's fosite sessions 2020-12-02 17:40:01 -08:00
Margo Crawford
1dd7c82af6 Added id token verification 2020-12-02 16:55:48 -08:00
Matt Moyer
fde56164cd
Add a redirectURI parameter to ExchangeAuthcodeAndValidateTokens() method.
We missed this in the original interface specification, but the `grant_type=authorization_code` requires it, per RFC6749 (https://tools.ietf.org/html/rfc6749#section-4.1.3).

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2020-12-02 15:55:33 -06:00
Matt Moyer
c23c54f500
Add an explicit Path=/; to our CSRF cookie, per the spec.
> [...] a cookie named "__Host-cookie1" MUST contain a "Path" attribute with a value of "/".

https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.2

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2020-12-02 15:55:33 -06:00
Margo Crawford
9419b7392d
WIP: start to validate ID token returned from token endpoint
This won't compile, but we are passing this between two teammates.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-12-02 16:26:47 -05:00
Andrew Keesler
09e6c86c46
token_handler.go: complete some TODOs and strengthen double auth code test
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-12-02 15:33:57 -05:00
Andrew Keesler
8e4c85d816
WIP: get linting and unit tests passing after token endpoint first draft
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-12-02 11:16:02 -05:00
Andrew Keesler
970be58847
token_handler.go: first draft of token handler, with a bunch of TODOs
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-12-02 11:14:45 -05:00
Margo Crawford
d60c184424 Add pkce and openidconnect storage
- Also refactor authorizationcode_test

Signed-off-by: Ryan Richard <rrichard@vmware.com>
2020-12-01 17:18:32 -08:00
Ryan Richard
f38c150f6a Finished tests for pkce storage and added it to kubestorage
- Also fixed some lint errors with v1.33.0 of the linter

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2020-12-01 14:53:22 -08:00
Margo Crawford
c8eaa3f383 WIP towards using k8s fosite storage in the supervisor's callback endpoint
- Note that this WIP commit includes a failing unit test, which will
  be addressed in the next commit

Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-12-01 11:01:42 -08:00
Matt Moyer
25ee99f93a
Add ValidateToken method to UpstreamOIDCIdentityProviderI interface.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2020-11-30 17:37:14 -06:00
Matt Moyer
d32583dd7f
Move OIDC Token structs into a new oidctypes package.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2020-11-30 17:02:03 -06:00
Matt Moyer
d64acbb5a9
Add upstreamoidc.ProviderConfig type implementing provider.UpstreamOIDCIdentityProviderI.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2020-11-30 15:22:56 -06:00
Ryan Richard
e6b6c0e3ab Merge branch 'main' into callback-endpoint 2020-11-20 15:50:26 -08:00
Ryan Richard
ccddeb4cda Merge branch 'main' into callback-endpoint 2020-11-20 15:13:25 -08:00
Monis Khan
d39cc08b66
Set defaults for fosite config
Signed-off-by: Monis Khan <mok@vmware.com>
2020-11-20 17:18:52 -05:00
Ryan Richard
c4ff1ca304 auth_handler.go: Ignore invalid CSRF cookies rather than return error
Generate a new cookie for the user and move on as if they had not sent
a bad cookie. Hopefully this will make the user experience better if,
for example, the server rotated cookie signing keys and then a user
submitted a very old cookie.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-20 13:56:35 -08:00
Andrew Keesler
b21f0035d7 callback_handler.go: Get upstream name from state instead of path
Also use ConstantTimeCompare() to compare CSRF tokens to prevent
leaking any information in how quickly we reject bad tokens.

Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-20 13:33:08 -08:00
Ryan Richard
72321fc106
Use /callback (without IDP name) path for callback endpoint (part 1)
This is much nicer UX for an administrator installing a UpstreamOIDCProvider
CRD. They don't have to guess as hard at what the callback endpoint path should
be for their UpstreamOIDCProvider.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-20 16:14:45 -05:00
Andrew Keesler
541019eb98
callback_handler.go: simplify stored ID token claims
Fosite is gonna set these fields for us.

Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-20 15:36:51 -05:00
Andrew Keesler
488d1b663a
internal/oidc/provider/manager: route to callback endpoint
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-20 10:44:56 -05:00
Andrew Keesler
8f5d1709a1
callback_handler.go: assert behavior about PKCE and IDSession storage
Also aggresively refactor for readability:
- Make helper validations functions for each type of storage
- Try to label symbols based on their downstream/upstream use and group them
  accordingly

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-20 09:41:49 -05:00
Andrew Keesler
f8d76066c5
callback_handler.go: assert nonce is stored correctly
I think we want to do this here since we are storing all of the
other ID token claims?

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-20 08:38:23 -05:00
Andrew Keesler
b25696a1fb callback_handler.go: Prepend iss to sub when making default username
- Also handle several more error cases
- Move RequireTimeInDelta to shared testutils package so other tests
  can also use it
- Move all of the oidc test helpers into a new oidc/oidctestutils
  package to break a circular import dependency. The shared testutil
  package can't depend on any of our other packages or else we
  end up with circular dependencies.
- Lots more assertions about what was stored at the end of the
  request to build confidence that we are going to pass all of the
  right settings over to the token endpoint through the storage, and
  also to avoid accidental regressions in that area in the future

Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-19 17:57:07 -08:00
Andrew Keesler
b49d37ca54
callback_handler.go: test invalid upstream ID token username/groups
Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-19 15:53:21 -05:00
Ryan Richard
83101eefce
callback_handler.go: start to test upstream token corner cases
Also refactor to get rid of duplicate test structs.

Also also don't default groups ID token claim because there is no standard one.

Also also also add some logging that will hopefully help us in debugging in the
future.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-19 14:19:01 -05:00
Ryan Richard
a47617cad0 callback_handler.go: Add JWT Audience claim to storage 2020-11-19 08:53:53 -08:00
Ryan Richard
ee84f31f42 callback_handler.go: Add JWT Issuer claim to storage 2020-11-19 08:35:23 -08:00
Andrew Keesler
ace861f722
callback_handler.go: get some thoughts down about default upstream claims
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-19 11:08:21 -05:00
Andrew Keesler
2e62be3ebb
callback_handler.go: assert correct args are passed to token exchange
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-19 10:20:46 -05:00
Andrew Keesler
48e0250649
callback_handler.go: test that we request openid scope correctly
Also add some testing.T.Log() calls to make debugging handler test failures
easier.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-19 09:28:56 -05:00
Andrew Keesler
6c72507bca
callback_handler.go: add test for failed upstream exchange/validation
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-19 09:00:41 -05:00
Andrew Keesler
63b8c6e4b2
callback_handler.go: test when state missing a needed param
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-19 08:51:23 -05:00
Andrew Keesler
ffdb7fa795
callback_handler.go: add a test for invalid state auth params
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-19 08:41:44 -05:00
Ryan Richard
652ea6bd2a Start using fosite in the Supervisor's callback handler 2020-11-18 17:15:01 -08:00
Ryan Richard
227fbd63aa Use an interface instead of a concrete type for UpstreamOIDCIdentityProvider
Because we want it to implement an AuthcodeExchanger interface and
do it in a way that will be more unit test-friendly than the underlying
library that we intend to use inside its implementation.
2020-11-18 13:38:13 -08:00
Matt Moyer
e0a9bef6ce
Move ./internal/oidcclient to ./pkg/oidcclient.
This will allow it to be imported by Go code outside of our repository, which was something we have planned for since this code was written.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2020-11-17 14:53:32 -06:00
Andrew Keesler
1c7601a2b5
callback_handler.go: start happy path test with redirect
Next steps: fosite storage?

Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-16 17:07:34 -05:00
Ryan Richard
052cdc40dc
callback_handler.go: add CSRF and version state validations
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-16 14:41:00 -05:00
Andrew Keesler
4138c9244f
callback_handler.go: write 2 invalid cookie tests
Also common-ize some more constants shared between the auth and callback
endpoints.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-16 11:47:49 -05:00
Andrew Keesler
3ef1171667 Tiny bit more code for Supervisor's callback_handler.go
Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-13 15:59:51 -08:00
Andrew Keesler
81b9a48437
callback_handler.go: initial API/test shape with 1 test
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-13 12:32:35 -05:00
Andrew Keesler
080bb594b2 Supervisor authorize endpoint reuses existing CSRF cookies and signs new ones
- To better support having multiple downstream providers configured,
  the authorize endpoint will share a CSRF cookie between all
  downstream providers' authorize endpoints. The first time a
  user's browser hits the authorize endpoint of any downstream
  provider, that endpoint will set the cookie. Then if the user
  starts an authorize flow with that same downstream provider or with
  any other downstream provider which shares the same domain name
  (i.e. differentiated by issuer path), then the same cookie will be
  submitted and respected.
- Just in case we are sharing the domain name with some other app,
  we sign the value of any new CSRF cookie and check the signature
  when we receive the cookie. This wasn't strictly necessary since
  we probably won't share a domain name with other apps, but it
  wasn't hard to add this cookie signing.

Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-12 15:36:59 -08:00
Andrew Keesler
8321773a22
auth_handler.go: fix lint error
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-12 12:24:40 -05:00
Andrew Keesler
3a943a3b9a
auth_handler.go: ignore encoding timestamp for deterministic tests
Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-12 12:14:50 -05:00
Ryan Richard
6d380c629a
auth_handler.go: use encryption in tests
Our unit tests are gonna touch a lot more corner cases than our
integration tests, so let's make them run as close to the real
implementation as possible.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-12 12:14:49 -05:00
Monis Khan
db6fc234b7 Add NullStorage for the authorize endpoint to use
We want to run all of the fosite validations in the authorize
endpoint, but we don't need to store anything yet because
we are storing what we need for later in the upstream state
parameter.

Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-11 14:49:24 -08:00
Ryan Richard
4b8c1de647 Add unit test to auth_handler_test.go for non-openid authorize requests
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-11 13:13:57 -08:00
Andrew Keesler
c2262773e6 Finish the WIP from the previous commit for saving authorize endpoint state
Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-11 12:29:14 -08:00
Monis Khan
dd190dede6 WIP for saving authorize endpoint state into upstream state param
Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-10 17:58:00 -08:00
Andrew Keesler
005225d5f9 Use the new plog pkg in auth_handler.go
- Add a new helper method to plog to make a consistent way to log
  expected errors at the info level (as opposed to unexpected
  system errors that would be logged using plog.Error)

Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-10 10:33:52 -08:00
Ryan Richard
b21c27b219 Merge branch 'main' into authorize_endpoint 2020-11-10 09:24:19 -08:00
Monis Khan
15a5332428
Reduce log spam
Signed-off-by: Monis Khan <mok@vmware.com>
2020-11-10 10:22:27 -05:00
Ryan Richard
246471bc91 Also run OIDC validations in supervisor authorize endpoint
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-06 14:44:58 -08:00
Ryan Richard
33ce79f89d Expose the Supervisor OIDC authorization endpoint to the public 2020-11-04 17:06:47 -08:00
Andrew Keesler
a36f7c6c07 Test that the port of localhost redirect URI is ignored during validation
Also move definition of our oauth client and the general fosite
configuration to a helper so we can use the same config to construct
the handler for both test and production code.

Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-04 15:04:50 -08:00
Ryan Richard
ba688f56aa Supervisor authorize endpoint errors when PKCE code_challenge_method is invalid
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-04 12:29:43 -08:00
Andrew Keesler
2564d1be42 Supervisor authorize endpoint errors when missing PKCE params
Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-04 12:19:07 -08:00
Ryan Richard
0045ce4286 Refactor auth_handler_test.go's creation of paths and urls to use helpers 2020-11-04 09:58:40 -08:00
Ryan Richard
8a7e22e63e @ankeesler: Maybe, but not this time ;) 2020-11-04 08:43:45 -08:00
Andrew Keesler
9e4ffd1cce
One of these days I will get here.Doc() spacing correct
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-04 11:29:33 -05:00
Andrew Keesler
6fe455c687
auth_handler.go: comment out currently unused fosite wiring
See e8f4336 for why this is here in the first place.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-04 11:20:03 -05:00
Andrew Keesler
d8c8f04860
auth_handler.go: write some more negative tests
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-04 11:12:26 -05:00
Andrew Keesler
e8f433643f
auth_handler.go: only inject oauth store into handler
Previously we were injecting the whole oauth handler chain into this function,
which meant we were essentially writing unit tests to test our tests. Let's push
some of this logic into the source code.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-04 10:35:26 -05:00
Andrew Keesler
4f95e6a372
auth_handler.go: add test for invalid downstream redirect uri
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-04 10:30:53 -05:00
Andrew Keesler
259ffb5267
Checkpoint: write a single negative test using fosite
Bringing in fosite to our go.mod introduced those other go.mod changes.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-04 10:15:19 -05:00
Ryan Richard
c34e5a727d Starting the implementation of an OIDC authorization endpoint handler
Does not validate incoming request parameters yet. Also is not
served on the http/https ports yet. Those will come in future commits.

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-11-03 16:17:38 -08:00
Andrew Keesler
0d8477ea8a Add a type for in-memory caching of upstream OIDC Identity Providers
Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-11-03 12:06:07 -08:00
Ryan Richard
8ff64d4c1a Require https scheme for OIDCProviderConfig Issuer field
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-10-28 12:49:41 -07:00
Ryan Richard
38802c2184 Add a way to set a default supervisor TLS cert for when SNI won't work
- Setting a Secret in the supervisor's namespace with a special name
  will cause it to get picked up and served as the supervisor's TLS
  cert for any request which does not have a matching SNI cert.
- This is especially useful for when there is no DNS record for an
  issuer and the user will be accessing it via IP address. This
  is not how we would expect it to be used in production, but it
  might be useful for other cases.
- Includes a new integration test
- Also suppress all of the warnings about ignoring the error returned by
  Close() in lines like `defer x.Close()` to make GoLand happier
2020-10-27 16:33:08 -07:00
Ryan Richard
8b7c30cfbd Supervisor listens for HTTPS on port 443 with configurable TLS certs
- TLS certificates can be configured on the OIDCProviderConfig using
  the `secretName` field.
- When listening for incoming TLS connections, choose the TLS cert
  based on the SNI hostname of the incoming request.
- Because SNI hostname information on incoming requests does not include
  the port number of the request, we add a validation that
  OIDCProviderConfigs where the issuer hostnames (not including port
  number) are the same must use the same `secretName`.
- Note that this approach does not yet support requests made to an
  IP address instead of a hostname. Also note that `localhost` is
  considered a hostname by SNI.
- Add port 443 as a container port to the pod spec.
- A new controller watches for TLS secrets and caches them in memory.
  That same in-memory cache is used while servicing incoming connections
  on the TLS port.
- Make it easy to configure both port 443 and/or port 80 for various
  Service types using our ytt templates for the supervisor.
- When deploying to kind, add another nodeport and forward it to the
  host on another port to expose our new HTTPS supervisor port to the
  host.
2020-10-26 17:03:26 -07:00
Ryan Richard
25a91019c2 Add spec.secretName to OPC and handle case-insensitive hostnames
- When two different Issuers have the same host (i.e. they differ
  only by path) then they must have the same secretName. This is because
  it wouldn't make sense for there to be two different TLS certificates
  for one host. Find any that do not have the same secret name to
  put an error status on them and to avoid serving OIDC endpoints for
  them. The host comparison is case-insensitive.
- Issuer hostnames should be treated as case-insensitive, because
  DNS hostnames are case-insensitive. So https://me.com and
  https://mE.cOm are duplicate issuers. However, paths are
  case-sensitive, so https://me.com/A and https://me.com/a are
  different issuers. Fixed this in the issuer validations and in the
  OIDC Manager's request router logic.
2020-10-23 16:25:44 -07:00
Ryan Richard
d9d76726c2 Implement per-issuer OIDC JWKS endpoint 2020-10-16 17:51:40 -07:00
Matt Moyer
67b692b11f
Implement the rest of an OIDC client CLI library.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2020-10-12 16:41:46 -05:00
Andrew Keesler
05141592f8 Refactor provider.Manager
- And also handle when an issuer's path is a subpath of another issuer

Signed-off-by: Ryan Richard <richardry@vmware.com>
2020-10-08 14:40:56 -07:00
Ryan Richard
8b7d96f42c Several small refactors related to OIDC providers 2020-10-08 11:28:21 -07:00
Ryan Richard
6b653fc663 Creation and deletion of OIDC Provider discovery endpoints from config
- The OIDCProviderConfigWatcherController synchronizes the
  OIDCProviderConfig settings to dynamically mount and unmount the
  OIDC discovery endpoints for each provider
- Integration test passes but unit tests need to be added still
2020-10-07 19:18:34 -07:00
Andrew Keesler
f48a4e445e
Fix linting and unit tests
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-10-07 11:48:21 -04:00
Andrew Keesler
20ce142f90
Merge remote-tracking branch 'upstream/main' into supervisor-with-discovery 2020-10-07 11:37:33 -04:00
Andrew Keesler
c49ebf4b57
supervisor-oidc: int test passes, but impl needs refactor
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-10-07 11:33:50 -04:00
Andrew Keesler
019f44982c
supervisor-oidc: checkpoint: controller watches OIDCProviderConfig
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-10-07 10:54:56 -04:00
Matt Moyer
38501ff763
Add initial "pinniped alpha login oidc" partial implementation.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2020-10-06 12:42:29 -05:00
Andrew Keesler
fd6a7f5892
supervisor-oidc: hoist OIDC discovery handler for testing
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
2020-10-06 11:16:57 -04:00