Skip to content

Commit

Permalink
Merge pull request #6 from boxboat/f_params
Browse files Browse the repository at this point in the history
Parameterize and Add Hooks
  • Loading branch information
caleblloyd authored Aug 1, 2018
2 parents 02e3757 + 1b445fc commit 5eab599
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 35 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This repository builds a Docker Image that protects an upstream server using [Ok

### Required

- `UPSTREAM_ORIGIN` - The upstream origin to proxy authenticated requests to. Should include scheme, host, and port e.g. `http://localhost:8080`
- `PROXY_PASS` - The upstream to proxy authenticated requests to. Should include scheme, host, and port e.g. `http://localhost:8080`
- `CLIENT_ID` - The Client ID can be found on the 'General' tab of the Web application that you created earlier in the Okta Developer Console
- `CLIENT_SECRET` - The Client Secret be found on the 'General' tab of the Web application that you created earlier in the Okta Developer Console
- `ISSUER` - Issuer is the URL of the authorization server that will perform authentication. All Developer Accounts have a 'default' authorization server. The issuer is a combination of your Org URL (found in the upper right of the console home page) and /oauth2/default. For example, `https://xxxxx.oktapreview.com/oauth2/default`
Expand All @@ -22,6 +22,7 @@ This repository builds a Docker Image that protects an upstream server using [Ok
- `COOKIE_NAME` - Defaults to `okta-jwt`. The name of the cookie that holds the Authorization Token
- `INJECT_REFRESH_JS` - Defaults to `true`. Set to `false` to disable injection of JavaScript that transparently refreshes Access Tokens when they are close to expiring
- `REQUEST_TIMEOUT` - Defaults to `5`. Timeout for calling the Okta `token` endpoint to retrieve an Authorization Token
- `SSO_PATH` - Defaults to `/sso/`. Path for SSO error and refresh endpoints. Should include leading and trailing slash

## Authenticated Headers Passed to Upstream Server

Expand All @@ -32,3 +33,13 @@ This repository builds a Docker Image that protects an upstream server using [Ok
1. Build container `./docker-build.sh`
2. Set environment variables in vars.env to match your deployment
3. Run container `./docker-run.sh`

## Customize NGINX Configuration

### Adding Configuration to the `http` block

Any files added to `/etc/nginx/conf.d` will be included in the `http` block.

### Adding Configuration to the `server` block

Any content in the file `/etc/nginx/includes/default-server.conf` will be included in the default `server` block.
61 changes: 36 additions & 25 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,18 @@ import (
const sock = "/var/run/auth.sock"

type config struct {
appOrigin string //computed
clientID string //CLIENT_ID
clientSecret string //CLIENT_SECRET
cookieName string //computed
issuer string //ISSUER
loginRedirect string //LOGIN_REDIRECT_URL
oktaLoginBaseURL string //computed
oktaOrigin string //computed
requestTimeout time.Duration //Default of 5 seconds if no env set
verifier *jwtverifier.JwtVerifier
appOrigin string //computed
clientID string //CLIENT_ID
clientSecret string //CLIENT_SECRET
cookieName string //computed
issuer string //ISSUER
loginRedirectPath string //computed
loginRedirectURL string //LOGIN_REDIRECT_URL
oktaLoginBaseURL string //computed
oktaOrigin string //computed
ssoPath string //SSO_PATH
requestTimeout time.Duration //Default of 5 seconds if no env set
verifier *jwtverifier.JwtVerifier
}

type jwtResponse struct {
Expand Down Expand Up @@ -67,6 +69,13 @@ func getConfig() *config {
log.Fatalf("LOGIN_REDIRECT_URL is not a valid URL, %v", loginRedirect)
}

ssoPath := os.Getenv("SSO_PATH")
if ssoPath == "" {
ssoPath = "/sso/"
} else {
ssoPath = "/" + strings.Trim(ssoPath, "/") + "/"
}

cookieName := os.Getenv("COOKIE_NAME")
if cookieName == "" {
cookieName = "okta-jwt"
Expand Down Expand Up @@ -104,16 +113,18 @@ func getConfig() *config {
"&nonce=123"

return &config{
appOrigin: appOrigin,
clientID: clientID,
clientSecret: clientSecret,
cookieName: cookieName,
issuer: issuer,
loginRedirect: loginRedirect,
oktaLoginBaseURL: oktaLoginBaseURL,
oktaOrigin: oktaOrigin,
requestTimeout: requestTimeOutDuration,
verifier: jwtverifierSetup.New(),
appOrigin: appOrigin,
clientID: clientID,
clientSecret: clientSecret,
cookieName: cookieName,
issuer: issuer,
loginRedirectPath: loginRedirectURL.Path,
loginRedirectURL: loginRedirect,
oktaLoginBaseURL: oktaLoginBaseURL,
oktaOrigin: oktaOrigin,
requestTimeout: requestTimeOutDuration,
ssoPath: ssoPath,
verifier: jwtverifierSetup.New(),
}
}

Expand All @@ -129,22 +140,22 @@ func runServer(conf *config) {
})

//Authorization code callback
http.HandleFunc("/sso/authorization-code/callback", func(w http.ResponseWriter, r *http.Request) {
http.HandleFunc(conf.loginRedirectPath, func(w http.ResponseWriter, r *http.Request) {
callbackHandler(w, r, conf)
})

//Refresh check
http.HandleFunc("/sso/refresh/check", func(w http.ResponseWriter, r *http.Request) {
http.HandleFunc(conf.ssoPath+"refresh/check", func(w http.ResponseWriter, r *http.Request) {
refreshCheckHandler(w, r, conf)
})

//Refresh done
http.HandleFunc("/sso/refresh/done", func(w http.ResponseWriter, r *http.Request) {
http.HandleFunc(conf.ssoPath+"refresh/done", func(w http.ResponseWriter, r *http.Request) {
refreshDoneHandler(w, r, conf)
})

//Error
http.HandleFunc("/sso/error", func(w http.ResponseWriter, r *http.Request) {
http.HandleFunc(conf.ssoPath+"error", func(w http.ResponseWriter, r *http.Request) {
errorHandler(w, r, conf)
})

Expand Down Expand Up @@ -399,7 +410,7 @@ func getJWT(code string, conf *config) (string, error) {
reqBody := []byte("code=" + url.QueryEscape(code) +
"&client_id=" + url.QueryEscape(conf.clientID) +
"&client_secret=" + url.QueryEscape(conf.clientSecret) +
"&redirect_uri=" + url.QueryEscape(conf.loginRedirect) +
"&redirect_uri=" + url.QueryEscape(conf.loginRedirectURL) +
"&grant_type=authorization_code" +
"&scope=openid profile")

Expand Down
1 change: 1 addition & 0 deletions stage/etc/nginx/includes/default-server.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# change this file to add additional configuration to the default server
1 change: 1 addition & 0 deletions stage/etc/nginx/includes/refresh-js.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# placeholder; if INJECT_REFRESH_JS == true, this will be replaced
9 changes: 6 additions & 3 deletions stage/etc/nginx/templates/default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ server {
listen 80 default_server;
server_name _;

# additional configuration for default_server
include /etc/nginx/includes/default-server.conf;

# auth_request settinggs
auth_request @auth;
auth_request_set $auth_request_redirect $upstream_http_x_auth_request_redirect;
Expand Down Expand Up @@ -33,7 +36,7 @@ server {
include /etc/nginx/includes/proxy-headers.conf;
include /etc/nginx/includes/refresh-js.conf;
proxy_set_header X-Forwarded-User $auth_request_user;
proxy_pass ${UPSTREAM_ORIGIN};
proxy_pass ${PROXY_PASS};
}

# SSO redirect handler
Expand All @@ -42,9 +45,9 @@ server {
include /etc/nginx/includes/proxy-headers.conf;
proxy_pass http://auth_server;
}

# SSO refresh and error handlers
location ~* /sso/(error|refresh/(check|done))$ {
location ~* ^${SSO_PATH}(error|refresh/(check|done))$ {
auth_request off;
include /etc/nginx/includes/proxy-headers.conf;
proxy_pass http://auth_server;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
server {
listen unix:/var/run/default-server.sock;
listen unix:/var/run/example-server.sock;
server_name _;

location / {
Expand Down
20 changes: 15 additions & 5 deletions stage/usr/local/bin/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ extract_path () {
echo "$1" | sed -r 's|^https?://[^/]+([^\?]+).*$|\1|ig'
}

ensure_path () {
echo "/$1/" | sed -r 's:(^//|//$):/:ig'
}

# start okta-nginx
okta-nginx &
okta_verify_pid=$!
Expand All @@ -35,22 +39,28 @@ if [ "$okta_verify_started" = "false" ]; then
fi
echo "okta-nginx started"

# set SSO path
if [ -z "$SSO_PATH" ]; then
export SSO_PATH="/sso/"
fi
export SSO_PATH=$(ensure_path "$SSO_PATH")

# stamp out redirect-js.conf template
if [ "$INJECT_REFRESH_JS" != "false" ]; then
app_origin=$(extract_origin "$LOGIN_REDIRECT_URL")
export REFRESH_JS=$(/var/okta-nginx/refresh-minify.sh "$app_origin")
export REFRESH_JS=$(/var/okta-nginx/refresh-minify.sh "$app_origin" "$SSO_PATH")
envsubst '${REFRESH_JS}' \
< /etc/nginx/templates/refresh-js.conf \
> /etc/nginx/includes/refresh-js.conf
fi

# stamp out default.conf template
if [ -z "$UPSTREAM_ORIGIN" ]; then
export UPSTREAM_ORIGIN="http://unix:/var/run/default-server.sock"
cp /etc/nginx/templates/default-server.conf /etc/nginx/conf.d/
if [ -z "$PROXY_PASS" ]; then
export PROXY_PASS="http://unix:/var/run/example-server.sock"
cp /etc/nginx/templates/example-server.conf /etc/nginx/conf.d/
fi
export APP_REDIRECT_PATH=$(extract_path "$LOGIN_REDIRECT_URL")
envsubst '${APP_REDIRECT_PATH},${UPSTREAM_ORIGIN}' \
envsubst '${APP_REDIRECT_PATH},${PROXY_PASS},${SSO_PATH}' \
< /etc/nginx/templates/default.conf \
> /etc/nginx/conf.d/default.conf

Expand Down
2 changes: 2 additions & 0 deletions stage/var/okta-nginx/refresh-minify.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/sh
# argument $1: application origin
# argument $2: SSO path

cd $(dirname $0)

Expand All @@ -9,5 +10,6 @@ echo '<script type="text/javascript">'$(\
| sed ':a;N;$!ba;s/\n/ /g' \
| sed -r 's/\s+/ /g' \
| sed -r "s|http://localhost:8080|${1}|g" \
| sed -r "s|/sso/|${2}|g" \
| sed -r "s/'/\\\'/g"
)'</script>'
1 change: 1 addition & 0 deletions stage/var/okta-nginx/refresh.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/// all comments should start with 3 forward slashes
/// all statements should end in semicolons
/// the app origin should be referred to as http://localhost:8080
/// the sso path should be referred to as /sso/
(function(){
/// iframe variable
var i;
Expand Down

0 comments on commit 5eab599

Please sign in to comment.