The "at_hash" claim, which provides hash verification for the
"access_token," is a required claim for implicit and hybrid flow
requests. Previously we did not include it (against spec). This
PR implements the "at_hash" logic and adds the claim to all
responses.
As a cleanup, it also moves some JOSE signing logic out of the
storage package and into the server package.
For details see:
https://openid.net/specs/openid-connect-core-1_0.html#ImplicitIDToken
The server implements a strategy called "Refresh Token Rotation" to
ensure refresh tokens can only be claimed once.
ref: https://tools.ietf.org/html/rfc6819#section-5.2.2.3
Previously "refresh_token" values in token responses where just the
ID of the internal refresh object. To implement rotation, when a
client redeemed a refresh token, the object would be deleted, a new
one created, and the new ID returned as the new "refresh_token".
However, this means there was no consistent ID for refresh tokens
internally, making things like foreign keys very hard to implement.
This is problematic for revocation features like showing all the
refresh tokens a user or client has out.
This PR updates the "refresh_token" to be an encoded protobuf
message, which holds the internal ID and a nonce. When a refresh
token is used, the nonce is updated to prevent reuse, but the ID
remains the same. Additionally it adds the timestamp of each
token's last use.
Accept the following response_type for the implicit flow:
id_token
token id_token
And the following for hybrid flow
code id_token
code token
code token id_token
This corrects the previous behavior of the implicit flow, which
only accepted "token" (now correctly rejected).
Introducing glide-vc caused us to unknowingly removed our Go
protobuf compiler (since it's a main). Add flags to glide-vc usage
to remedy this.
Since we now require several glide and glide-vc flags, add a Makfile
target and tests to catch when PRs don't use the correct flags.
Dex's Postgres client currently uses the `timestamp` datatype for
storing times. This lops of timezones with no conversion, causing
times to lose locality information.
We could convert all times to UTC before storing them, but this is
a backward incompatible change for upgrades, since the new version
of dex would still be reading times from the database with no
locality.
Because of this intrinsic issue that current Postgres users don't
save any timezone data, we chose to treat any existing installation
as corrupted and change the datatype used for times to `timestamptz`.
This is a breaking change, but it seems hard to offer an
alternative that's both correct and backward compatible.
Additionally, an internal flag has been added to SQL flavors,
`supportsTimezones`. This allows us to handle SQLite3, which doesn't
support timezones, while still storing timezones in other flavors.
Flavors that don't support timezones are explicitly converted to
UTC.
Add a script to check the Go version before building dex. This
gives a nice error message rather than just failing to compile.
With changes:
$ go version
go version go1.6.4 linux/amd64
$ make
ERROR: dex requires Go version 1.7+. Please update your Go installation: https://golang.org/dl/
Makefile:93: recipe for target 'check-go-version' failed
make: *** [check-go-version] Error 2
Checks only added for building the actual binary, not tests, since
this is aimed at users just starting off with the project.
This PR reworks the web layout so static files can be provided and
a "themes" directory to allow a certain degree of control over logos,
styles, etc.
This PR does NOT add general support for frontend customization,
only enough to allow us to start exploring theming internally.
The dex binary also must now be run from the root directory since
templates are no longer "compiled into" the binary.
The docker image has been updated with frontend assets.
Now that LDAP supports an `insecureSkipVerify` option, clarify that
`insecureNoTLS` is an extremely bad choice and as such we may drop
support for 389 in the future.
However, since we send plain text passwords from our frontend to our
backend, this probably gets us into a bigger conversation about dex's
TLS story. For example when terminiation is approporate. cc'ing
@dghubble for thoughts on how that might apply to our internal uses.
We probably want an overaching security doc at some point, but that
can be another PR.
Ensure compared times are within a second of one another instead of
rounding, which can flake if the two times are different enough to
do round to different values.
Tested using the golang.org/x/tools/cmd/stress tool.
The following set of commands fail without this patch:
$ go get golang.org/x/tools/cmd/stress
$ go test -o server.test github.com/coreos/dex/server
$ stress ./server.test -test.run=TestOAuth2CodeFlow
219 runs so far, 0 failures
425 runs so far, 0 failures
618 runs so far, 0 failures
802 runs so far, 0 failures
^C
Closes#699
Add OpenSSL to the dex Docker container so wget can be used to query
HTTPS endpoint. This is a requirement for health checking when dex is
doing its own TLS termination.
This increased the image size from 20.37 MB to 20.92 MB (+550 KB).
Additionally add Ed and Rithu as maintainers.
Bcrypt'd hashes have "$" characters in them. This means that #667
(accepting actually bcrypted values) combined with #627 (expanding
config with environment variables) broke the example config.
For now, allow storages and connectors to expand their configs from
the environment, but don't do this anywhere else.
ghodss/yaml converts from YAML to JSON before attempting to unmarshal.
This allows us to:
* Get the correct behavor when decoding base64'd []byte slices.
* Use *json.RawMessage.
* Not have to support extravagant YAML features.
* Let our structs use `json:` tags
Instead of throwing a 500 error if a user enters an invalid name,
display the same text box as if the user had entered the wrong
password.
NOTE: An invalid username now returns much quicker than an invalid
password. Consider adding an arbitrary sleep in the future if we
care about masking which was invalid.
Based on #640 we're going to osixia/openldap instead of rolling our
own container. Removing this work for now. If we want it back we can
revert easily enough.
Use a hash algorithm to match client IDs to Kubernetes object names.
Because cryptographic hash algorithms produce sums larger than a
Kubernetes name can fit, a non-cryptographic hash is used instead.
Hash collisions are checked and result in errors.
"state" means something specific to OAuth2 and SAML so we don't
want to confuse developers who are working on this.
Also don't use "session" which could easily be confused with HTTP
cookies.
Let the server handle the state token instead of the connector. As a
result it can throw out bad requests earlier. It can also use that
token to determine which connector was used to generate the request
allowing all connectors to share the same callback URL.
Callbacks now all look like:
https://dex.example.com/callback
Instead of:
https://dex.example.com/callback/(connector id)
Even when multiple connectors are being used.
Using the default KUBECONFIG environment variable to indicate that
the Kubernetes tests should be run lead to cases where developers
accidentally ran the tests. This has now been changed to
"DEX_KUBECONFIG" and documentation hsa been added detailing how to
run these tests.
Additionally, no other storage reads environment variables for its
normal configuration (outside of tests) so the Kubernetes storage
no longer does.
Overall, be less surprising.
These status codes spam the error logs for events like key rotation
and third party resource creation. In these cases "bad" status codes
are expected and shouldn't be automatically printed.
Allow users to define config values which are read form environemnt
variables. Helpful for sensitive variables such as OAuth2 client IDs
or LDAP credentials.
The in cluster kubernetes client currently requires using the
downward API to determine its namespace. However this value can be
determine by inspecting the service account token mounted into the
pod. As a fallback, use this to guess the current namespace.
go-oidc sends an extra space before the list of scopes. This is bad
but we have to support it, so we'll be more lenient and ignore
duplicated whitespace.
Some OpenID Connect providers, notably Google, don't follow the spec
and allow refresh tokens to be requested with the "offline_access"
scope. Try to determine which we're talking to by checking the
supported_scopes listed by the provider discovery.