From a4cb57ab5d7328a71b073302a41a7fcf66a6c48d Mon Sep 17 00:00:00 2001 From: Eric Chiang Date: Thu, 20 Apr 2017 16:48:09 -0700 Subject: [PATCH] Documentation: add a doc describing how to use dex --- Documentation/getting-started.md | 3 + Documentation/img/dex-flow.png | Bin 0 -> 21257 bytes Documentation/using-dex.md | 188 +++++++++++++++++++++++++++++++ README.md | 1 + 4 files changed, 192 insertions(+) create mode 100644 Documentation/img/dex-flow.png create mode 100644 Documentation/using-dex.md diff --git a/Documentation/getting-started.md b/Documentation/getting-started.md index bf85ae59..5633135d 100644 --- a/Documentation/getting-started.md +++ b/Documentation/getting-started.md @@ -40,8 +40,11 @@ Login to dex through the example app using the following steps. ## Further reading +Dex is generally used as a building block to drive authentication for other apps. See [_"Writing apps that use dex"_][using-dex] for an overview of instrumenting apps to work with dex. + Check out the Documentation directory for further reading on setting up different storages, interacting with the dex API, intros for OpenID Connect, and logging in through other identity providers such as Google, GitHub, or LDAP. [go-setup]: https://golang.org/doc/install [example-config]: ../examples/config-dev.yaml [oidc-discovery]: https://openid.net/specs/openid-connect-discovery-1_0-17.html#ProviderMetadata +[using-dex]: using-dex.md diff --git a/Documentation/img/dex-flow.png b/Documentation/img/dex-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..78acffd1a4ed91e3ac5dbec37bb172c338e91438 GIT binary patch literal 21257 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 z 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 YnO2Eg!=VFTL4)}Wp00i_>zopr0PYNke*gdg literal 0 HcmV?d00001 diff --git a/Documentation/using-dex.md b/Documentation/using-dex.md new file mode 100644 index 00000000..8ac230fa --- /dev/null +++ b/Documentation/using-dex.md @@ -0,0 +1,188 @@ +# Writing apps that use dex + +Once you have dex up and running, the next step is to write applications that use dex to drive authentication. Apps that interact with dex generally fall into one of two categories: + +1. Apps that request OpenID Connect ID tokens to authenticate users. + * Used for authenticating an end user. + * Must be web based. +2. Apps that consume ID tokens from other apps. + * Needs to verify that a client is acting on behalf of a user. + +The first category of apps are standard OAuth2 clients. Users show up at a website, and the application wants to authenticate those end users by pulling claims out of the ID token. + +The second category of apps consume ID tokens as credentials. This lets another service handle OAuth2 flows, then use the ID token retrieved from dex to act on the end user's behalf with the app. An example of an app that falls into this category is the [Kubernetes API server][api-server]. + +## Requesting an ID token from dex + +Apps that directly use dex to authenticate a user use OAuth2 code flows to request a token response. The exact steps taken are: + +* User visits client app. +* Client app redirects user to dex with an OAuth2 request. +* Dex determines user's identity. +* Dex redirects user to dex with a code. +* Client exchanges code with dex for an id_token. + +![][dex-flow] + +The dex repo contains a small [example app][example-app] as a working, self contained app that performs this flow. + +The rest of this section explores the code sections which to help explain how to implementing this logic in your own app. + +### Configuring your app + +The example app uses the following Go packages to perform the code flow: + +* [github.com/coreos/go-oidc][go-oidc] +* [golang.org/x/oauth2][go-oauth2] + +First, client details should be present in the dex configuration. For example, we could register an app with dex with the following section: + +```yaml +staticClients: +- id: example-app + secret: example-app-secret + name: 'Example App' + # Where the app will be running. + redirectURIs: + - 'http://127.0.0.1:5555/callback' +``` + +In this case, the Go code would configured as: + +```go +// Initialize a provider by specifying dex's issuer URL. +provider, err := oidc.NewProvider(ctx, "https://dex-issuer-url.com") +if err != nil { + // handle error +} + +// Configure the OAuth2 config with the client values. +oauth2Config := oauth2.Config{ + // client_id and client_secret of the client. + ClientID: "example-app", + ClientSecret: "example-app-secret", + + // The redirectURL. + RedirectURL: "http://127.0.0.1:5556/callback", + + // Discovery returns the OAuth2 endpoints. + Endpoint: provider.Endpoint(), + + // "openid" is a required scope for OpenID Connect flows. + // + // Other scopes, such as "groups" can be requested. + Scopes: []string{oidc.ScopeOpenID, "profile", "email", "groups"}, +} + +// Create an ID token parser. +idTokenVerifier := provider.NewVerifier(&oidc.Config{ClientID: "example-app"}) +``` + +The HTTP server should then redirect unauthenticated users to dex to initialize the OAuth2 flow. + +```go +// handleRedirect is used to start an OAuth2 flow with the dex server. +func handleRedirect(w http.ResponseWriter, r *http.Request) { + state := newState() + http.Redirect(w, r, oauth2Config.AuthCodeURL(state), http.StatusFound) +} +``` + +After dex verifies the user's identity it redirects the user back to the client app with a code that can be exchanged for an ID token. The ID token can then be parsed by the verifier created above. This immediately + +```go +func handleOAuth2Callback(w http.ResponseWriter, r *http.Request) { + state := r.URL.Query().Get("state") + + // Verify state. + + oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code")) + if err != nil { + // handle error + } + + // Extract the ID Token from OAuth2 token. + rawIDToken, ok := oauth2Token.Extra("id_token").(string) + if !ok { + // handle missing token + } + + // Parse and verify ID Token payload. + idToken, err := idTokenVerifier.Verify(ctx, rawIDToken) + if err != nil { + // handle error + } + + // Extract custom claims. + var claims struct { + Email string `json:"email"` + Verified bool `json:"email_verified"` + Groups []string `json:"groups"` + } + if err := idToken.Claims(&claims); err != nil { + // handle error + } +} +``` + +### State tokens + +The state parameter is an arbitrary string that dex will always return with the callback. It plays a security role, preventing certain kinds of OAuth2 attacks. Specifically it can be used by clients to ensure: + +* The user who started the flow is the one who finished it, by linking the user's session with the state token. For example, by setting the state as an HTTP cookie, then comparing it when the user returns to the app. +* The request hasn't been replayed. This could be accomplished by associating some nonce in the state. + +A more thorough discussion of these kinds of best practices can be found in the [_"OAuth 2.0 Threat Model and Security Considerations"_][oauth2-threat-model] RFC. + +## Consuming ID tokens + +Apps can also choose to consume ID tokens, letting other trusted clients handle the web flows for login. Clients pass along the ID tokens they receive from dex, usually as a bearer token, letting them act at the user to the backend service. + +To accept ID tokens as user credentials, an app would construct an OpenID Connect verifier similarly to the above example. The verifier validates the ID token's signature, ensures it hasn't expired, etc. An important part of this code is that the verifier only trusts the example app's client. This ensures the example app is the one who's using the ID token, and not another, untrusted client. + +```go +// Initialize a provider by specifying dex's issuer URL. +provider, err := oidc.NewProvider(ctx, "https://dex-issuer-url.com") +if err != nil { + // handle error +} +// Create an ID token parser, but only trust ID tokens issued to "example-app" +idTokenVerifier := provider.NewVerifier(&oidc.Config{ClientID: "example-app"}) +``` + +The verifier can then be used to pull user info out of tokens: + +```go +type user struct { + email string + groups []string +} + +// authorize verifies a bearer token and pulls user information form the claims. +func authorize(ctx context.Context, bearerToken string) (*user, error) { + idToken, err := idTokenVerifier.Verify(ctx, bearerToken) + if err != nil { + return nil, fmt.Errorf("could not verify bearer token: %v", err) + } + // Extract custom claims. + var claims struct { + Email string `json:"email"` + Verified bool `json:"email_verified"` + Groups []string `json:"groups"` + } + if err := idToken.Claims(&claims); err != nil { + return nil, fmt.Errorf("failed to parse claims: %v", err) + } + if !claims.Verified { + return nil, fmt.Errorf("email (%q) in returned claims was not verified", claims.Email) + } + return &user{claims.Email, claims.Groups}, nil +} +``` + +[api-server]: https://kubernetes.io/docs/admin/authentication/#openid-connect-tokens +[dex-flow]: img/dex-flow.png +[example-app]: ../cmd/example-app +[oauth2-threat-model]: https://tools.ietf.org/html/rfc6819 +[go-oidc]: https://godoc.org/github.com/coreos/go-oidc +[go-oauth2]: https://godoc.org/golang.org/x/oauth2 diff --git a/README.md b/README.md index 4160dfdd..3a2c8b4f 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ More docs for running dex as a Kubernetes authenticator can be found [here](Docu ## Documentation * [Getting started](Documentation/getting-started.md) +* [Writing apps that use dex](Documentation/using-dex.md) * [What's new in v2](Documentation/v2.md) * [Custom scopes, claims, and client features](Documentation/custom-scopes-claims-clients.md) * [Storage options](Documentation/storage.md)