Skip to content
This repository has been archived by the owner on Dec 7, 2020. It is now read-only.

Commit

Permalink
Debug Handler (#156)
Browse files Browse the repository at this point in the history
- adding the --enable-profiling to switch on profiling
  • Loading branch information
gambol99 authored Nov 18, 2016
1 parent d98a7fe commit 004e966
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 7 deletions.
81 changes: 80 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@
Keycloak-proxy is a proxy service which at the risk of stating the obvious integrates with the [Keycloak](https://github.com/keycloak/keycloak) authentication service. Although technically the service has no dependency on Keycloak itself and would quite happily work with any OpenID provider. The service supports both access tokens in browser cookie or bearer tokens.

```shell
[jest@starfury keycloak-proxy]$ bin/keycloak-proxy help
NAME:
keycloak-proxy - is a proxy using the keycloak service for auth and authorization

USAGE:
keycloak-proxy [options]

VERSION:
v1.2.7 (git+sha: fe9654c)
v1.2.8 (git+sha: d98a7fe-dirty)

AUTHOR(S):
Rohith <[email protected]>
Expand All @@ -50,6 +51,7 @@ GLOBAL OPTIONS:
--revocation-url value the url for the revocation endpoint to revoke refresh token [$PROXY_REVOCATION_URL]
--store-url value url for the storage subsystem, e.g redis://127.0.0.1:6379, file:///etc/tokens.file [$PROXY_STORE_URL]
--upstream-url value the url for the upstream endpoint you wish to proxy to [$PROXY_UPSTREAM_URL]
--enable-login-handler this enables the login hanlder /oauth/login, by default this is disabled
--upstream-keepalives enables or disables the keepalive connections for upstream endpoint
--upstream-timeout value is the maximum amount of time a dial will wait for a connect to complete (default: 10s)
--upstream-keepalive-timeout value specifies the keep-alive period for an active network connection (default: 10s)
Expand Down Expand Up @@ -90,6 +92,7 @@ GLOBAL OPTIONS:
--cors-exposes-headers value set the expose cors headers access control (Access-Control-Expose-Headers)
--cors-max-age value the max age applied to cors headers (Access-Control-Max-Age) (default: 0s)
--cors-credentials the credentials access control header (Access-Control-Allow-Credentials)
--enable-profiling switching on the golang profiling via pprof on /debug/pprof, /debug/pprof/heap etc
--enable-security-filter enables the security filter handler
--skip-token-verification TESTING ONLY; bypass token verification, only expiration and roles enforced
--json-logging switch on json logging rather than text (defaults true)
Expand All @@ -98,6 +101,82 @@ GLOBAL OPTIONS:
--help, -h show help
--version, -v print the version
NAME:
keycloak-proxy - is a proxy using the keycloak service for auth and authorization
USAGE:
keycloak-proxy [options]
VERSION:
v1.2.7 (git+sha: fe9654c)
AUTHOR(S):
Rohith <[email protected]>
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--config value the path to the configuration file for the keycloak proxy [$PROXY_CONFIG_FILE]
--listen value the interface the service should be listening on [$PROXY_LISTEN]
--client-secret value the client secret used to authenticate to the oauth server (access_type: confidential) [$PROXY_CLIENT_SECRET]
--client-id value the client id used to authenticate to the oauth service [$PROXY_CLIENT_ID]
--discovery-url value the discovery url to retrieve the openid configuration [$PROXY_DISCOVERY_URL]
--scope value a variable list of scopes requested when authenticating the user
--token-validate-only validate the token and roles only, no required implement oauth
--redirection-url value redirection url for the oauth callback url (/oauth is added) [$PROXY_REDIRECTION_URL]
--revocation-url value the url for the revocation endpoint to revoke refresh token [$PROXY_REVOCATION_URL]
--store-url value url for the storage subsystem, e.g redis://127.0.0.1:6379, file:///etc/tokens.file [$PROXY_STORE_URL]
--upstream-url value the url for the upstream endpoint you wish to proxy to [$PROXY_UPSTREAM_URL]
--upstream-keepalives enables or disables the keepalive connections for upstream endpoint
--upstream-timeout value is the maximum amount of time a dial will wait for a connect to complete (default: 10s)
--upstream-keepalive-timeout value specifies the keep-alive period for an active network connection (default: 10s)
--enable-authorization-header adds the authorization header to the proxy request
--enable-refresh-tokens enables the handling of the refresh tokens
--secure-cookie enforces the cookie to be secure, default to true
--http-only-cookie enforces the cookie is in http only mode, default to false
--cookie-domain value a domain the access cookie is available to, defaults host header
--cookie-access-name value the name of the cookie use to hold the access token (default: "kc-access")
--cookie-refresh-name value the name of the cookie used to hold the encrypted refresh token (default: "kc-state")
--encryption-key value the encryption key used to encrpytion the session state
--no-redirects do not have back redirects when no authentication is present, 401 them
--hostname value a list of hostnames the service will respond to, defaults to all
--enable-metrics enable the prometheus metrics collector on /oauth/metrics
--localhost-only-metrics enforces the metrics page can only been requested from 127.0.0.1
--enable-proxy-protocol whether to enable proxy protocol
--enable-forwarding enables the forwarding proxy mode, signing outbound request
--forwarding-username value the username to use when logging into the openid provider
--forwarding-password value the password to use when logging into the openid provider
--forwarding-domains value a list of domains which should be signed; everything else is relayed unsigned
--tls-cert value the path to a certificate file used for TLS
--tls-private-key value the path to the private key for TLS support
--tls-ca-certificate value the path to the ca certificate used for mutual TLS
--tls-ca-key value the path the ca private key, used by the forward signing proxy
--tls-client-certificate value the path to the client certificate, used to outbound connections in reverse and forwarding proxy modes
--skip-upstream-tls-verify whether to skip the verification of any upstream TLS (defaults to true)
--skip-openid-provider-tls-verify whether to skip the verification of any TLS communication with the openid provider (defaults to false)
--match-claims value keypair values for matching access token claims e.g. aud=myapp, iss=http://example.*
--add-claims value retrieve extra claims from the token and inject into headers, e.g given_name -> X-Auth-Given-Name
--resource value a list of resources 'uri=/admin|methods=GET,PUT|roles=role1,role2'
--headers value Add custom headers to the upstream request, key=value
--signin-page value a custom template displayed for signin
--forbidden-page value a custom template used for access forbidden
--tag value keypair's passed to the templates at render,e.g title='My Page'
--cors-origins value list of origins to add to the CORE origins control (Access-Control-Allow-Origin)
--cors-methods value the method permitted in the access control (Access-Control-Allow-Methods)
--cors-headers value a set of headers to add to the CORS access control (Access-Control-Allow-Headers)
--cors-exposes-headers value set the expose cors headers access control (Access-Control-Expose-Headers)
--cors-max-age value the max age applied to cors headers (Access-Control-Max-Age) (default: 0s)
--cors-credentials the credentials access control header (Access-Control-Allow-Credentials)
--enable-security-filter enables the security filter handler
--skip-token-verification TESTING ONLY; bypass token verification, only expiration and roles enforced
--json-logging switch on json logging rather than text (defaults true)
--log-requests switch on logging of all incoming requests (defaults true)
--verbose switch on debug / verbose logging
--help, -h show help
--version, -v print the version
```

#### **Building**
Expand Down
13 changes: 10 additions & 3 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,11 +313,15 @@ func getCLIOptions() []cli.Flag {
Name: "cors-max-age",
Usage: "the max age applied to cors headers (Access-Control-Max-Age)",
},
cli.BoolFlag{
cli.BoolTFlag{
Name: "cors-credentials",
Usage: "the credentials access control header (Access-Control-Allow-Credentials)",
},
cli.BoolFlag{
cli.BoolTFlag{
Name: "enable-profiling",
Usage: "switching on the golang profiling via pprof on /debug/pprof, /debug/pprof/heap etc",
},
cli.BoolTFlag{
Name: "enable-security-filter",
Usage: "enables the security filter handler",
},
Expand All @@ -333,7 +337,7 @@ func getCLIOptions() []cli.Flag {
Name: "log-requests",
Usage: "switch on logging of all incoming requests (defaults true)",
},
cli.BoolFlag{
cli.BoolTFlag{
Name: "verbose",
Usage: "switch on debug / verbose logging",
},
Expand Down Expand Up @@ -429,6 +433,9 @@ func parseCLIOptions(cx *cli.Context, config *Config) (err error) {
if cx.IsSet("enable-login-handler") {
config.EnableLoginHandler = cx.Bool("enable-login-handler")
}
if cx.IsSet("enable-profiling") {
config.EnableProfiling = cx.Bool("enable-profiling")
}
if cx.IsSet("enable-metrics") {
config.EnableMetrics = cx.Bool("enable-metrics")
}
Expand Down
2 changes: 2 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ type Config struct {
// Headers permits adding customs headers across the board
Headers map[string]string `json:"headers" yaml:"headers"`

// EnableProfiling indicates if profiles is switched on
EnableProfiling bool `json:"enable-profiling" yaml:"enable-profiling"`
// EnableMetrics indicates if the metrics is enabled
EnableMetrics bool `json:"enable-metrics" yaml:"enable-metrics"`
// EnableURIMetrics indicates we want to keep metrics on uri request times
Expand Down
38 changes: 38 additions & 0 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"io/ioutil"
"net"
"net/http"
"net/http/pprof"
"net/url"
"path"
"strings"
Expand Down Expand Up @@ -394,6 +395,43 @@ func (r *oauthProxy) healthHandler(cx *gin.Context) {
cx.String(http.StatusOK, "OK\n")
}

// debugHandler is responsible for providing the pprof
func (r *oauthProxy) debugHandler(cx *gin.Context) {
name := cx.Param("name")
switch cx.Request.Method {
case http.MethodGet:
switch name {
case "heap":
fallthrough
case "goroutine":
fallthrough
case "block":
fallthrough
case "threadcreate":
pprof.Handler(name).ServeHTTP(cx.Writer, cx.Request)
case "cmdline":
pprof.Cmdline(cx.Writer, cx.Request)
case "profile":
pprof.Profile(cx.Writer, cx.Request)
case "trace":
pprof.Trace(cx.Writer, cx.Request)
case "symbol":
pprof.Symbol(cx.Writer, cx.Request)
default:
cx.AbortWithStatus(http.StatusNotFound)
}
case http.MethodPost:
switch name {
case "symbol":
pprof.Symbol(cx.Writer, cx.Request)
default:
cx.AbortWithStatus(http.StatusNotFound)
}
}

cx.Abort()
}

// metricsHandler forwards the request into the prometheus handler
func (r *oauthProxy) metricsHandler(cx *gin.Context) {
if r.config.LocalhostMetrics {
Expand Down
3 changes: 1 addition & 2 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func (r *oauthProxy) metricsMiddleware() gin.HandlerFunc {
// entrypointMiddleware checks to see if the request requires authentication
func (r *oauthProxy) entrypointMiddleware() gin.HandlerFunc {
return func(cx *gin.Context) {
// step: we can skip the
if strings.HasPrefix(cx.Request.URL.Path, oauthURL) {
return
}
Expand Down Expand Up @@ -255,10 +256,8 @@ func (r *oauthProxy) authenticationMiddleware() gin.HandlerFunc {
}
}(user.token, rToken)
}

// step: update the with the new access token
user.token = token

// step: inject the user into the context
cx.Set(userContextName, user)
}
Expand Down
8 changes: 7 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,16 @@ func (r *oauthProxy) createReverseProxy() error {
return err
}

//step: create the gin router
// step: create the gin router
engine := gin.New()
engine.Use(gin.Recovery())

// step: is profiling enabled?
if r.config.EnableProfiling {
log.Warn("Enabling the debug profiling on /debug/pprof")
engine.Any("/debug/pprof/:name", r.debugHandler)
}

// step: are we logging the traffic?
if r.config.LogRequests {
engine.Use(r.loggingMiddleware())
Expand Down

0 comments on commit 004e966

Please sign in to comment.