1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-01-10 04:18:14 +02:00

Merge branch 'master' into ap-gh-pagination-with-lastpage

This commit is contained in:
Joel Speed 2019-11-14 14:15:25 +00:00
commit 6326660699
No known key found for this signature in database
GPG Key ID: 6E80578D6751DEFB
22 changed files with 173 additions and 76 deletions

View File

@ -1,16 +1,19 @@
# Vx.x.x (Pre-release) # Vx.x.x (Pre-release)
## Changes since v4.0.0 ## Changes since v4.0.0
- [#292](https://github.com/pusher/oauth2_proxy/pull/292) Added bash >= 4.0 dependency to configure script (@jmfrank63)
- [#227](https://github.com/pusher/oauth2_proxy/pull/227) Add Keycloak provider (@Ofinka) - [#227](https://github.com/pusher/oauth2_proxy/pull/227) Add Keycloak provider (@Ofinka)
- [#259](https://github.com/pusher/oauth2_proxy/pull/259) Redirect to HTTPS (@jmickey) - [#259](https://github.com/pusher/oauth2_proxy/pull/259) Redirect to HTTPS (@jmickey)
- [#273](https://github.com/pusher/oauth2_proxy/pull/273) Support Go 1.13 (@dio) - [#273](https://github.com/pusher/oauth2_proxy/pull/273) Support Go 1.13 (@dio)
- [#275](https://github.com/pusher/oauth2_proxy/pull/275) docker: build from debian buster (@syscll) - [#275](https://github.com/pusher/oauth2_proxy/pull/275) docker: build from debian buster (@syscll)
- [#258](https://github.com/pusher/oauth2_proxy/pull/258) Add IDToken for Azure provider - [#258](https://github.com/pusher/oauth2_proxy/pull/258) Add IDToken for Azure provider
- This PR adds the IDToken into the session for the Azure provider allowing requests to a backend to be identified as a specific user. As a consequence, if you are using a cookie to store the session the cookie will now exceed the 4kb size limit and be split into multiple cookies. This can cause problems when using nginx as a proxy, resulting in no cookie being passed at all. Either increase the proxy_buffer_size in nginx or implement the redis session storage (see https://pusher.github.io/oauth2_proxy/configuration#redis-storage) - This PR adds the IDToken into the session for the Azure provider allowing requests to a backend to be identified as a specific user. As a consequence, if you are using a cookie to store the session the cookie will now exceed the 4kb size limit and be split into multiple cookies. This can cause problems when using nginx as a proxy, resulting in no cookie being passed at all. Either increase the proxy_buffer_size in nginx or implement the redis session storage (see https://pusher.github.io/oauth2_proxy/configuration#redis-storage)
- [#274](https://github.com/pusher/oauth2_proxy/pull/274) Supports many github teams with api pagination support (@toshi-miura,@apratina)
- [#286](https://github.com/pusher/oauth2_proxy/pull/286) Requests.go updated with useful error messages (@biotom) - [#286](https://github.com/pusher/oauth2_proxy/pull/286) Requests.go updated with useful error messages (@biotom)
- [#274](https://github.com/pusher/oauth2_proxy/pull/274) Supports many github teams with api pagination support (@toshi-miura, @apratina)
- [#302](https://github.com/pusher/oauth2_proxy/pull/302) Rewrite dist script (@syscll)
- [#304](https://github.com/pusher/oauth2_proxy/pull/304) Add new Logo! :tada: (@JoelSpeed)
- [#300](https://github.com/pusher/oauth2_proxy/pull/300) Added userinfo endpoint (@kbabuadze)
- [#309](https://github.com/pusher/oauth2_proxy/pull/309) Added support for custom CA when connecting to Redis cache
# v4.0.0 # v4.0.0

View File

@ -61,29 +61,4 @@ test: lint
.PHONY: release .PHONY: release
release: lint test release: lint test
mkdir release BINARY=${BINARY} VERSION=${VERSION} ./dist.sh
mkdir release/$(BINARY)-$(VERSION).darwin-amd64.$(GO_VERSION)
mkdir release/$(BINARY)-$(VERSION).linux-amd64.$(GO_VERSION)
mkdir release/$(BINARY)-$(VERSION).linux-arm64.$(GO_VERSION)
mkdir release/$(BINARY)-$(VERSION).linux-armv6.$(GO_VERSION)
mkdir release/$(BINARY)-$(VERSION).windows-amd64.$(GO_VERSION)
GO111MODULE=on GOOS=darwin GOARCH=amd64 go build -ldflags="-X main.VERSION=${VERSION}" \
-o release/$(BINARY)-$(VERSION).darwin-amd64.$(GO_VERSION)/$(BINARY) github.com/pusher/oauth2_proxy
GO111MODULE=on GOOS=linux GOARCH=amd64 go build -ldflags="-X main.VERSION=${VERSION}" \
-o release/$(BINARY)-$(VERSION).linux-amd64.$(GO_VERSION)/$(BINARY) github.com/pusher/oauth2_proxy
GO111MODULE=on GOOS=linux GOARCH=arm64 go build -ldflags="-X main.VERSION=${VERSION}" \
-o release/$(BINARY)-$(VERSION).linux-arm64.$(GO_VERSION)/$(BINARY) github.com/pusher/oauth2_proxy
GO111MODULE=on GOOS=linux GOARCH=arm GOARM=6 go build -ldflags="-X main.VERSION=${VERSION}" \
-o release/$(BINARY)-$(VERSION).linux-armv6.$(GO_VERSION)/$(BINARY) github.com/pusher/oauth2_proxy
GO111MODULE=on GOOS=windows GOARCH=amd64 go build -ldflags="-X main.VERSION=${VERSION}" \
-o release/$(BINARY)-$(VERSION).windows-amd64.$(GO_VERSION)/$(BINARY) github.com/pusher/oauth2_proxy
shasum -a 256 release/$(BINARY)-$(VERSION).darwin-amd64.$(GO_VERSION)/$(BINARY) > release/$(BINARY)-$(VERSION).darwin-amd64-sha256sum.txt
shasum -a 256 release/$(BINARY)-$(VERSION).linux-amd64.$(GO_VERSION)/$(BINARY) > release/$(BINARY)-$(VERSION).linux-amd64-sha256sum.txt
shasum -a 256 release/$(BINARY)-$(VERSION).linux-arm64.$(GO_VERSION)/$(BINARY) > release/$(BINARY)-$(VERSION).linux-arm64-sha256sum.txt
shasum -a 256 release/$(BINARY)-$(VERSION).linux-armv6.$(GO_VERSION)/$(BINARY) > release/$(BINARY)-$(VERSION).linux-armv6-sha256sum.txt
shasum -a 256 release/$(BINARY)-$(VERSION).windows-amd64.$(GO_VERSION)/$(BINARY) > release/$(BINARY)-$(VERSION).windows-amd64-sha256sum.txt
tar -C release -czvf release/$(BINARY)-$(VERSION).darwin-amd64.$(GO_VERSION).tar.gz $(BINARY)-$(VERSION).darwin-amd64.$(GO_VERSION)
tar -C release -czvf release/$(BINARY)-$(VERSION).linux-amd64.$(GO_VERSION).tar.gz $(BINARY)-$(VERSION).linux-amd64.$(GO_VERSION)
tar -C release -czvf release/$(BINARY)-$(VERSION).linux-arm64.$(GO_VERSION).tar.gz $(BINARY)-$(VERSION).linux-arm64.$(GO_VERSION)
tar -C release -czvf release/$(BINARY)-$(VERSION).linux-armv6.$(GO_VERSION).tar.gz $(BINARY)-$(VERSION).linux-armv6.$(GO_VERSION)
tar -C release -czvf release/$(BINARY)-$(VERSION).windows-amd64.$(GO_VERSION).tar.gz $(BINARY)-$(VERSION).windows-amd64.$(GO_VERSION)

View File

@ -1,4 +1,4 @@
# oauth2_proxy ![OAuth2 Proxy](/docs/logos/OAuth2_Proxy_horizontal.svg)
[![Build Status](https://secure.travis-ci.org/pusher/oauth2_proxy.svg?branch=master)](http://travis-ci.org/pusher/oauth2_proxy) [![Build Status](https://secure.travis-ci.org/pusher/oauth2_proxy.svg?branch=master)](http://travis-ci.org/pusher/oauth2_proxy)
[![Go Report Card](https://goreportcard.com/badge/github.com/pusher/oauth2_proxy)](https://goreportcard.com/report/github.com/pusher/oauth2_proxy) [![Go Report Card](https://goreportcard.com/badge/github.com/pusher/oauth2_proxy)](https://goreportcard.com/report/github.com/pusher/oauth2_proxy)

4
configure vendored
View File

@ -5,6 +5,10 @@ GREEN='\033[0;32m'
BLUE='\033[0;34m' BLUE='\033[0;34m'
NC='\033[0m' NC='\033[0m'
if [ -z "${BASH_VERSINFO}" ] || [ -z "${BASH_VERSINFO[0]}" ] || [ ${BASH_VERSINFO[0]} -lt 4 ]; then
echo "This script requires Bash version >= 4"; exit 1;
fi
declare -A tools=() declare -A tools=()
declare -A desired=() declare -A desired=()

View File

@ -0,0 +1,30 @@
#
# Autocompletion for oauth2_proxy
#
# To install this, copy/move this file to /etc/bash.completion.d/
# or add a line to your ~/.bashrc | ~/.bash_profile that says ". /path/to/oauth2_proxy/contrib/oauth2_proxy_autocomplete.sh"
#
_oauth2_proxy() {
_oauth2_proxy_commands=$(oauth2_proxy -h 2>&1 | sed -n '/^\s*-/s/ \+/ /gp' | awk '{print $1}' | tr '\n' ' ')
local cur prev
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
case "$prev" in
-@(config|tls-cert-file|tls-key-file|authenticated-emails-file|htpasswd-file|custom-templates-dir|logging-filename|jwt-key-file))
_filedir
return 0
;;
-provider)
COMPREPLY=( $(compgen -W "google azure facebook github keycloak gitlab linkedin login.gov" -- ${cur}) )
return 0
;;
-@(http-address|https-address|redirect-url|upstream|basic-auth-password|skip-auth-regex|flush-interval|extra-jwt-issuers|email-domain|whitelist-domain|keycloak-group|azure-tenant|bitbucket-team|bitbucket-repository|github-org|github-team|gitlab-group|google-group|google-admin-email|google-service-account-json|client-id|client_secret|banner|footer|proxy-prefix|ping-path|cookie-name|cookie-secret|cookie-domain|cookie-path|cookie-expire|cookie-refresh|redist-sentinel-master-name|redist-sentinel-connection-urls|logging-max-size|logging-max-age|logging-max-backups|standard-logging-format|request-logging-format|exclude-logging-paths|auth-logging-format|oidc-issuer-url|oidc-jwks-url|login-url|redeem-url|profile-url|resource|validate-url|scope|approval-prompt|signature-key|acr-values|jwt-key|pubjwk-url))
return 0
;;
esac
COMPREPLY=( $(compgen -W "${_oauth2_proxy_commands}" -- ${cur}) )
return 0;
}
complete -F _oauth2_proxy oauth2_proxy

83
dist.sh
View File

@ -1,45 +1,46 @@
#!/bin/bash #!/usr/bin/env bash
# build binary distributions for linux/amd64 and darwin/amd64
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" set -o errexit
echo "working dir $DIR"
mkdir -p $DIR/dist
dep ensure || exit 1
os=$(go env GOOS) if [[ -z ${BINARY} ]] || [[ -z ${VERSION} ]]; then
arch=$(go env GOARCH) echo "Missing required env var: BINARY=X VERSION=X $(basename $0)"
version=$(cat $DIR/version.go | grep "const VERSION" | awk '{print $NF}' | sed 's/"//g') exit 1
goversion=$(go version | awk '{print $3}')
sha256sum=()
echo "... running tests"
./test.sh
for os in windows linux darwin; do
echo "... building v$version for $os/$arch"
EXT=
if [ $os = windows ]; then
EXT=".exe"
fi
BUILD=$(mktemp -d ${TMPDIR:-/tmp}/oauth2_proxy.XXXXXX)
TARGET="oauth2_proxy-$version.$os-$arch.$goversion"
FILENAME="oauth2_proxy-$version.$os-$arch$EXT"
GOOS=$os GOARCH=$arch CGO_ENABLED=0 \
go build -ldflags="-s -w" -o $BUILD/$TARGET/$FILENAME || exit 1
pushd $BUILD/$TARGET
sha256sum+=("$(shasum -a 256 $FILENAME || exit 1)")
cd .. && tar czvf $TARGET.tar.gz $TARGET
mv $TARGET.tar.gz $DIR/dist
popd
done
checksum_file="sha256sum.txt"
cd $DIR/dist
if [ -f $checksum_file ]; then
rm $checksum_file
fi fi
touch $checksum_file
for checksum in "${sha256sum[@]}"; do # Check for Go version 1.13.*
echo "$checksum" >> $checksum_file GO_VERSION=$(go version | awk '{print $3}')
if [[ ! "${GO_VERSION}" =~ ^go1.13.* ]]; then
echo "Go version must be >= go1.13"
exit 1
fi
ARCHS=(darwin-amd64 linux-amd64 linux-arm64 linux-armv6 windows-amd64)
mkdir -p release
# Create architecture specific release dirs
for ARCH in "${ARCHS[@]}"; do
mkdir -p release/${BINARY}-${VERSION}.${ARCH}.${GO_VERSION}
GO_OS=$(echo $ARCH | awk -F- '{print $1}')
GO_ARCH=$(echo $ARCH | awk -F- '{print $2}')
# Create architecture specific binaries
if [[ ${GO_ARCH} == "armv6" ]]; then
GO111MODULE=on GOOS=${GO_OS} GOARCH=arm GOARM=6 go build -ldflags="-X main.VERSION=${VERSION}" \
-o release/${BINARY}-${VERSION}.${ARCH}.${GO_VERSION}/${BINARY} github.com/pusher/oauth2_proxy
else
GO111MODULE=on GOOS=${GO_OS} GOARCH=${GO_ARCH} go build -ldflags="-X main.VERSION=${VERSION}" \
-o release/${BINARY}-${VERSION}.${ARCH}.${GO_VERSION}/${BINARY} github.com/pusher/oauth2_proxy
fi
cd release
# Create sha256sum for architecture specific binary
shasum -a 256 ${BINARY}-${VERSION}.${ARCH}.${GO_VERSION}/${BINARY} > ${BINARY}-${VERSION}.${ARCH}-sha256sum.txt
# Create tar file for architecture specific binary
tar -czvf ${BINARY}-${VERSION}.${ARCH}.${GO_VERSION}.tar.gz ${BINARY}-${VERSION}.${ARCH}.${GO_VERSION}
cd ..
done done

View File

@ -5,7 +5,7 @@ permalink: /
nav_order: 0 nav_order: 0
--- ---
# oauth2_proxy ![OAuth2 Proxy](/logos/OAuth2_Proxy_horizontal.svg)
A reverse proxy and static file server that provides authentication using Providers (Google, GitHub, and others) A reverse proxy and static file server that provides authentication using Providers (Google, GitHub, and others)
to validate accounts by email, domain or group. to validate accounts by email, domain or group.

View File

@ -9,7 +9,7 @@ nav_order: 1
1. Choose how to deploy: 1. Choose how to deploy:
a. Download [Prebuilt Binary](https://github.com/pusher/oauth2_proxy/releases) (current release is `v3.2.0`) a. Download [Prebuilt Binary](https://github.com/pusher/oauth2_proxy/releases) (current release is `v4.0.0`)
b. Build with `$ go get github.com/pusher/oauth2_proxy` which will put the binary in `$GOROOT/bin` b. Build with `$ go get github.com/pusher/oauth2_proxy` which will put the binary in `$GOROOT/bin`
@ -18,8 +18,8 @@ nav_order: 1
Prebuilt binaries can be validated by extracting the file and verifying it against the `sha256sum.txt` checksum file provided for each release starting with version `v3.0.0`. Prebuilt binaries can be validated by extracting the file and verifying it against the `sha256sum.txt` checksum file provided for each release starting with version `v3.0.0`.
``` ```
sha256sum -c sha256sum.txt 2>&1 | grep OK $ sha256sum -c sha256sum.txt 2>&1 | grep OK
oauth2_proxy-3.2.0.linux-amd64: OK oauth2_proxy-4.0.0.linux-amd64: OK
``` ```
2. [Select a Provider and Register an OAuth Application with a Provider](auth-configuration) 2. [Select a Provider and Register an OAuth Application with a Provider](auth-configuration)

View File

@ -14,4 +14,5 @@ OAuth2 Proxy responds directly to the following endpoints. All other endpoints w
- /oauth2/sign_in - the login page, which also doubles as a sign out page (it clears cookies) - /oauth2/sign_in - the login page, which also doubles as a sign out page (it clears cookies)
- /oauth2/start - a URL that will redirect to start the OAuth cycle - /oauth2/start - a URL that will redirect to start the OAuth cycle
- /oauth2/callback - the URL used at the end of the OAuth cycle. The oauth app will be configured with this as the callback url. - /oauth2/callback - the URL used at the end of the OAuth cycle. The oauth app will be configured with this as the callback url.
- /oauth2/userinfo - the URL is used to return user's email from the session in JSON format.
- /oauth2/auth - only returns a 202 Accepted response or a 401 Unauthorized response; for use with the [Nginx `auth_request` directive](#nginx-auth-request) - /oauth2/auth - only returns a 202 Accepted response or a 401 Unauthorized response; for use with the [Nginx `auth_request` directive](#nginx-auth-request)

View File

@ -14,6 +14,7 @@
# You can create any custom variable you would like, and they will be accessible # You can create any custom variable you would like, and they will be accessible
# in the templates via {{ site.myvariable }}. # in the templates via {{ site.myvariable }}.
title: OAuth2_Proxy title: OAuth2_Proxy
logo: /logos/OAuth2_Proxy_horizontal.svg
description: >- # this means to ignore newlines until "baseurl:" description: >- # this means to ignore newlines until "baseurl:"
OAuth2_Proxy documentation site OAuth2_Proxy documentation site
baseurl: "/oauth2_proxy" # the subpath of your site, e.g. /blog baseurl: "/oauth2_proxy" # the subpath of your site, e.g. /blog

View File

@ -117,7 +117,7 @@ See below for provider specific options
### Upstreams Configuration ### Upstreams Configuration
`oauth2_proxy` supports having multiple upstreams, and has the option to pass requests on to HTTP(S) servers or serve static files from the file system. HTTP and HTTPS upstreams are configured by providing a URL such as `http://127.0.0.1:8080/` for the upstream parameter, that will forward all authenticated requests to be forwarded to the upstream server. If you instead provide `http://127.0.0.1:8080/some/path/` then it will only be requests that start with `/some/path/` which are forwarded to the upstream. `oauth2_proxy` supports having multiple upstreams, and has the option to pass requests on to HTTP(S) servers or serve static files from the file system. HTTP and HTTPS upstreams are configured by providing a URL such as `http://127.0.0.1:8080/` for the upstream parameter, this will forward all authenticated requests to the upstream server. If you instead provide `http://127.0.0.1:8080/some/path/` then it will only be requests that start with `/some/path/` which are forwarded to the upstream.
Static file paths are configured as a file:// URL. `file:///var/www/static/` will serve the files from that directory at `http://[oauth2_proxy url]/var/www/static/`, which may not be what you want. You can provide the path to where the files should be available by adding a fragment to the configured URL. The value of the fragment will then be used to specify which path the files are available at. `file:///var/www/static/#/static/` will ie. make `/var/www/static/` available at `http://[oauth2_proxy url]/static/`. Static file paths are configured as a file:// URL. `file:///var/www/static/` will serve the files from that directory at `http://[oauth2_proxy url]/var/www/static/`, which may not be what you want. You can provide the path to where the files should be available by adding a fragment to the configured URL. The value of the fragment will then be used to specify which path the files are available at. `file:///var/www/static/#/static/` will ie. make `/var/www/static/` available at `http://[oauth2_proxy url]/static/`.

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 360"><defs><style>.cls-1{fill:#06ed94;}.cls-2{fill:#059b61;}.cls-3{fill:#1957ba;}.cls-4{fill:#6ca8ff;}</style></defs><title>OAuth2_Proxy_logo_v3</title><path class="cls-1" d="M179.00205,349.728c-93.69483,0-169.921-76.22687-169.921-169.9217S85.30722,9.88462,179.00205,9.88462c93.69408,0,169.92021,76.22687,169.92021,169.9217S272.69613,349.728,179.00205,349.728Zm0-327.81581c-87.06238,0-157.89338,70.831-157.89338,157.89411s70.831,157.89411,157.89338,157.89411,157.89411-70.831,157.89411-157.89411S266.06442,21.91221,179.00205,21.91221Z"/><polygon class="cls-2" points="208.628 90.373 203.724 108.705 243.153 141.064 280.21 136.494 208.628 90.373"/><polygon class="cls-1" points="304.604 167.593 304.604 133.558 250.778 87.759 208.628 90.373 260.02 131.65 53.401 131.65 53.401 169.893 304.604 167.593"/><polygon class="cls-3" points="149.376 261.504 154.28 243.172 113.684 209.179 77.795 215.382 149.376 261.504"/><polygon class="cls-4" points="53.401 184.283 53.401 218.319 107.226 264.118 149.376 261.504 97.984 220.226 304.604 220.226 304.604 181.984 53.401 184.283"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -91,6 +91,8 @@ func main() {
flagSet.String("redis-connection-url", "", "URL of redis server for redis session storage (eg: redis://HOST[:PORT])") flagSet.String("redis-connection-url", "", "URL of redis server for redis session storage (eg: redis://HOST[:PORT])")
flagSet.Bool("redis-use-sentinel", false, "Connect to redis via sentinels. Must set --redis-sentinel-master-name and --redis-sentinel-connection-urls to use this feature") flagSet.Bool("redis-use-sentinel", false, "Connect to redis via sentinels. Must set --redis-sentinel-master-name and --redis-sentinel-connection-urls to use this feature")
flagSet.String("redis-sentinel-master-name", "", "Redis sentinel master name. Used in conjunction with --redis-use-sentinel") flagSet.String("redis-sentinel-master-name", "", "Redis sentinel master name. Used in conjunction with --redis-use-sentinel")
flagSet.String("redis-ca-path", "", "Redis custom CA path")
flagSet.Bool("redis-insecure-skip-tls-verify", false, "Use insecure TLS connection to redis")
flagSet.Var(&redisSentinelConnectionURLs, "redis-sentinel-connection-urls", "List of Redis sentinel connection URLs (eg redis://HOST[:PORT]). Used in conjunction with --redis-use-sentinel") flagSet.Var(&redisSentinelConnectionURLs, "redis-sentinel-connection-urls", "List of Redis sentinel connection URLs (eg redis://HOST[:PORT]). Used in conjunction with --redis-use-sentinel")
flagSet.String("logging-filename", "", "File to log requests to, empty for stdout") flagSet.String("logging-filename", "", "File to log requests to, empty for stdout")

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"crypto/tls" "crypto/tls"
b64 "encoding/base64" b64 "encoding/base64"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"html/template" "html/template"
@ -75,6 +76,7 @@ type OAuthProxy struct {
OAuthStartPath string OAuthStartPath string
OAuthCallbackPath string OAuthCallbackPath string
AuthOnlyPath string AuthOnlyPath string
UserInfoPath string
redirectURL *url.URL // the url to receive requests at redirectURL *url.URL // the url to receive requests at
whitelistDomains []string whitelistDomains []string
@ -266,6 +268,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
OAuthStartPath: fmt.Sprintf("%s/start", opts.ProxyPrefix), OAuthStartPath: fmt.Sprintf("%s/start", opts.ProxyPrefix),
OAuthCallbackPath: fmt.Sprintf("%s/callback", opts.ProxyPrefix), OAuthCallbackPath: fmt.Sprintf("%s/callback", opts.ProxyPrefix),
AuthOnlyPath: fmt.Sprintf("%s/auth", opts.ProxyPrefix), AuthOnlyPath: fmt.Sprintf("%s/auth", opts.ProxyPrefix),
UserInfoPath: fmt.Sprintf("%s/userinfo", opts.ProxyPrefix),
ProxyPrefix: opts.ProxyPrefix, ProxyPrefix: opts.ProxyPrefix,
provider: opts.provider, provider: opts.provider,
@ -557,6 +560,8 @@ func (p *OAuthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
p.OAuthCallback(rw, req) p.OAuthCallback(rw, req)
case path == p.AuthOnlyPath: case path == p.AuthOnlyPath:
p.AuthenticateOnly(rw, req) p.AuthenticateOnly(rw, req)
case path == p.UserInfoPath:
p.UserInfo(rw, req)
default: default:
p.Proxy(rw, req) p.Proxy(rw, req)
} }
@ -585,6 +590,22 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) {
} }
} }
//UserInfo endpoint outputs session email in JSON format
func (p *OAuthProxy) UserInfo(rw http.ResponseWriter, req *http.Request) {
session, err := p.getAuthenticatedSession(rw, req)
if err != nil {
http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
userInfo := struct {
Email string `json:"email"`
}{session.Email}
rw.Header().Set("Content-Type", "application/json")
rw.WriteHeader(http.StatusOK)
json.NewEncoder(rw).Encode(userInfo)
}
// SignOut sends a response to clear the authentication cookie // SignOut sends a response to clear the authentication cookie
func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) { func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) {
p.ClearSessionCookie(rw, req) p.ClearSessionCookie(rw, req)

View File

@ -746,6 +746,32 @@ func TestProcessCookieFailIfRefreshSetAndCookieExpired(t *testing.T) {
} }
} }
func NewUserInfoEndpointTest() *ProcessCookieTest {
pcTest := NewProcessCookieTestWithDefaults()
pcTest.req, _ = http.NewRequest("GET",
pcTest.opts.ProxyPrefix+"/userinfo", nil)
return pcTest
}
func TestUserInfoEndpointAccepted(t *testing.T) {
test := NewUserInfoEndpointTest()
startSession := &sessions.SessionState{
Email: "john.doe@example.com", AccessToken: "my_access_token"}
test.SaveSession(startSession)
test.proxy.ServeHTTP(test.rw, test.req)
assert.Equal(t, http.StatusOK, test.rw.Code)
bodyBytes, _ := ioutil.ReadAll(test.rw.Body)
assert.Equal(t, "{\"email\":\"john.doe@example.com\"}\n", string(bodyBytes))
}
func TestUserInfoEndpointUnauthorizedOnNoCookieSetError(t *testing.T) {
test := NewUserInfoEndpointTest()
test.proxy.ServeHTTP(test.rw, test.req)
assert.Equal(t, http.StatusUnauthorized, test.rw.Code)
}
func NewAuthOnlyEndpointTest(modifiers ...OptionsModifier) *ProcessCookieTest { func NewAuthOnlyEndpointTest(modifiers ...OptionsModifier) *ProcessCookieTest {
pcTest := NewProcessCookieTestWithOptionsModifiers(modifiers...) pcTest := NewProcessCookieTestWithOptionsModifiers(modifiers...)
pcTest.req, _ = http.NewRequest("GET", pcTest.req, _ = http.NewRequest("GET",

View File

@ -27,4 +27,6 @@ type RedisStoreOptions struct {
UseSentinel bool `flag:"redis-use-sentinel" cfg:"redis_use_sentinel" env:"OAUTH2_PROXY_REDIS_USE_SENTINEL"` UseSentinel bool `flag:"redis-use-sentinel" cfg:"redis_use_sentinel" env:"OAUTH2_PROXY_REDIS_USE_SENTINEL"`
SentinelMasterName string `flag:"redis-sentinel-master-name" cfg:"redis_sentinel_master_name" env:"OAUTH2_PROXY_REDIS_SENTINEL_MASTER_NAME"` SentinelMasterName string `flag:"redis-sentinel-master-name" cfg:"redis_sentinel_master_name" env:"OAUTH2_PROXY_REDIS_SENTINEL_MASTER_NAME"`
SentinelConnectionURLs []string `flag:"redis-sentinel-connection-urls" cfg:"redis_sentinel_connection_urls" env:"OAUTH2_PROXY_REDIS_SENTINEL_CONNECTION_URLS"` SentinelConnectionURLs []string `flag:"redis-sentinel-connection-urls" cfg:"redis_sentinel_connection_urls" env:"OAUTH2_PROXY_REDIS_SENTINEL_CONNECTION_URLS"`
RedisCAPath string `flag:"redis-ca-path" cfg:"redis_ca_path" env:"OAUTH2_PROXY_REDIS_CA_PATH"`
RedisInsecureTLS bool `flag:"redis-insecure-skip-tls-verify" cfg:"redis_insecure_skip_tls_verify" env:"OAUTH2_PROXY_REDIS_INSECURE_SKIP_TLS_VERIFY"`
} }

View File

@ -4,10 +4,12 @@ import (
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"crypto/rand" "crypto/rand"
"crypto/x509"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"strings" "strings"
"time" "time"
@ -17,6 +19,7 @@ import (
"github.com/pusher/oauth2_proxy/pkg/apis/sessions" "github.com/pusher/oauth2_proxy/pkg/apis/sessions"
"github.com/pusher/oauth2_proxy/pkg/cookies" "github.com/pusher/oauth2_proxy/pkg/cookies"
"github.com/pusher/oauth2_proxy/pkg/encryption" "github.com/pusher/oauth2_proxy/pkg/encryption"
"github.com/pusher/oauth2_proxy/pkg/logger"
) )
// TicketData is a structure representing the ticket used in server session storage // TicketData is a structure representing the ticket used in server session storage
@ -64,6 +67,31 @@ func newRedisClient(opts options.RedisStoreOptions) (*redis.Client, error) {
return nil, fmt.Errorf("unable to parse redis url: %s", err) return nil, fmt.Errorf("unable to parse redis url: %s", err)
} }
if opts.RedisInsecureTLS != false {
opt.TLSConfig.InsecureSkipVerify = true
}
if opts.RedisCAPath != "" {
rootCAs, err := x509.SystemCertPool()
if err != nil {
logger.Printf("failed to load system cert pool for redis connection, falling back to empty cert pool")
}
if rootCAs == nil {
rootCAs = x509.NewCertPool()
}
certs, err := ioutil.ReadFile(opts.RedisCAPath)
if err != nil {
return nil, fmt.Errorf("failed to load %q, %v", opts.RedisCAPath, err)
}
// Append our cert to the system pool
if ok := rootCAs.AppendCertsFromPEM(certs); !ok {
logger.Printf("no certs appended, using system certs only")
}
opt.TLSConfig.RootCAs = rootCAs
}
client := redis.NewClient(opt) client := redis.NewClient(opt)
return client, nil return client, nil
} }