-
Notifications
You must be signed in to change notification settings - Fork 134
Add document to configure Basic Auth #1634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4bb46cc
7c66f30
2168088
39d1062
a3cfbf8
f689e7e
36a8dc1
6ca5610
d8e89c0
741a6a9
d3e3a71
b29e63f
a5b553c
8998484
f00be74
b943954
86ee8c4
d5c6add
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,365 @@ | ||||||||
| --- | ||||||||
| title: Configure basic authentication | ||||||||
| weight: 800 | ||||||||
| toc: true | ||||||||
| nd-content-type: how-to | ||||||||
| nd-product: FABRIC | ||||||||
| --- | ||||||||
|
|
||||||||
|
|
||||||||
| This page describes how to configure basic authentication in NGINX Gateway Fabric using the AuthenticationFilter custom resource definition (CRD). | ||||||||
|
|
||||||||
| Authentication can be used to secure applications and APIs, ensuring only trusted and authorized users have access. | ||||||||
|
|
||||||||
| 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. | ||||||||
|
|
||||||||
| ## Before you begin | ||||||||
|
|
||||||||
| - [Install]({{< ref "/ngf/install/" >}}) NGINX Gateway Fabric. | ||||||||
|
|
||||||||
| ## Setup | ||||||||
|
|
||||||||
shaun-nx marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| In this part of the document, we will set up several resources in your cluster to demonstrate usage of the AuthenticationFilter CRD. | ||||||||
|
|
||||||||
|
Comment on lines
+20
to
+23
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
The rest of the document only deals with one level of heading/section nesting, so this is unnecessary. Adding additional edit suggestions to "pop" the remainder one level up. |
||||||||
| ## Deploy sample applications | ||||||||
|
|
||||||||
| To deploy the `coffee` and `tea` applications, run the following YAML with `kubectl apply`: | ||||||||
|
|
||||||||
salonichf5 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| ```yaml | ||||||||
| kubectl apply -f - <<EOF | ||||||||
| apiVersion: apps/v1 | ||||||||
| kind: Deployment | ||||||||
| metadata: | ||||||||
| name: coffee | ||||||||
| spec: | ||||||||
| replicas: 2 | ||||||||
| selector: | ||||||||
| matchLabels: | ||||||||
| app: coffee | ||||||||
| template: | ||||||||
| metadata: | ||||||||
| labels: | ||||||||
| app: coffee | ||||||||
| spec: | ||||||||
| containers: | ||||||||
| - name: coffee | ||||||||
| image: nginxdemos/nginx-hello:plain-text | ||||||||
| ports: | ||||||||
| - containerPort: 8080 | ||||||||
| --- | ||||||||
| apiVersion: v1 | ||||||||
| kind: Service | ||||||||
| metadata: | ||||||||
| name: coffee | ||||||||
| spec: | ||||||||
| ports: | ||||||||
| - port: 80 | ||||||||
| targetPort: 8080 | ||||||||
| protocol: TCP | ||||||||
| name: http | ||||||||
| selector: | ||||||||
| app: coffee | ||||||||
| --- | ||||||||
| apiVersion: apps/v1 | ||||||||
| kind: Deployment | ||||||||
| metadata: | ||||||||
| name: tea | ||||||||
| spec: | ||||||||
| replicas: 2 | ||||||||
| selector: | ||||||||
| matchLabels: | ||||||||
| app: tea | ||||||||
| template: | ||||||||
| metadata: | ||||||||
| labels: | ||||||||
| app: tea | ||||||||
| spec: | ||||||||
| containers: | ||||||||
| - name: tea | ||||||||
| image: nginxdemos/nginx-hello:plain-text | ||||||||
| ports: | ||||||||
| - containerPort: 8080 | ||||||||
| --- | ||||||||
| apiVersion: v1 | ||||||||
| kind: Service | ||||||||
| metadata: | ||||||||
| name: tea | ||||||||
| spec: | ||||||||
| ports: | ||||||||
| - port: 80 | ||||||||
| targetPort: 8080 | ||||||||
| protocol: TCP | ||||||||
| name: http | ||||||||
| selector: | ||||||||
| app: tea | ||||||||
| EOF | ||||||||
| ``` | ||||||||
|
|
||||||||
salonichf5 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| To confirm the application pods are availble, run `kubectl get`: | ||||||||
|
|
||||||||
| ```shell | ||||||||
| kubectl get pods | ||||||||
| ``` | ||||||||
|
|
||||||||
| ```text | ||||||||
| NAME READY STATUS RESTARTS AGE | ||||||||
| coffee-654ddf664b-fllj7 1/1 Running 0 21s | ||||||||
| coffee-654ddf664b-lpgq9 1/1 Running 0 21s | ||||||||
| tea-75bc9f4b6d-cx2jl 1/1 Running 0 21s | ||||||||
| tea-75bc9f4b6d-s99jz 1/1 Running 0 21s | ||||||||
| ``` | ||||||||
|
|
||||||||
| ### Create a Gateway | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| To create your Gateway resource and provision the NGINX pod, run the following YAML with `kubectl apply`: | ||||||||
|
|
||||||||
| ```yaml | ||||||||
| kubectl apply -f - <<EOF | ||||||||
| apiVersion: gateway.networking.k8s.io/v1 | ||||||||
| kind: Gateway | ||||||||
| metadata: | ||||||||
| name: cafe-gateway | ||||||||
| spec: | ||||||||
| gatewayClassName: nginx | ||||||||
| listeners: | ||||||||
| - name: http | ||||||||
| port: 80 | ||||||||
| protocol: HTTP | ||||||||
| hostname: "cafe.example.com" | ||||||||
| EOF | ||||||||
| ``` | ||||||||
|
|
||||||||
| Confirm the Gateway was assigned an IP address and reports a `Programmed=True` status with `kubectl describe`: | ||||||||
|
|
||||||||
| ```shell | ||||||||
| kubectl describe gateways.gateway.networking.k8s.io cafe-gateway | grep "Addresses:" -A2 | ||||||||
| ``` | ||||||||
|
|
||||||||
| ```text | ||||||||
| Addresses: | ||||||||
| Type: IPAddress | ||||||||
| Value: 10.96.20.187 | ||||||||
| ``` | ||||||||
|
|
||||||||
| Save the public IP address and port(s) of the Gateway into shell variables: | ||||||||
|
|
||||||||
| ```text | ||||||||
| GW_IP=XXX.YYY.ZZZ.III | ||||||||
| GW_PORT=<port number> | ||||||||
| ``` | ||||||||
|
|
||||||||
| ## Create a user credentials secret and AuthenticationFilter | ||||||||
|
|
||||||||
| Deploy a secret with user credentials, and the AuthenticationFilter by running the following YAML with `kubectl apply`: | ||||||||
|
|
||||||||
| {{< call-out "important" >}} Ensure the secret deployed is of type `nginx.org/htpasswd` and the key is `auth` {{< /call-out >}} | ||||||||
|
|
||||||||
| ```yaml | ||||||||
| kubectl apply -f - <<EOF | ||||||||
| apiVersion: v1 | ||||||||
| kind: Secret | ||||||||
| metadata: | ||||||||
| name: basic-auth | ||||||||
| type: nginx.org/htpasswd | ||||||||
| data: | ||||||||
| # Base64 of "htpasswd -bn user1 password1" | ||||||||
| auth: dXNlcjE6JGFwcjEkWEFKeU5yekgkY0Rjdy9YMVBCZTFmTjltQVBweXpxMA== | ||||||||
| --- | ||||||||
| apiVersion: gateway.nginx.org/v1alpha1 | ||||||||
| kind: AuthenticationFilter | ||||||||
| metadata: | ||||||||
| name: basic-auth | ||||||||
| spec: | ||||||||
| type: Basic | ||||||||
| basic: | ||||||||
| secretRef: | ||||||||
| name: basic-auth | ||||||||
| realm: "Restricted basic-auth" | ||||||||
| EOF | ||||||||
| ``` | ||||||||
|
|
||||||||
| Verify the AuthenticationFilter is _Accepted_ and has no errors using `kubectl describe`: | ||||||||
|
|
||||||||
| ```shell | ||||||||
| kubectl describe authenticationfilters.gateway.nginx.org | grep "Status:" -A10 | ||||||||
| ``` | ||||||||
|
|
||||||||
| ```text | ||||||||
| Status: | ||||||||
| Controllers: | ||||||||
| Conditions: | ||||||||
| Last Transition Time: 2026-01-08T10:09:18Z | ||||||||
| Message: The AuthenticationFilter is accepted | ||||||||
| Observed Generation: 1 | ||||||||
| Reason: Accepted | ||||||||
| Status: True | ||||||||
| Type: Accepted | ||||||||
| Controller Name: gateway.nginx.org/nginx-gateway-controller | ||||||||
| Events: <none> | ||||||||
| ``` | ||||||||
|
|
||||||||
| ## Deploy a HTTPRoute referencing the AuthenticationFilter | ||||||||
|
|
||||||||
| Deploy a HTTPRoute resource which references the AuthenticationFilter using the `ExtensionRef` filter type. | ||||||||
|
|
||||||||
| In this example, the filter is applied to the `/coffee` path: run the following YAML with `kubectl apply` | ||||||||
|
|
||||||||
| ```yaml | ||||||||
| kubectl apply -f - <<EOF | ||||||||
| apiVersion: gateway.networking.k8s.io/v1 | ||||||||
| kind: HTTPRoute | ||||||||
| metadata: | ||||||||
| name: cafe-routes | ||||||||
| spec: | ||||||||
| parentRefs: | ||||||||
| - name: cafe-gateway | ||||||||
| sectionName: http | ||||||||
| hostnames: | ||||||||
| - "cafe.example.com" | ||||||||
| rules: | ||||||||
| - matches: | ||||||||
| - path: | ||||||||
| type: PathPrefix | ||||||||
| value: /coffee | ||||||||
| backendRefs: | ||||||||
| - name: coffee | ||||||||
| port: 80 | ||||||||
| filters: | ||||||||
| - type: ExtensionRef | ||||||||
| extensionRef: | ||||||||
| group: gateway.nginx.org | ||||||||
| kind: AuthenticationFilter | ||||||||
| name: basic-auth | ||||||||
| - matches: | ||||||||
| - path: | ||||||||
| type: PathPrefix | ||||||||
| value: /tea | ||||||||
| backendRefs: | ||||||||
| - name: tea | ||||||||
| port: 80 | ||||||||
| EOF | ||||||||
| ``` | ||||||||
|
|
||||||||
| Verify the HTTPRoute is _Accepted_ and there are no errors with `kubectl describe`: | ||||||||
|
|
||||||||
| ```shell | ||||||||
| kubectl describe httproute cafe-routes | grep "Status:" -A10 | ||||||||
| ``` | ||||||||
|
|
||||||||
| ```text | ||||||||
| Status: | ||||||||
| Parents: | ||||||||
| Conditions: | ||||||||
| Last Transition Time: 2026-01-06T15:18:55Z | ||||||||
| Message: The Route is accepted | ||||||||
| Observed Generation: 1 | ||||||||
| Reason: Accepted | ||||||||
| Status: True | ||||||||
| Type: Accepted | ||||||||
| Last Transition Time: 2026-01-06T15:18:55Z | ||||||||
| Message: All references are resolved | ||||||||
| Observed Generation: 1 | ||||||||
| Reason: ResolvedRefs | ||||||||
| Status: True | ||||||||
| Type: ResolvedRefs | ||||||||
| Controller Name: gateway.nginx.org/nginx-gateway-controller | ||||||||
| Parent Ref: | ||||||||
| Group: gateway.networking.k8s.io | ||||||||
| Kind: Gateway | ||||||||
| Name: cafe-gateway | ||||||||
| Namespace: default | ||||||||
| Section Name: http | ||||||||
| Events: <none> | ||||||||
| ``` | ||||||||
|
|
||||||||
| ## Verify Basic Authentication | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| {{< call-out "note" >}} | ||||||||
|
|
||||||||
| Your clients should be able to resolve the domain name "cafe.example.com" to the public IP of the NGINX Service. | ||||||||
|
|
||||||||
| This guide simulates it using curl's `--resolve` option. | ||||||||
|
|
||||||||
| {{< /call-out >}} | ||||||||
|
|
||||||||
| Accessing `/coffee` with valid credentials: | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| ```shell | ||||||||
| curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee -u user1:password1 | ||||||||
| ``` | ||||||||
|
|
||||||||
| Response: | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| ```text | ||||||||
| Server address: 10.244.0.7:8080 | ||||||||
| Server name: coffee-654ddf664b-nhhvr | ||||||||
| Date: 06/Jan/2026:15:20:15 +0000 | ||||||||
| URI: /coffee | ||||||||
| Request ID: 13a925b2514b62c45ea4a79800248d5c | ||||||||
| ``` | ||||||||
|
|
||||||||
| Accessing `/coffee` without credentials: | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| ```shell | ||||||||
| curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee | ||||||||
| ``` | ||||||||
|
|
||||||||
| Response: | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| ```text | ||||||||
| <html> | ||||||||
| <head><title>401 Authorization Required</title></head> | ||||||||
| <body> | ||||||||
| <center><h1>401 Authorization Required</h1></center> | ||||||||
| <hr><center>nginx</center> | ||||||||
| </body> | ||||||||
| </html> | ||||||||
| ``` | ||||||||
|
|
||||||||
| Accessing `/coffee` with incorrect credentials: | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| ```shell | ||||||||
| curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee -u user1:wrong | ||||||||
| ``` | ||||||||
|
|
||||||||
| Response: | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| ```text | ||||||||
| <html> | ||||||||
| <head><title>401 Authorization Required</title></head> | ||||||||
| <body> | ||||||||
| <center><h1>401 Authorization Required</h1></center> | ||||||||
| <hr><center>nginx</center> | ||||||||
| </body> | ||||||||
| </html> | ||||||||
| ``` | ||||||||
|
|
||||||||
| Accessing `/tea` | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| Since tea has no AuthenticationFilter attached, responses are processed normally: | ||||||||
|
|
||||||||
| ```shell | ||||||||
| curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/tea | ||||||||
| ``` | ||||||||
|
|
||||||||
| Response: | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| ```text | ||||||||
| Server address: 10.244.0.10:8080 | ||||||||
| Server name: tea-75bc9f4b6d-ms2n8 | ||||||||
| Date: 06/Jan/2026:15:36:26 +0000 | ||||||||
| URI: /tea | ||||||||
| Request ID: c7eb0509303de1c160cb7e7d2ac1d99f | ||||||||
| ``` | ||||||||
|
|
||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| ## Troubleshooting | ||||||||
|
|
||||||||
| - Ensure the HTTPRoute is Accepted and references the correct AuthenticationFilter name and group. | ||||||||
| - Confirm the secret key is named `auth` and is of type `nginx.org/htpasswd`. | ||||||||
| - Ensure the secret referenced by the AuthenticationFilter is in the same namespace. | ||||||||
|
|
||||||||
salonichf5 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| ## Further reading | ||||||||
|
|
||||||||
| - [Example deployment files for AuthenticationFilter](https://github.com/nginx/nginx-gateway-fabric/tree/main/examples/basic-authentication) | ||||||||
| - [NGINX HTTP Basic Auth Module](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html) | ||||||||
Uh oh!
There was an error while loading. Please reload this page.