Skip to content

Commit 824f2ec

Browse files
authored
Add document to configure Basic Auth (#1634)
1 parent 618f60f commit 824f2ec

File tree

1 file changed

+365
-0
lines changed

1 file changed

+365
-0
lines changed
Lines changed: 365 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,365 @@
1+
---
2+
title: Configure basic authentication
3+
weight: 800
4+
toc: true
5+
nd-content-type: how-to
6+
nd-product: FABRIC
7+
---
8+
9+
10+
This page describes how to configure basic authentication in NGINX Gateway Fabric using the AuthenticationFilter custom resource definition (CRD).
11+
12+
Authentication can be used to secure applications and APIs, ensuring only trusted and authorized users have access.
13+
14+
By following these instructions, you will create two sample application endpoints. One will include basic authentication and the other will not, allowing you to review how each behaves.
15+
16+
## Before you begin
17+
18+
- [Install]({{< ref "/ngf/install/" >}}) NGINX Gateway Fabric.
19+
20+
## Setup
21+
22+
In this part of the document, we will set up several resources in your cluster to demonstrate usage of the AuthenticationFilter CRD.
23+
24+
## Deploy sample applications
25+
26+
To deploy the `coffee` and `tea` applications, run the following YAML with `kubectl apply`:
27+
28+
```yaml
29+
kubectl apply -f - <<EOF
30+
apiVersion: apps/v1
31+
kind: Deployment
32+
metadata:
33+
name: coffee
34+
spec:
35+
replicas: 2
36+
selector:
37+
matchLabels:
38+
app: coffee
39+
template:
40+
metadata:
41+
labels:
42+
app: coffee
43+
spec:
44+
containers:
45+
- name: coffee
46+
image: nginxdemos/nginx-hello:plain-text
47+
ports:
48+
- containerPort: 8080
49+
---
50+
apiVersion: v1
51+
kind: Service
52+
metadata:
53+
name: coffee
54+
spec:
55+
ports:
56+
- port: 80
57+
targetPort: 8080
58+
protocol: TCP
59+
name: http
60+
selector:
61+
app: coffee
62+
---
63+
apiVersion: apps/v1
64+
kind: Deployment
65+
metadata:
66+
name: tea
67+
spec:
68+
replicas: 2
69+
selector:
70+
matchLabels:
71+
app: tea
72+
template:
73+
metadata:
74+
labels:
75+
app: tea
76+
spec:
77+
containers:
78+
- name: tea
79+
image: nginxdemos/nginx-hello:plain-text
80+
ports:
81+
- containerPort: 8080
82+
---
83+
apiVersion: v1
84+
kind: Service
85+
metadata:
86+
name: tea
87+
spec:
88+
ports:
89+
- port: 80
90+
targetPort: 8080
91+
protocol: TCP
92+
name: http
93+
selector:
94+
app: tea
95+
EOF
96+
```
97+
98+
To confirm the application pods are availble, run `kubectl get`:
99+
100+
```shell
101+
kubectl get pods
102+
```
103+
104+
```text
105+
NAME READY STATUS RESTARTS AGE
106+
coffee-654ddf664b-fllj7 1/1 Running 0 21s
107+
coffee-654ddf664b-lpgq9 1/1 Running 0 21s
108+
tea-75bc9f4b6d-cx2jl 1/1 Running 0 21s
109+
tea-75bc9f4b6d-s99jz 1/1 Running 0 21s
110+
```
111+
112+
### Create a Gateway
113+
114+
To create your Gateway resource and provision the NGINX pod, run the following YAML with `kubectl apply`:
115+
116+
```yaml
117+
kubectl apply -f - <<EOF
118+
apiVersion: gateway.networking.k8s.io/v1
119+
kind: Gateway
120+
metadata:
121+
name: cafe-gateway
122+
spec:
123+
gatewayClassName: nginx
124+
listeners:
125+
- name: http
126+
port: 80
127+
protocol: HTTP
128+
hostname: "cafe.example.com"
129+
EOF
130+
```
131+
132+
Confirm the Gateway was assigned an IP address and reports a `Programmed=True` status with `kubectl describe`:
133+
134+
```shell
135+
kubectl describe gateways.gateway.networking.k8s.io cafe-gateway | grep "Addresses:" -A2
136+
```
137+
138+
```text
139+
Addresses:
140+
Type: IPAddress
141+
Value: 10.96.20.187
142+
```
143+
144+
Save the public IP address and port(s) of the Gateway into shell variables:
145+
146+
```text
147+
GW_IP=XXX.YYY.ZZZ.III
148+
GW_PORT=<port number>
149+
```
150+
151+
## Create a user credentials secret and AuthenticationFilter
152+
153+
Deploy a secret with user credentials, and the AuthenticationFilter by running the following YAML with `kubectl apply`:
154+
155+
{{< call-out "important" >}} Ensure the secret deployed is of type `nginx.org/htpasswd` and the key is `auth` {{< /call-out >}}
156+
157+
```yaml
158+
kubectl apply -f - <<EOF
159+
apiVersion: v1
160+
kind: Secret
161+
metadata:
162+
name: basic-auth
163+
type: nginx.org/htpasswd
164+
data:
165+
# Base64 of "htpasswd -bn user1 password1"
166+
auth: dXNlcjE6JGFwcjEkWEFKeU5yekgkY0Rjdy9YMVBCZTFmTjltQVBweXpxMA==
167+
---
168+
apiVersion: gateway.nginx.org/v1alpha1
169+
kind: AuthenticationFilter
170+
metadata:
171+
name: basic-auth
172+
spec:
173+
type: Basic
174+
basic:
175+
secretRef:
176+
name: basic-auth
177+
realm: "Restricted basic-auth"
178+
EOF
179+
```
180+
181+
Verify the AuthenticationFilter is _Accepted_ and has no errors using `kubectl describe`:
182+
183+
```shell
184+
kubectl describe authenticationfilters.gateway.nginx.org | grep "Status:" -A10
185+
```
186+
187+
```text
188+
Status:
189+
Controllers:
190+
Conditions:
191+
Last Transition Time: 2026-01-08T10:09:18Z
192+
Message: The AuthenticationFilter is accepted
193+
Observed Generation: 1
194+
Reason: Accepted
195+
Status: True
196+
Type: Accepted
197+
Controller Name: gateway.nginx.org/nginx-gateway-controller
198+
Events: <none>
199+
```
200+
201+
## Deploy a HTTPRoute referencing the AuthenticationFilter
202+
203+
Deploy a HTTPRoute resource which references the AuthenticationFilter using the `ExtensionRef` filter type.
204+
205+
In this example, the filter is applied to the `/coffee` path: run the following YAML with `kubectl apply`
206+
207+
```yaml
208+
kubectl apply -f - <<EOF
209+
apiVersion: gateway.networking.k8s.io/v1
210+
kind: HTTPRoute
211+
metadata:
212+
name: cafe-routes
213+
spec:
214+
parentRefs:
215+
- name: cafe-gateway
216+
sectionName: http
217+
hostnames:
218+
- "cafe.example.com"
219+
rules:
220+
- matches:
221+
- path:
222+
type: PathPrefix
223+
value: /coffee
224+
backendRefs:
225+
- name: coffee
226+
port: 80
227+
filters:
228+
- type: ExtensionRef
229+
extensionRef:
230+
group: gateway.nginx.org
231+
kind: AuthenticationFilter
232+
name: basic-auth
233+
- matches:
234+
- path:
235+
type: PathPrefix
236+
value: /tea
237+
backendRefs:
238+
- name: tea
239+
port: 80
240+
EOF
241+
```
242+
243+
Verify the HTTPRoute is _Accepted_ and there are no errors with `kubectl describe`:
244+
245+
```shell
246+
kubectl describe httproute cafe-routes | grep "Status:" -A10
247+
```
248+
249+
```text
250+
Status:
251+
Parents:
252+
Conditions:
253+
Last Transition Time: 2026-01-06T15:18:55Z
254+
Message: The Route is accepted
255+
Observed Generation: 1
256+
Reason: Accepted
257+
Status: True
258+
Type: Accepted
259+
Last Transition Time: 2026-01-06T15:18:55Z
260+
Message: All references are resolved
261+
Observed Generation: 1
262+
Reason: ResolvedRefs
263+
Status: True
264+
Type: ResolvedRefs
265+
Controller Name: gateway.nginx.org/nginx-gateway-controller
266+
Parent Ref:
267+
Group: gateway.networking.k8s.io
268+
Kind: Gateway
269+
Name: cafe-gateway
270+
Namespace: default
271+
Section Name: http
272+
Events: <none>
273+
```
274+
275+
## Verify Basic Authentication
276+
277+
{{< call-out "note" >}}
278+
279+
Your clients should be able to resolve the domain name "cafe.example.com" to the public IP of the NGINX Service.
280+
281+
This guide simulates it using curl's `--resolve` option.
282+
283+
{{< /call-out >}}
284+
285+
Accessing `/coffee` with valid credentials:
286+
287+
```shell
288+
curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee -u user1:password1
289+
```
290+
291+
Response:
292+
293+
```text
294+
Server address: 10.244.0.7:8080
295+
Server name: coffee-654ddf664b-nhhvr
296+
Date: 06/Jan/2026:15:20:15 +0000
297+
URI: /coffee
298+
Request ID: 13a925b2514b62c45ea4a79800248d5c
299+
```
300+
301+
Accessing `/coffee` without credentials:
302+
303+
```shell
304+
curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee
305+
```
306+
307+
Response:
308+
309+
```text
310+
<html>
311+
<head><title>401 Authorization Required</title></head>
312+
<body>
313+
<center><h1>401 Authorization Required</h1></center>
314+
<hr><center>nginx</center>
315+
</body>
316+
</html>
317+
```
318+
319+
Accessing `/coffee` with incorrect credentials:
320+
321+
```shell
322+
curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee -u user1:wrong
323+
```
324+
325+
Response:
326+
327+
```text
328+
<html>
329+
<head><title>401 Authorization Required</title></head>
330+
<body>
331+
<center><h1>401 Authorization Required</h1></center>
332+
<hr><center>nginx</center>
333+
</body>
334+
</html>
335+
```
336+
337+
Accessing `/tea`
338+
339+
Since tea has no AuthenticationFilter attached, responses are processed normally:
340+
341+
```shell
342+
curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/tea
343+
```
344+
345+
Response:
346+
347+
```text
348+
Server address: 10.244.0.10:8080
349+
Server name: tea-75bc9f4b6d-ms2n8
350+
Date: 06/Jan/2026:15:36:26 +0000
351+
URI: /tea
352+
Request ID: c7eb0509303de1c160cb7e7d2ac1d99f
353+
```
354+
355+
356+
## Troubleshooting
357+
358+
- Ensure the HTTPRoute is Accepted and references the correct AuthenticationFilter name and group.
359+
- Confirm the secret key is named `auth` and is of type `nginx.org/htpasswd`.
360+
- Ensure the secret referenced by the AuthenticationFilter is in the same namespace.
361+
362+
## Further reading
363+
364+
- [Example deployment files for AuthenticationFilter](https://github.com/nginx/nginx-gateway-fabric/tree/main/examples/basic-authentication)
365+
- [NGINX HTTP Basic Auth Module](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html)

0 commit comments

Comments
 (0)