Basic Auth
This feature is available in Gloo Gateway Enterprise only. If you are using the open source version of Gloo, these instructions do not work.
In certain cases - such as during testing or when releasing a new API to a small number of known users - it may be convenient to secure a Virtual Service using Basic Authentication. With this simple authentication mechanism the encoded user credentials are sent along with the request in a standard header.
To secure your Virtual Services using Basic Authentication, you first need to provide Gloo Gateway with a set of known users and
their passwords. You can then use this information to decide who is allowed to access which routes.
If a request matches a route on which Basic Authentication is configured, Gloo Gateway will verify the credentials in the
standard Authorization
header before sending the request to its destination. If the user associated with the credentials
is not explicitly allowed to access that route, Gloo Gateway will return a 401 response to the downstream client.
Be sure to check the external auth configuration overview for detailed information about how authentication is configured on Virtual Services.
Setup
This guide assumes that you have deployed Gloo to the gloo-system
namespace and that the glooctl
command line utility
is installed on your machine. glooctl
provides several convenient functions to view, manipulate, and debug Gloo resources;
in particular, it is worth mentioning the following command, which we will use each time we need to retrieve the URL of
the Gloo Gateway that is running inside your cluster:
glooctl proxy url
Let’s start by creating a Static Upstream that routes to a website; we will send requests to it during this tutorial.
apiVersion: gloo.solo.io/v1
kind: Upstream
metadata:
name: json-upstream
namespace: gloo-system
spec:
static:
hosts:
- addr: jsonplaceholder.typicode.com
port: 80
glooctl create upstream static --static-hosts jsonplaceholder.typicode.com:80 --name json-upstream
Creating a Virtual Service
Now let’s configure Gloo Gateway to route requests to the upstream we just created. To do that, we define a simple Virtual Service to match all requests that:
- contain a
Host
header with valuefoo
and - have a path that starts with
/
(this will match all requests).
Apply the following virtual service:
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: auth-tutorial
namespace: gloo-system
spec:
virtualHost:
domains:
- 'foo'
routes:
- matchers:
- prefix: /
routeAction:
single:
upstream:
name: json-upstream
namespace: gloo-system
options:
autoHostRewrite: true
Let’s send a request that matches the above route to the gateway proxy and make sure it works:
curl -H "Host: foo" $(glooctl proxy url)/posts/1
The above command should produce the following output:
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
Securing the Virtual Service
The auth configuration format shown on this page was introduced with Gloo Enterprise, release 0.20.1. If you are using an earlier version, please refer to this page to see which configuration formats are supported by each version.
As we just saw, we were able to reach the upstream without having to provide any credentials. This is because by default
Gloo Gateway allows any request on routes that do not specify authentication configuration. Let’s change this behavior.
We will update the Virtual Service so that only requests by the user user
with password password
are allowed.
Gloo Gateway expects password to be hashed and salted using the
APR1 format. Passwords in this format follow this pattern:
$apr1$SALT$HASHED_PASSWORD
To generate such a password you can use the htpasswd
utility:
htpasswd -nbm user password
Running the above command returns a string like user:$apr1$TYiryv0/$8BvzLUO9IfGPGGsPnAgSu1
, where:
TYiryv0/
is the salt and8BvzLUO9IfGPGGsPnAgSu1
is the hashed password.
Now that we have a password in the required format, let’s go ahead and create an AuthConfig
CRD with our
Basic Authentication configuration:
kubectl apply -f - <<EOF
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: basic-auth
namespace: gloo-system
spec:
configs:
- basicAuth:
apr:
users:
user:
salt: "TYiryv0/"
hashedPassword: "8BvzLUO9IfGPGGsPnAgSu1"
EOF
Once the AuthConfig
has been created, we can use it to secure our Virtual Service:
kubectl apply -f - <<EOF
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: auth-tutorial
namespace: gloo-system
spec:
virtualHost:
domains:
- 'foo'
routes:
- matchers:
- prefix: /
routeAction:
single:
upstream:
name: json-upstream
namespace: gloo-system
options:
autoHostRewrite: true
options:
extauth:
configRef:
name: basic-auth
namespace: gloo-system
EOF
In the above example we have added the configuration to the Virtual Host. Each route belonging to a Virtual Host will
inherit its AuthConfig
, unless it overwrites or disables it.
Testing denied requests
Let’s try and resend the same request we sent earlier:
curl -v -H "Host: foo" $(glooctl proxy url)/posts/1
You will see that the response now contains a 401 Unauthorized code, indicating that Gloo Gateway denied the request.
> GET /posts/1 HTTP/1.1
> Host: foo
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< www-authenticate: Basic realm=""
< date: Mon, 07 Oct 2019 13:36:58 GMT
< server: envoy
< content-length: 0
Testing authenticated requests
For a request to be allowed, it must now include the user credentials inside the expected header, which has the following format:
Authorization: basic <base64_encoded_credentials>
To encode the credentials, just run:
echo -n "user:password" | base64
This outputs dXNlcjpwYXNzd29yZA==
. Let’s include the header with this value in our request:
curl -H "Authorization: basic dXNlcjpwYXNzd29yZA==" -H "Host: foo" $(glooctl proxy url)/posts/1
We are now able to reach the upstream again!
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
Logging
If Gloo Gateway is running on kubernetes, the extauth server logs can be viewed with:
kubectl logs -n gloo-system deploy/extauth -f
If the auth config has been received successfully, you should see the log line:
"logger":"extauth","caller":"runner/run.go:179","msg":"got new config"
Extended configuration
The auth configuration format that is shown on this page was introduced with Gloo Gateway Enterprise release 1.16.0. To find the configuration format for an earlier version, see Configuration format history.
An extended configuration is available that allows use of the SHA1 hashing algorithm instead of APR.
The following configuration defines a list of users, and the salt and hashed password that they need to use to authenticate successfully. It uses APR encryption to store the credentials for the same user that was used in the previous example.
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: basic-auth
namespace: gloo-system
spec:
configs:
- basicAuth:
encryption:
apr: {}
userList:
users:
user:
salt: "TYiryv0/"
hashedPassword: "8BvzLUO9IfGPGGsPnAgSu1"
You can change the encryption algorithm for the hashed password to SHA1 as shown in the following example. In this example, the username and salt remain the same and the hashedPassword needs to be recalculated and updated.
apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
name: basic-auth
namespace: gloo-system
spec:
configs:
- basicAuth:
encryption:
sha1: {}
userList:
users:
user:
salt: "TYiryv0/"
hashedPassword: "010eb058a59f4ac5ba05639b0263cf91b4345fd6"
The same curls
should work with this config as the hashing algorithm only affects the hashed password stored on the server side.
curl -H "Authorization: basic dXNlcjpwYXNzd29yZA==" -H "Host: foo" $(glooctl proxy url)/posts/1
The hashed password is case-insensitive as the alphabetic characters represent hexadecimal digits.
When using the extended configuration, the proxy-authorization
header is also supported.
curl -H "Proxy- Authorization: basic dXNlcjpwYXNzd29yZA==" -H "Host: foo" $(glooctl proxy url)/posts/1
Summary
In this tutorial, we installed Gloo Gateway Enterprise and created an unauthenticated Virtual Service that routes requests to a
static upstream. We then created a Basic Authentication AuthConfig
object and used it to secure our Virtual Service.
We first showed how unauthenticated requests fail with a 401 Unauthorized
response, and then showed how to send
authenticated requests successfully to the upstream.
Cleanup the resources by running:
kubectl delete ac -n gloo-system basic-auth
kubectl delete vs -n gloo-system auth-tutorial
kubectl delete upstream -n gloo-system json-upstream