saml-auth
The saml-auth plugin enables API7 to act as the service provider (SP) and authenticate users via SAML 2.0 by interacting with identity providers (IdP).
Example
Integrate with Keycloak
The following example assumes you have installed API7 Enterprise locally and demonstrates how you can set up SAML single sign-on (SSO) with Keycloak.
Start a Keycloak Server
Start a Keycloak instance with admin username admin and admin password admin-pass:
- Docker
- Kubernetes
docker run -d --name keycloak \
-e 'KEYCLOAK_ADMIN=admin' \
-e 'KEYCLOAK_ADMIN_PASSWORD=admin-pass' \
-p 8080:8080 \
quay.io/keycloak/keycloak:25.0.4 start-dev
Once started, visit http://localhost:8080 in your browser to access the Keycloak admin console. Log in with the admin username and password.
Create a Kubernetes manifest file for the Keycloak deployment and service:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: aic
name: keycloak
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:25.0.4
args:
- start-dev
env:
- name: KEYCLOAK_ADMIN
value: admin
- name: KEYCLOAK_ADMIN_PASSWORD
value: admin-pass
- name: KC_HTTP_PORT
value: "8080"
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: keycloak
spec:
selector:
app: keycloak
ports:
- port: 8080
targetPort: 8080
type: ClusterIP
Apply the manifest:
kubectl apply -f keycloak.yaml
Wait for the pod to be ready. Once ready, forward the Keycloak port to your local machine so you can access the admin console and so that the browser can reach the IdP during the SAML flow:
kubectl port-forward -n aic service/keycloak 8080:8080 &
Once the port-forward is active, visit http://localhost:8080 in your browser to access the Keycloak admin console. Log in with the admin username and password.
Create a Client
Create a new client in Keycloak and configure the following:
- Configure the Client type as
SAML. - Enter the service provider's (SP) name as the Client ID, for example,
api7.- Note that this value should be consistent with the
sp_issuerparameter value, which you will configure later in the plugin.
- Note that this value should be consistent with the
- Add
http://127.0.0.1:9080/anything/login_callbackto Valid redirect URIs. - Add
http://127.0.0.1:9080/anything/logout_callbackto Valid post logout redirect URIs. - Set Force POST binding option to
Off. - Make sure the Sign documents option is
On. Otherwise,SigAlgandSignaturewill be missing from the SAML response.
Find the Realm's SAML Metadata
In this step, you will find the idp_cert and idp_uri from the realm's SAML metadata file.
Select Realm Settings and under the General tab, you should find SAML 2.0 Identity Provider Metadata in Endpoints. The metadata file should look similar to the following:
<md:EntityDescriptor
xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="http://localhost:8080/realms/master">
<md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:KeyName>wDDsXcgLGAZwZgpSb_jlBRf5MF8FoTcOYs0DgZ30Xcc</ds:KeyName>
<ds:X509Data>
<ds:X509Certificate>MIICmzCCAYMCBgGRl7njKjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMjQwODI4MDY0MjA3WhcNMzQwODI4MDY0MzQ3WjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdYPYSFoX2MADSIgfLYQ5oZcLNE+qB+qsO8sNpiebMQE3RmI5+MmZC/aozRzkzxcY+AoM50qfHrM1yM99A9ZxZt6fW/MuIv6IP5zWLDl0XWGVeOH0HIH4/xBxQetBxm1HdOYpCQg5Wm9hmYfebmN7NfW8HjnORjfUuUGgs5eCiHVqfiCfphLF5w+DcIcnjIwyF+xVH/7fRWgo5inBSeIavZh/LEv7LzBeRleGgoZ/+q7cVQiL2e0b8rsslqUOZJmwdPU3VSS0vW1bmXsZsfaZD0bgakFvSj0ARzwIbxc74eEQYKflHGS0zkrpm+TsO5KUn59SCPOhGNgGYpKKv6cY1AgMBAAEwDQYJKoZIhvcNAQELBQADggEBABN21PoEiTaZ20qQUdKD03m+bySlF4jRX2AeZqCedBaW+nHrbefaJdEnE9AcXBENCWVr6ntdeREaL9dW6KpV1hT4BmnXO2aiFotZe4Vc2W6cv7nDpjil6Q5/isbT5sriYhcU9oXBAaLf9dlg7K/X1l1+zcy9Pd1uKUfrC+5ds/Zv+xHiiK4h55o8shcmBmQ7bsanzNmjIQNnyF+lNRciGRvgJp59TR7AWpiBQDTNW1KK3XjO9lmN8nCEPbpdNGi77TDX0OZVrbbPy3vL4n8Gi3oQptHhmV7xou4fTEn9TCrdW82OLOduBCMk9t0tFFNB8Hlxq5XsLVLYW7O9GGcjDmI=</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:ArtifactResolutionService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/realms/master/protocol/saml/resolve" index="0"></md:ArtifactResolutionService>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/realms/master/protocol/saml"></md:SingleLogoutService>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8080/realms/master/protocol/saml"></md:SingleLogoutService>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://localhost:8080/realms/master/protocol/saml"></md:SingleLogoutService>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/realms/master/protocol/saml"></md:SingleLogoutService>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:8080/realms/master/protocol/saml"></md:SingleSignOnService>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8080/realms/master/protocol/saml"></md:SingleSignOnService>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://localhost:8080/realms/master/protocol/saml"></md:SingleSignOnService>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="http://localhost:8080/realms/master/protocol/saml"></md:SingleSignOnService>
</md:IDPSSODescriptor>
</md:EntityDescriptor>
Note down the certificate content in X509Certificate for plugin configuration idp_cert.
The SingleSignOnService.Location URL will also be used in the idp_uri plugin configuration later, where the localhost should be replace with your private IP address. For example, the idp_uri would look similar to http://192.168.2.101:8080/realms/master/protocol/saml.
Create Service Provider (SP) Certificate and Key
There are two approaches to create the service provider's certificate and key, and configure the certificate in Keycloak:
- Generate the certificate and private key locally using openssl, and import the certificate to Keycloak client; or
- Generate the certificate and private key in Keycloak, which automatically configures the certificate in Keycloak. You will save the certificate and private key for plugin configuration later in API7.
With the first approach, generate the certificate and private key using the openssl utility:
# Generate Private Key
openssl genrsa -out sp_private_key.pem 2048
# Generate Certificate Signing Request (CSR)
openssl req -new -key sp_private_key.pem -out sp_csr.pem -subj "/CN=API7"
# Generate Self-Signed Certificate
openssl x509 -req -days 365 -in sp_csr.pem -signkey sp_private_key.pem -out sp_cert.pem
In Keycloak, go to the client, and under Keys tab where you see the Client signature required option is set on On, you should see an option to Import Key for the Certificate. Choose Certificate PEM as the Archive format and import sp_cert.pem.
Alternatively if you wish to use the second approach, to generate the certificate and key in Keycloak, you can click Regenerate under Certificate. This will update the certificate configured in the client and download the private key to your host.
Create a Route with saml-auth Plugin
Replace the secret, idp_uri IP address, idp_cert, sp_cert, and sp_private_key with your own values.
- Admin API
- ADC
- Ingress Controller
Create a route with the saml-auth plugin:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "saml-auth-route",
"uri": "/anything/*",
"plugins": {
"saml-auth": {
"secret": "my_secret_key",
"sp_issuer": "api7",
"idp_uri": "http://192.168.2.101:8080/realms/master/protocol/saml",
"login_callback_uri": "/anything/login_callback",
"logout_callback_uri": "/anything/logout_callback",
"logout_uri": "/anything/logout",
"logout_redirect_uri": "/anything/logout_ok",
"idp_cert": "-----BEGIN CERTIFICATE-----\nMIICmzCCAYMCBgGRl7njKjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0\nZXIwHhcNMjQwODI4MDY0MjA3WhcNMzQwODI4MDY0MzQ3WjARMQ8wDQYDVQQDDAZt\nYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdYPYSFoX2MADS\nIgfLYQ5oZcLNE+qB+qsO8sNpiebMQE3RmI5+MmZC/aozRzkzxcY+AoM50qfHrM1y\nM99A9ZxZt6fW/MuIv6IP5zWLDl0XWGVeOH0HIH4/xBxQetBxm1HdOYpCQg5Wm9hm\nYfebmN7NfW8HjnORjfUuUGgs5eCiHVqfiCfphLF5w+DcIcnjIwyF+xVH/7fRWgo5\ninBSeIavZh/LEv7LzBeRleGgoZ/+q7cVQiL2e0b8rsslqUOZJmwdPU3VSS0vW1bm\nXsZsfaZD0bgakFvSj0ARzwIbxc74eEQYKflHGS0zkrpm+TsO5KUn59SCPOhGNgGY\npKKv6cY1AgMBAAEwDQYJKoZIhvcNAQELBQADggEBABN21PoEiTaZ20qQUdKD03m+\nbySlF4jRX2AeZqCedBaW+nHrbefaJdEnE9AcXBENCWVr6ntdeREaL9dW6KpV1hT4\nBmnXO2aiFotZe4Vc2W6cv7nDpjil6Q5/isbT5sriYhcU9oXBAaLf9dlg7K/X1l1+\nzcy9Pd1uKUfrC+5ds/Zv+xHiiK4h55o8shcmBmQ7bsanzNmjIQNnyF+lNRciGRvg\nJp59TR7AWpiBQDTNW1KK3XjO9lmN8nCEPbpdNGi77TDX0OZVrbbPy3vL4n8Gi3oQ\nptHhmV7xou4fTEn9TCrdW82OLOduBCMk9t0tFFNB8Hlxq5XsLVLYW7O9GGcjDmI=\n-----END CERTIFICATE-----",
"sp_cert": "-----BEGIN CERTIFICATE-----\nMIIC0TCCAbmgAwIBAgIUAT7h3zLAul/3S1F9Ms9w7JjpoJ0wDQYJKoZIhvcNAQEL\nBQAwETEPMA0GA1UEAwwGQVBJU0lYMB4XDTI0MDgyNzA5MDk1NloXDTI1MDgyNzA5\nMDk1NlowETEPMA0GA1UEAwwGQVBJU0lYMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAvJBsuNfgvxe+xrBPr9+OCwD4dk3M9ua+14l9tlQHFgtqGXEq7nYc\n0ic9wqim+kdxpJWfiwG0mClklO0nELNsgBVrC06FqrcSe2CGEh91UBkGEOzvOgm7\nEBJOB/5Nc4tE/3NXM0ocfRgFXNEvGMkH9M+odGk7ZQraI/hfazwYgjOty1LrvSMp\nKhCfx0DpKlLuX0w2P9CfLuSgZ0ZTdN3Yr4icEuEs0i3ptCd/bip2fccKkRWEguIe\nywoDl/2fjubJFc5sFhl7Rtf+CeFKgqeByNPX2+UCix136L1r+VIlA+3ClInPWZUY\nWCbs/envBO6omUsnqPPCU2zVdYW0Qb+rrQIDAQABoyEwHzAdBgNVHQ4EFgQUvGIj\nuvPoHC74lhKSlOJAwrdq4WwwDQYJKoZIhvcNAQELBQADggEBAJU0+aKCUSYvN6oe\n7PHYD0ZvE13wItzKq/7DQQe1zA/kDoCvSyC8+gB+FZmdHmkGGNdNqXsQgHEnP7Y0\nx7gDqA3s0blXEkECfmmRcVxcS3rb8CVVFqiKdyRO91opdir5J9vbmiF7RK1ajFTy\nyemhK0xxFpPM+gTdetEj7AoVMrlRoOLC+L62GaSi/gpQmKPR91FLyj33vCfVrDCo\nQXYMPQmSbBCwlHrHWa/Px7F7aQ3fuwmY6jgObxewl3HUSCfV1TT4/uYV9GsrVx4p\np9LcyuVBuJroIlCJrk5Q/ozGhuiRoKApaTeUSjy5opziBRC2bF+TIxbO9Mkibtbh\nxvXZ4WE=\n-----END CERTIFICATE-----",
"sp_private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC8kGy41+C/F77G\nsE+v344LAPh2Tcz25r7XiX22VAcWC2oZcSrudhzSJz3CqKb6R3GklZ+LAbSYKWSU\n7ScQs2yAFWsLToWqtxJ7YIYSH3VQGQYQ7O86CbsQEk4H/k1zi0T/c1czShx9GAVc\n0S8YyQf0z6h0aTtlCtoj+F9rPBiCM63LUuu9IykqEJ/HQOkqUu5fTDY/0J8u5KBn\nRlN03diviJwS4SzSLem0J39uKnZ9xwqRFYSC4h7LCgOX/Z+O5skVzmwWGXtG1/4J\n4UqCp4HI09fb5QKLHXfovWv5UiUD7cKUic9ZlRhYJuz96e8E7qiZSyeo88JTbNV1\nhbRBv6utAgMBAAECggEAFPBeulnykZXD8BFVD/0dq1gkvxJdn884wvt4E76Z+Nc0\npXWdJFTGV4nXAF41CJbVZkbdLBT45mq2ShlZnK+n7UMzm1JRYocozL2Htcx7fPUC\naO++ku3QsXSu6JFTLXD6LPm0ZbQlnLiFo+xws+pi8Ur79E1ZNJuzZIooomJOgGqm\nz/0aTCw1JbMXAI7x0ygCYarfhqX4/M6qokV0Nt64hHxHxtrIWzVac+1QdR4WLaFL\nbdrb6QQeeCw5rWUrZfqmF6+NwCCeP5k/HMeVSwXsI+WrEVCjQBB2qpFqgiDNyfz2\n2i7UYXBP0PUmHEPsctWCYlWwqskBxLZnJdDKTmBCKwKBgQDpXpUpNgaI1LOrhxEQ\n5v1iXDSJweV8Kcdth+e6IGFLtxBgvhDNCijBhwKaFe90SFRldGQgZrz4tBKcxdEw\nslGbbNSSmVZ7nSMpZQoV74Uyrk2i7vxq6A9+ZCMWFpFIwoFBz4SUpnwEe+TEe/l3\nAMOz8BdFa3J0XzUhL7k5X+KaewKBgQDO2Yvi84JhwcmgRzlhv5o6gD40C5x1dv5w\nRqnXxnZGigVwtSBS6CoayBtL8MYNdTB5oM6qoF/FiVHYxbnwgD3d4net/BbUYz9H\nkONxwuEM0a35uSf2FHCaRn7BDPjmbdNmrkWr0bHyjlNAd1CQiwmeLxnaTwjf3C+M\nTdI+p08t9wKBgDms84Zk4MaOcv0we2pG/FaD3UQylInUNYJ/dSjN+d3hl32hW7uh\nCCOUP3NfenetrJYKZviPC6MXtgXi6el0GLEl+39jwDj6xAbl/tEfCjdVVsCu+dle\nEv40t2stFqj50UI3jFfEsZ/WEtrwnN3pZXSiIM46WOYj5ZiXF9rzNKjjAoGBAJcv\nwKPf8fM7rgA9Lr64SaTqqQxnVDMzByPPMkKpJzfFl9ZaPMb8NBIhInpuAIRDnGu5\n0nQ6BeYeyTjUxGP5h76O0YTUVWdlJxJK30L9+nnhI/T7lS6yn97TGcBGmAHsUfCh\n/gBoo1SzHDxpOPR8+0moCZBb5hOhHwvAsaPjq+bfAoGBALV/t+smBLogJOBXpfKU\n9LCXnnIqG804vyobSNCVoJm832gBTM7fVcTZa5I+0O+l1emEETIgKU+5ioP/qwou\nU3a/7jXX4hewCpmPVhvvlHgjs+UOBS6hXQMnq52h6mPhiikGOQ6YnqHtxyFORIlo\ntUlwMjanVlxRKyGJlBYQtADk\n-----END PRIVATE KEY-----"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
Create a route with the saml-auth plugin:
services:
- name: saml-auth-service
routes:
- name: saml-auth-route
uris:
- /anything/*
plugins:
saml-auth:
secret: my_secret_key
sp_issuer: api7
idp_uri: "http://192.168.2.101:8080/realms/master/protocol/saml"
login_callback_uri: /anything/login_callback
logout_callback_uri: /anything/logout_callback
logout_uri: /anything/logout
logout_redirect_uri: /anything/logout_ok
idp_cert: "-----BEGIN CERTIFICATE-----\nMIICmzCCAYMCBgGRl7njKjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0\nZXIwHhcNMjQwODI4MDY0MjA3WhcNMzQwODI4MDY0MzQ3WjARMQ8wDQYDVQQDDAZt\nYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdYPYSFoX2MADS\nIgfLYQ5oZcLNE+qB+qsO8sNpiebMQE3RmI5+MmZC/aozRzkzxcY+AoM50qfHrM1y\nM99A9ZxZt6fW/MuIv6IP5zWLDl0XWGVeOH0HIH4/xBxQetBxm1HdOYpCQg5Wm9hm\nYfebmN7NfW8HjnORjfUuUGgs5eCiHVqfiCfphLF5w+DcIcnjIwyF+xVH/7fRWgo5\ninBSeIavZh/LEv7LzBeRleGgoZ/+q7cVQiL2e0b8rsslqUOZJmwdPU3VSS0vW1bm\nXsZsfaZD0bgakFvSj0ARzwIbxc74eEQYKflHGS0zkrpm+TsO5KUn59SCPOhGNgGY\npKKv6cY1AgMBAAEwDQYJKoZIhvcNAQELBQADggEBABN21PoEiTaZ20qQUdKD03m+\nbySlF4jRX2AeZqCedBaW+nHrbefaJdEnE9AcXBENCWVr6ntdeREaL9dW6KpV1hT4\nBmnXO2aiFotZe4Vc2W6cv7nDpjil6Q5/isbT5sriYhcU9oXBAaLf9dlg7K/X1l1+\nzcy9Pd1uKUfrC+5ds/Zv+xHiiK4h55o8shcmBmQ7bsanzNmjIQNnyF+lNRciGRvg\nJp59TR7AWpiBQDTNW1KK3XjO9lmN8nCEPbpdNGi77TDX0OZVrbbPy3vL4n8Gi3oQ\nptHhmV7xou4fTEn9TCrdW82OLOduBCMk9t0tFFNB8Hlxq5XsLVLYW7O9GGcjDmI=\n-----END CERTIFICATE-----"
sp_cert: "-----BEGIN CERTIFICATE-----\nMIIC0TCCAbmgAwIBAgIUAT7h3zLAul/3S1F9Ms9w7JjpoJ0wDQYJKoZIhvcNAQEL\nBQAwETEPMA0GA1UEAwwGQVBJU0lYMB4XDTI0MDgyNzA5MDk1NloXDTI1MDgyNzA5\nMDk1NlowETEPMA0GA1UEAwwGQVBJU0lYMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAvJBsuNfgvxe+xrBPr9+OCwD4dk3M9ua+14l9tlQHFgtqGXEq7nYc\n0ic9wqim+kdxpJWfiwG0mClklO0nELNsgBVrC06FqrcSe2CGEh91UBkGEOzvOgm7\nEBJOB/5Nc4tE/3NXM0ocfRgFXNEvGMkH9M+odGk7ZQraI/hfazwYgjOty1LrvSMp\nKhCfx0DpKlLuX0w2P9CfLuSgZ0ZTdN3Yr4icEuEs0i3ptCd/bip2fccKkRWEguIe\nywoDl/2fjubJFc5sFhl7Rtf+CeFKgqeByNPX2+UCix136L1r+VIlA+3ClInPWZUY\nWCbs/envBO6omUsnqPPCU2zVdYW0Qb+rrQIDAQABoyEwHzAdBgNVHQ4EFgQUvGIj\nuvPoHC74lhKSlOJAwrdq4WwwDQYJKoZIhvcNAQELBQADggEBAJU0+aKCUSYvN6oe\n7PHYD0ZvE13wItzKq/7DQQe1zA/kDoCvSyC8+gB+FZmdHmkGGNdNqXsQgHEnP7Y0\nx7gDqA3s0blXEkECfmmRcVxcS3rb8CVVFqiKdyRO91opdir5J9vbmiF7RK1ajFTy\nyemhK0xxFpPM+gTdetEj7AoVMrlRoOLC+L62GaSi/gpQmKPR91FLyj33vCfVrDCo\nQXYMPQmSbBCwlHrHWa/Px7F7aQ3fuwmY6jgObxewl3HUSCfV1TT4/uYV9GsrVx4p\np9LcyuVBuJroIlCJrk5Q/ozGhuiRoKApaTeUSjy5opziBRC2bF+TIxbO9Mkibtbh\nxvXZ4WE=\n-----END CERTIFICATE-----"
sp_private_key: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC8kGy41+C/F77G\nsE+v344LAPh2Tcz25r7XiX22VAcWC2oZcSrudhzSJz3CqKb6R3GklZ+LAbSYKWSU\n7ScQs2yAFWsLToWqtxJ7YIYSH3VQGQYQ7O86CbsQEk4H/k1zi0T/c1czShx9GAVc\n0S8YyQf0z6h0aTtlCtoj+F9rPBiCM63LUuu9IykqEJ/HQOkqUu5fTDY/0J8u5KBn\nRlN03diviJwS4SzSLem0J39uKnZ9xwqRFYSC4h7LCgOX/Z+O5skVzmwWGXtG1/4J\n4UqCp4HI09fb5QKLHXfovWv5UiUD7cKUic9ZlRhYJuz96e8E7qiZSyeo88JTbNV1\nhbRBv6utAgMBAAECggEAFPBeulnykZXD8BFVD/0dq1gkvxJdn884wvt4E76Z+Nc0\npXWdJFTGV4nXAF41CJbVZkbdLBT45mq2ShlZnK+n7UMzm1JRYocozL2Htcx7fPUC\naO++ku3QsXSu6JFTLXD6LPm0ZbQlnLiFo+xws+pi8Ur79E1ZNJuzZIooomJOgGqm\nz/0aTCw1JbMXAI7x0ygCYarfhqX4/M6qokV0Nt64hHxHxtrIWzVac+1QdR4WLaFL\nbdrb6QQeeCw5rWUrZfqmF6+NwCCeP5k/HMeVSwXsI+WrEVCjQBB2qpFqgiDNyfz2\n2i7UYXBP0PUmHEPsctWCYlWwqskBxLZnJdDKTmBCKwKBgQDpXpUpNgaI1LOrhxEQ\n5v1iXDSJweV8Kcdth+e6IGFLtxBgvhDNCijBhwKaFe90SFRldGQgZrz4tBKcxdEw\nslGbbNSSmVZ7nSMpZQoV74Uyrk2i7vxq6A9+ZCMWFpFIwoFBz4SUpnwEe+TEe/l3\nAMOz8BdFa3J0XzUhL7k5X+KaewKBgQDO2Yvi84JhwcmgRzlhv5o6gD40C5x1dv5w\nRqnXxnZGigVwtSBS6CoayBtL8MYNdTB5oM6qoF/FiVHYxbnwgD3d4net/BbUYz9H\nkONxwuEM0a35uSf2FHCaRn7BDPjmbdNmrkWr0bHyjlNAd1CQiwmeLxnaTwjf3C+M\nTdI+p08t9wKBgDms84Zk4MaOcv0we2pG/FaD3UQylInUNYJ/dSjN+d3hl32hW7uh\nCCOUP3NfenetrJYKZviPC6MXtgXi6el0GLEl+39jwDj6xAbl/tEfCjdVVsCu+dle\nEv40t2stFqj50UI3jFfEsZ/WEtrwnN3pZXSiIM46WOYj5ZiXF9rzNKjjAoGBAJcv\nwKPf8fM7rgA9Lr64SaTqqQxnVDMzByPPMkKpJzfFl9ZaPMb8NBIhInpuAIRDnGu5\n0nQ6BeYeyTjUxGP5h76O0YTUVWdlJxJK30L9+nnhI/T7lS6yn97TGcBGmAHsUfCh\n/gBoo1SzHDxpOPR8+0moCZBb5hOhHwvAsaPjq+bfAoGBALV/t+smBLogJOBXpfKU\n9LCXnnIqG804vyobSNCVoJm832gBTM7fVcTZa5I+0O+l1emEETIgKU+5ioP/qwou\nU3a/7jXX4hewCpmPVhvvlHgjs+UOBS6hXQMnq52h6mPhiikGOQ6YnqHtxyFORIlo\ntUlwMjanVlxRKyGJlBYQtADk\n-----END PRIVATE KEY-----"
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Synchronize the configuration to the gateway:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: saml-auth-plugin-config
spec:
plugins:
- name: saml-auth
config:
secret: my_secret_key
sp_issuer: api7
idp_uri: "http://192.168.2.101:8080/realms/master/protocol/saml"
login_callback_uri: /anything/login_callback
logout_callback_uri: /anything/logout_callback
logout_uri: /anything/logout
logout_redirect_uri: /anything/logout_ok
idp_cert: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
sp_cert: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
sp_private_key: "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: saml-auth-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: PathPrefix
value: /anything/
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: saml-auth-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
Apply the configuration to your cluster:
kubectl apply -f saml-auth-ic.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: saml-auth-route
spec:
ingressClassName: apisix
http:
- name: saml-auth-route
match:
paths:
- /anything/*
upstreams:
- name: httpbin-external-domain
plugins:
- name: saml-auth
enable: true
config:
secret: my_secret_key
sp_issuer: api7
idp_uri: "http://192.168.2.101:8080/realms/master/protocol/saml"
login_callback_uri: /anything/login_callback
logout_callback_uri: /anything/logout_callback
logout_uri: /anything/logout
logout_redirect_uri: /anything/logout_ok
idp_cert: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
sp_cert: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
sp_private_key: "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
Apply the configuration to your cluster:
kubectl apply -f saml-auth-ic.yaml
Verify
Navigate to http://127.0.0.1:9080/anything/saml-test in your browser and log in with your Keycloak credentials.
If successful, you should be redirected and see a response similar to the following in your browser:
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-CA,en-US;q=0.9,en;q=0.8",
"Cookie": "saml_session=90f84a61-cb03-4f8c-8202-5e7b5267bda6",
"Host": "127.0.0.1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15",
"X-Amzn-Trace-Id": "Root=1-66cf4d36-18bbacc80af8987b77b1f5c4",
"X-Forwarded-Host": "127.0.0.1"
},
"json": null,
"method": "GET",
"origin": "192.168.65.1, 203.91.85.123",
"url": "http://127.0.0.1/anything/saml-test"
}