Merge pull request #209 from clems4ever/kube
Create configurations to run Authelia on Kubepull/219/head
commit
a1786d8108
|
@ -43,6 +43,7 @@ as 2nd factor.
|
|||
* User-defined access control per subdomain and resource.
|
||||
* Support of [basic authentication] for endpoints protected by single factor.
|
||||
* High-availability using a highly-available distributed database and KV store.
|
||||
* Compatible with Kubernetes ingress-nginx controller out of the box.
|
||||
|
||||
## Deployment
|
||||
|
||||
|
@ -66,6 +67,12 @@ own the configuration file from [config.template.yml] at the root of the repo.
|
|||
|
||||
where **/path/to/data/dir** is the directory where all user data will be stored.
|
||||
|
||||
### With Kubernetes
|
||||
|
||||
<img src="/images/kube-logo.png" width="24" align="left">
|
||||
|
||||
Please refer to the following [README](./example/kube/README.md).
|
||||
|
||||
## Getting started
|
||||
|
||||
The provided example is docker-based so that you can deploy and test it very
|
||||
|
|
|
@ -11,8 +11,8 @@ services:
|
|||
- SLAPD_ADDITIONAL_SCHEMAS=openldap
|
||||
- SLAPD_FORCE_RECONFIGURE=true
|
||||
volumes:
|
||||
- ./example/ldap/base.ldif:/etc/ldap.dist/prepopulate/base.ldif
|
||||
- ./example/ldap/access.rules:/etc/ldap.dist/prepopulate/access.rules
|
||||
- ./example/compose/ldap/base.ldif:/etc/ldap.dist/prepopulate/base.ldif
|
||||
- ./example/compose/ldap/access.rules:/etc/ldap.dist/prepopulate/access.rules
|
||||
networks:
|
||||
- example-network
|
||||
|
|
@ -3,6 +3,6 @@ services:
|
|||
nginx-authelia:
|
||||
image: nginx:alpine
|
||||
volumes:
|
||||
- ./example/nginx/authelia/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./example/compose/nginx/authelia/nginx.conf:/etc/nginx/nginx.conf
|
||||
networks:
|
||||
- example-network
|
|
@ -0,0 +1,9 @@
|
|||
version: '2'
|
||||
services:
|
||||
nginx-backend:
|
||||
image: nginx:alpine
|
||||
volumes:
|
||||
- ./example/compose/nginx/backend/html:/usr/share/nginx/html
|
||||
- ./example/compose/nginx/backend/nginx.conf:/etc/nginx/nginx.conf
|
||||
networks:
|
||||
- example-network
|
|
@ -56,7 +56,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
|
||||
You can also log off by visiting the following <a href="https://login.example.com:8080/logout?redirect=https://home.example.com:8080/">link</a>.
|
||||
You can also log off by visiting the following <a href="https://login.example.com:8080/logout?rd=https://home.example.com:8080/">link</a>.
|
||||
|
||||
<h1>List of users</h1>
|
||||
Here is the list of credentials you can log in with to test access control.<br/>
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
@ -3,8 +3,8 @@ services:
|
|||
nginx-portal:
|
||||
image: nginx:alpine
|
||||
volumes:
|
||||
- ./example/nginx/portal/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./example/nginx/portal/ssl:/etc/ssl
|
||||
- ./example/compose/nginx/portal/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./example/compose/nginx/portal/ssl:/etc/ssl
|
||||
ports:
|
||||
- "8080:443"
|
||||
networks:
|
|
@ -74,11 +74,15 @@ http {
|
|||
|
||||
location /auth_verify {
|
||||
internal;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
|
||||
proxy_pass $upstream_verify;
|
||||
}
|
||||
|
@ -96,7 +100,7 @@ http {
|
|||
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
error_page 401 =302 https://login.example.com:8080?redirect=$redirect;
|
||||
error_page 401 =302 https://login.example.com:8080?rd=$redirect;
|
||||
error_page 403 = https://login.example.com:8080/error/403;
|
||||
|
||||
proxy_pass $upstream_endpoint;
|
||||
|
@ -113,7 +117,7 @@ http {
|
|||
auth_request_set $groups $upstream_http_remote_groups;
|
||||
proxy_set_header Custom-Forwarded-Groups $groups;
|
||||
|
||||
error_page 401 =302 https://login.example.com:8080?redirect=$redirect;
|
||||
error_page 401 =302 https://login.example.com:8080?rd=$redirect;
|
||||
error_page 403 = https://login.example.com:8080/error/403;
|
||||
|
||||
proxy_pass $upstream_headers;
|
||||
|
@ -137,11 +141,15 @@ http {
|
|||
|
||||
location /auth_verify {
|
||||
internal;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
|
||||
proxy_pass $upstream_verify;
|
||||
}
|
||||
|
@ -159,7 +167,7 @@ http {
|
|||
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
error_page 401 =302 https://login.example.com:8080?redirect=$redirect;
|
||||
error_page 401 =302 https://login.example.com:8080?rd=$redirect;
|
||||
error_page 403 = https://login.example.com:8080/error/403;
|
||||
|
||||
proxy_pass $upstream_endpoint;
|
||||
|
@ -183,11 +191,15 @@ http {
|
|||
|
||||
location /auth_verify {
|
||||
internal;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
|
||||
proxy_pass $upstream_verify;
|
||||
}
|
||||
|
@ -205,7 +217,7 @@ http {
|
|||
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
error_page 401 =302 https://login.example.com:8080?redirect=$redirect;
|
||||
error_page 401 =302 https://login.example.com:8080?rd=$redirect;
|
||||
error_page 403 = https://login.example.com:8080/error/403;
|
||||
|
||||
proxy_pass $upstream_endpoint;
|
||||
|
@ -229,11 +241,15 @@ http {
|
|||
|
||||
location /auth_verify {
|
||||
internal;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
|
||||
proxy_pass $upstream_verify;
|
||||
}
|
||||
|
@ -251,7 +267,7 @@ http {
|
|||
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
error_page 401 =302 https://login.example.com:8080?redirect=$redirect;
|
||||
error_page 401 =302 https://login.example.com:8080?rd=$redirect;
|
||||
error_page 403 = https://login.example.com:8080/error/403;
|
||||
|
||||
proxy_pass $upstream_endpoint;
|
||||
|
@ -276,12 +292,18 @@ http {
|
|||
|
||||
location /auth_verify {
|
||||
internal;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_set_header Proxy-Authorization $http_authorization;
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# This header is required for basic authentication.
|
||||
proxy_set_header Proxy-Authorization $http_authorization;
|
||||
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
|
||||
proxy_pass $upstream_verify;
|
||||
}
|
||||
|
@ -299,7 +321,7 @@ http {
|
|||
|
||||
proxy_set_header Host $http_host;
|
||||
|
||||
error_page 401 =302 https://login.example.com:8080?redirect=$redirect;
|
||||
error_page 401 =302 https://login.example.com:8080?rd=$redirect;
|
||||
error_page 403 = https://login.example.com:8080/error/403;
|
||||
|
||||
proxy_pass $upstream_endpoint;
|
||||
|
@ -316,7 +338,7 @@ http {
|
|||
auth_request_set $groups $upstream_http_remote_groups;
|
||||
proxy_set_header Custom-Forwarded-Groups $groups;
|
||||
|
||||
error_page 401 =302 https://login.example.com:8080?redirect=$redirect;
|
||||
error_page 401 =302 https://login.example.com:8080?rd=$redirect;
|
||||
error_page 403 = https://login.example.com:8080/error/403;
|
||||
|
||||
proxy_pass $upstream_headers;
|
|
@ -0,0 +1,114 @@
|
|||
# Authelia on Kubernetes
|
||||
|
||||
Authelia is now available on Kube in order to protect your most critical
|
||||
applications using 2-factor authentication and Single Sign-On.
|
||||
|
||||
This example leverages [ingress-nginx](https://github.com/kubernetes/ingress-nginx)
|
||||
v0.13.0 to delegate authentications and authorizations to Authelia within
|
||||
the cluster.
|
||||
|
||||
## Getting started
|
||||
|
||||
In order to deploy Authelia on Kube, you must have a cluster at hand. If you
|
||||
don't, please follow the next section otherwise skip it and go
|
||||
to the next.
|
||||
|
||||
### Set up a Kube cluster
|
||||
|
||||
Hopefully, spawning a development cluster from scratch has become very
|
||||
easy lately with the use of **minikube**. This project creates a VM on your
|
||||
computer and start a Kube cluster inside it. It also configure a CLI called
|
||||
kubectl so that you can deploy applications in the cluster right away.
|
||||
|
||||
Basically, you need to follow the instruction from the [repository](https://github.com/kubernetes/minikube).
|
||||
It should be a matter of downloading the binary and start the cluster with
|
||||
two commands:
|
||||
|
||||
```
|
||||
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
|
||||
minikube start # you can use --vm-driver flag for selecting your hypervisor (virtualbox by default otherwise)
|
||||
```
|
||||
|
||||
After few seconds, your cluster should be working and you should be able to
|
||||
get access to the cluster by creating a proxy with
|
||||
|
||||
```
|
||||
kubectl proxy
|
||||
```
|
||||
|
||||
and visiting `http://localhost:8001/ui`
|
||||
|
||||
### Deploy Authelia
|
||||
|
||||
Once the cluster is ready and you can access it, run the following command to
|
||||
deploy Authelia:
|
||||
|
||||
```
|
||||
./bootstrap.sh
|
||||
```
|
||||
|
||||
In order to visit the test applications that have been deployed to test
|
||||
Authelia, edit your /etc/hosts and add the following lines replacing the IP
|
||||
with the IP of your VM given by minikube:
|
||||
|
||||
```
|
||||
192.168.39.26 login.kube.example.com
|
||||
192.168.39.26 app1.kube.example.com
|
||||
192.168.39.26 app2.kube.example.com
|
||||
192.168.39.26 mail.kube.example.com
|
||||
192.168.39.26 home.kube.example.com
|
||||
|
||||
# The domain of the private docker registry holding dev version of Authelia
|
||||
192.168.39.26 registry.kube.example.com
|
||||
```
|
||||
|
||||
Once done, you can visit http://home.kube.example.com and follow the
|
||||
instructions written in the page.
|
||||
|
||||
## How does it work?
|
||||
|
||||
### Authentication via Authelia
|
||||
|
||||
In a Kube clusters, the routing logic of requests is handled by ingress
|
||||
controllers following rules provided by ingress configurations.
|
||||
|
||||
In this example, [ingress-nginx](https://github.com/kubernetes/ingress-nginx)
|
||||
controller has been installed to handle the incoming requests. Some of them
|
||||
(specified in the ingress configuration) are forwarded to Authelia so that
|
||||
it can verify whether they are allowed and should reach the protected endpoint.
|
||||
|
||||
The authentication is provided at the ingress level by an annotation called
|
||||
`nginx.ingress.kubernetes.io/auth-url` that is filled with the URL of
|
||||
Authelia's verification endpoint.
|
||||
The ingress controller also requires the URL to the
|
||||
authentication portal so that the user can be redirected in case she is not
|
||||
yet authenticated.
|
||||
|
||||
Those annotations can be seen in `apps/secure-ingress.yml` configuration.
|
||||
|
||||
### Production grade infrastructure
|
||||
|
||||
What is great with using [ingress-nginx](https://github.com/kubernetes/ingress-nginx)
|
||||
is that it is compatible with [kube-lego](https://github.com/jetstack/kube-lego)
|
||||
which removes the usual pain of manual SSL certificate renewals. It uses
|
||||
letsencrypt to issue and renew certificates every three month without any
|
||||
manual intervention.
|
||||
|
||||
## What do I need know to deploy it in my cluster?
|
||||
|
||||
Given your cluster is already made of an LDAP server, a Redis cluster, a Mongo
|
||||
cluster and a SMTP server, you'll only need to install the ingress-controller
|
||||
and Authelia whose kubernetes deployment configurations are respectively in
|
||||
`ingress-controller` and `authelia` directories. A template configuration
|
||||
is provided there, you just need to create the configmap to use it within
|
||||
the cluster.
|
||||
|
||||
### I'm already using ingress-nginx
|
||||
|
||||
If you're already using ingress-nginx as your ingress controller, you only
|
||||
need to install Authelia with its configuration and that's it!
|
||||
|
||||
## Questions
|
||||
|
||||
If you have questions about the implementation, please post them on
|
||||
[![Gitter](https://img.shields.io/gitter/room/badges/shields.svg)](https://gitter.im/authelia/general?utm_source=share-link&utm_medium=link&utm_campaign=share-link)
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: test-app-home
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: test-app-home
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: test-app-home
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: test-app-home
|
||||
spec:
|
||||
containers:
|
||||
- name: test-app-home
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- name: app-home-page
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumes:
|
||||
- name: app-home-page
|
||||
configMap:
|
||||
name: app-home-page
|
||||
items:
|
||||
- key: index.html
|
||||
path: index.html
|
|
@ -0,0 +1,35 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Authelia Home</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Authelia on Kube</h1>
|
||||
|
||||
In this example, two applications have been deployed along with Authelia and a fake mailbox in order to confirm your secret registration to Authelia:
|
||||
<ul>
|
||||
<li><a href="https://app1.kube.example.com">https://app1.kube.example.com</a></li>
|
||||
<li><a href="https://app2.kube.example.com">https://app2.kube.example.com</a></li>
|
||||
<li><a href="http://mail.kube.example.com">http://mail.kube.example.com</a></li>
|
||||
</ul>
|
||||
<p>
|
||||
Please note that <b>app1</b> is publicly available and <b>app2</b> is protected by Authelia.<br/>
|
||||
<br/>
|
||||
You can start by visiting <b>app1</b> and then try to access <b>app2</b>. Since <b>app2</b> is protected by Authelia, you will be redirected to Authelia's portal.<br/>
|
||||
<br/>
|
||||
If it's the first time you login in this cluster, you'll need to choose your authentication method and follow Authelia's instructions.<br/>
|
||||
<br/>
|
||||
Once done, you'll be able to authenticate with your selected second factor method.
|
||||
</p>
|
||||
<p>
|
||||
Here is the list of available users in the LDAP
|
||||
<ul>
|
||||
<li><strong>john / password</strong>
|
||||
<li><strong>bob / password</strong>
|
||||
<li><strong>harry / password</strong>
|
||||
</ul>
|
||||
</p>
|
||||
<p>
|
||||
You can always log off by clicking <a href="https://login.kube.example.com/logout?rd=http://home.kube.example.com">here</a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: test-app-home-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: test-app-home
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: test-app1
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: test-app1
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: test-app1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: test-app1
|
||||
spec:
|
||||
containers:
|
||||
- name: test-app1
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- name: app1-page
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumes:
|
||||
- name: app1-page
|
||||
configMap:
|
||||
name: app1-page
|
||||
items:
|
||||
- key: index.html
|
||||
path: index.html
|
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Application 1</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Application 1</h1>
|
||||
<p><a href="http://home.kube.example.com">Go Home</a></p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: test-app1-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: test-app1
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
|
@ -0,0 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICvDCCAaQCCQD9zdaObelW0jANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVh
|
||||
cHAxLmt1YmUuZXhhbXBsZS5jb20wHhcNMTgwMzA0MTUxMDUxWhcNMjgwMzAxMTUx
|
||||
MDUxWjAgMR4wHAYDVQQDDBVhcHAxLmt1YmUuZXhhbXBsZS5jb20wggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+v2s9ABHFgxuYFyGkqlbNQ5OtzHAB79lM
|
||||
sbAMJ9pnMTBA4FXdHgQuQ6Z4F233hMokVfnX9C2KxuLLOQMXJdoVQGytkbGGCzoz
|
||||
Hz1qXBjDCwQtUGgLJ6zc3C8QKx90zmY0NmH55ttFCQKPHaaxgrS2YXsPzMlQKrgH
|
||||
drRklfCpnRZWG9/M1YzXOKeT4VuwTsHyeI8tnco11WJLsZwRxc6TjEgNwwBnct8R
|
||||
/cDhl5guDhqFPgMuBtzRlTVOeZS8NraHL5GRswoUeFJfS2VA3FTABwRWV3J6d5gl
|
||||
oXpvMzCB01u2jVKLq75g91lGT6I+AVMgSOJG4Nezum7brS7jJjVFAgMBAAEwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAIFox2Ox/hJqmaSAyE0TqCaLf3UK78z9m/FYUzWoupGE
|
||||
JAJ83wghVcj7XLKG4x6wN+v342JVa0mQ5X773kqNidHmSdWFPd/hGtx+0dQK3BVV
|
||||
4CmQCNfA7BZDuxWPW0mcrkKun2aSCq0zjK0f/CzPXZxyPW18EmzSNGkmkXCesM5i
|
||||
aevdE5PBKikGz4EfzieVTsImdHDfh2/azdRrmSh22x9/tpZy3mMkc5ERpgL2ll+m
|
||||
HZuZ9FEBQHj92pk2aMBVdxPYpgzWAWbuRUs3vfTIhPlzHcI/ZpE60Ete+yY5lBw/
|
||||
Gf+ph3HPB8gzSOH/hmcmerX9h6E3MFAncdC4hH3R0j8=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,15 @@
|
|||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIICZTCCAU0CAQAwIDEeMBwGA1UEAwwVYXBwMS5rdWJlLmV4YW1wbGUuY29tMIIB
|
||||
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvr9rPQARxYMbmBchpKpWzUOT
|
||||
rcxwAe/ZTLGwDCfaZzEwQOBV3R4ELkOmeBdt94TKJFX51/QtisbiyzkDFyXaFUBs
|
||||
rZGxhgs6Mx89alwYwwsELVBoCyes3NwvECsfdM5mNDZh+ebbRQkCjx2msYK0tmF7
|
||||
D8zJUCq4B3a0ZJXwqZ0WVhvfzNWM1zink+FbsE7B8niPLZ3KNdViS7GcEcXOk4xI
|
||||
DcMAZ3LfEf3A4ZeYLg4ahT4DLgbc0ZU1TnmUvDa2hy+RkbMKFHhSX0tlQNxUwAcE
|
||||
VldyeneYJaF6bzMwgdNbto1Si6u+YPdZRk+iPgFTIEjiRuDXs7pu260u4yY1RQID
|
||||
AQABoAAwDQYJKoZIhvcNAQELBQADggEBALcwQAjNjyhMAbGNpFl6iYhzdhUjz02p
|
||||
hTpc15T+S4PatbgeERYAIuSGxomPHfh+30udxGDCSy730V2urC0eGPjRpnJpGHNG
|
||||
1Dau0sgi28TQPOqhBcZm0GNHMocc5iG+AxWAsxNwtSH3wRoeUGYXavcm9/tWvYbi
|
||||
RIKmzXTQKsmY+qhBo3e/phUFuSU8GARYkfDSVqcTM7C3xswgXYcImrkbHAxvsC7+
|
||||
3nr8ir2K9t2M3QxV7lTybNacuOF84wL93AZDvJ04HctXXgtt2rSI6vxxt18jyrxJ
|
||||
yHX9ADrAa+jhPAM664SZs/+l0fBbil2UaMPOKXOCmYGuERpWh1HLHKo=
|
||||
-----END CERTIFICATE REQUEST-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAvr9rPQARxYMbmBchpKpWzUOTrcxwAe/ZTLGwDCfaZzEwQOBV
|
||||
3R4ELkOmeBdt94TKJFX51/QtisbiyzkDFyXaFUBsrZGxhgs6Mx89alwYwwsELVBo
|
||||
Cyes3NwvECsfdM5mNDZh+ebbRQkCjx2msYK0tmF7D8zJUCq4B3a0ZJXwqZ0WVhvf
|
||||
zNWM1zink+FbsE7B8niPLZ3KNdViS7GcEcXOk4xIDcMAZ3LfEf3A4ZeYLg4ahT4D
|
||||
Lgbc0ZU1TnmUvDa2hy+RkbMKFHhSX0tlQNxUwAcEVldyeneYJaF6bzMwgdNbto1S
|
||||
i6u+YPdZRk+iPgFTIEjiRuDXs7pu260u4yY1RQIDAQABAoIBAQCwn3ahCUtrZDdM
|
||||
4T5ZxxCRCJ3aNI8SfBDuHyowV0a4fqd7qz5WfNDKNgIS+T7uDptOgf3SpVr2QasH
|
||||
GkduS7JgM0NuhJWo1QSTCb5Imfajw7OecfGlQpuh9o/tnMCH3AZvGlwmlkk651jj
|
||||
REVx4OGMbz8QJkPSY3v8DUKEUQKDSkRhZRhRGDZqbOSeERhOo2O3MqcBaVossYRw
|
||||
+2Apth2XHg+7mgQjQF+8Z/DeXtLZgOB4VwQ0vkJmSu+FLhWDJqA+WH5JaOrmS3SN
|
||||
lrPeIEwQMGHmwmIUAaQ7Akkow2xx4VuDRQUcUlitAM21x/MjBdTFbFx975svOiuE
|
||||
vePNasYBAoGBAOK8e8x0OrqhgsVGWLvJjHnhzTePpemCCB9jRRnTcmMUxXR7moCh
|
||||
WGgbyQ3+pU15WMxaIpVrGlV3LOwqSEXYspIpBQKv5+kSAaJf/Op3rtuzo57JLMYP
|
||||
YokMu43ewtSF0CE/7h98vruAYCcDJZs+T7K0lHCBS9pcjhU2MS/ktW2lAoGBANdd
|
||||
2a1dkEbZyD9NMGD+wWTkctrML3r1ZLy2gq1AX/oyKzdtD6T1nob435RVkyqPGLhr
|
||||
tEHJuxLiaJlCk5Kd8V84ps0J9SlZTkLzf2ixb06f1YI9ye37UzBr13H59+N6w8Zu
|
||||
24Gv12ht+WBecWKHgtF16LaCDPYORUMOa3CpgFchAoGBAN6M0Rr6jta3R0tpZBlW
|
||||
mErd5vd9SQWtO1nLr3zM/f7g2XsfA6T0OXlepHbXFtu3mwBiDIYK7XssEezxB6V/
|
||||
MK+kEaX0kTZFFVOS0gY2WWyOo7BsmEUDvtz0oXd8SlId0g+A17MSV4hlVnuUbCo3
|
||||
/DRVaUoQrypzJIcPfTIcVDR9AoGAY3uNrqB2odO9xUfhnhxvtywzxc/l6tVp6CYi
|
||||
bOc8rnT4M40kWd2/kbdqh7mT1mftUlsmE/GcgZemG41+X46nzYV8v1/nKGeBWDnk
|
||||
U7cKpHX+iUADg/PBNK/MAHEoSaMOxh21Nc3FIg8Sz6owlAPmsNzXV17xn8NtyRDj
|
||||
HlKd3yECgYBvB0bV1yXOvfoqGXAyadNJM9eKOuQwhrOJCXzCeMInhUtLpH35kC17
|
||||
e8rOmoBhV1rLpxlMLV8giyJSRUPoN/TfUHfS2pWfKPobrp50vaUn1hYp6EEr85Qs
|
||||
DdV2VilJsJN49sMg67GV3Zi4lnjVzYNFegw6y5Xi8l8ulYtzxJnemA==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: test-app2
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: test-app2
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: test-app2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: test-app2
|
||||
spec:
|
||||
containers:
|
||||
- name: test-app2
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- name: app2-page
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumes:
|
||||
- name: app2-page
|
||||
configMap:
|
||||
name: app2-page
|
||||
items:
|
||||
- key: index.html
|
||||
path: index.html
|
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Application 2</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Application 2</h2>
|
||||
<p><a href="http://home.kube.example.com">Go Home</a></p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: test-app2-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: test-app2
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
|
@ -0,0 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICvDCCAaQCCQCE6h+pwV+OTTANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVh
|
||||
cHAyLmt1YmUuZXhhbXBsZS5jb20wHhcNMTgwMzA0MTUwODUyWhcNMjgwMzAxMTUw
|
||||
ODUyWjAgMR4wHAYDVQQDDBVhcHAyLmt1YmUuZXhhbXBsZS5jb20wggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDuVrXRL0i75y0QpbkFM7h1jIwbKOQYdkCR
|
||||
tAp4aFjRAnHE1DtiXuexoyhs0hbwtxmFF0RpPjOVLvLl/AZt6i65dC5gl1czLmmH
|
||||
nzjBzUF4jM5qJioP867vR2+SDnD6YWCQrwYG8bHeFKvppAlTY7g8YoTD/b3JNnV1
|
||||
t+uaPyNKvu33pOP2vP/w/709WFVEwd/334RFF6fjAyYrOgYgvqcgyJ6E6T4cf/Vl
|
||||
psgLZpJ7o4VoFHq1MdP6Ro+HzKwHUsDbH53U6wISe3dRBmHjTJH2sp1KuJ5gR1Ko
|
||||
CiiVfq+CCPOxGKNngQe2EqDHmuVuXu30VFu82hznfkXdlhuzTGSfAgMBAAEwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAEWeTkGmuXnAPU8JGTa+O00kI9nFy10inbiU8O+XuwUL
|
||||
Cj53CRffbzlsCDRDDxxoBuJ5EvWho5F7MR7A8ZRDfWqLTogvjpVp2YJ+jK/iTbqU
|
||||
95tCVMByZufa4bHPWmngeYsSu0s0+qRYOeyiCbiFzlzFP3nLSS6aMPwrMUz7/Qp1
|
||||
XUE1YfyqjKDkvFN4Wq1GKOUZEh4CJh3SuOE/FrRAiaAWnOH4LVDn5TFEbLyEqZLd
|
||||
BrYEDopRsTpJck/ZEF43GZ0t8Y8CKffpWGV4PvSiUnl/7mKd+i+QsTx8CnnlR9y/
|
||||
ZvwNRwvRw3uXwkgRinE8wwONAfwB2nIYKyuU9/ODAPs=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,15 @@
|
|||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIICZTCCAU0CAQAwIDEeMBwGA1UEAwwVYXBwMi5rdWJlLmV4YW1wbGUuY29tMIIB
|
||||
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7la10S9Iu+ctEKW5BTO4dYyM
|
||||
GyjkGHZAkbQKeGhY0QJxxNQ7Yl7nsaMobNIW8LcZhRdEaT4zlS7y5fwGbeouuXQu
|
||||
YJdXMy5ph584wc1BeIzOaiYqD/Ou70dvkg5w+mFgkK8GBvGx3hSr6aQJU2O4PGKE
|
||||
w/29yTZ1dbfrmj8jSr7t96Tj9rz/8P+9PVhVRMHf99+ERRen4wMmKzoGIL6nIMie
|
||||
hOk+HH/1ZabIC2aSe6OFaBR6tTHT+kaPh8ysB1LA2x+d1OsCEnt3UQZh40yR9rKd
|
||||
SrieYEdSqAoolX6vggjzsRijZ4EHthKgx5rlbl7t9FRbvNoc535F3ZYbs0xknwID
|
||||
AQABoAAwDQYJKoZIhvcNAQELBQADggEBANqbKTFSeOf9GRgrNuqRGYYdqSPaoXpu
|
||||
iSKhJRABj4zMOCJlfDpeMQ8mGfmBUV+IHr+X8/nbMt+OMEf4u1+7Mmz4Zfvkt5gP
|
||||
MBlYbauVxn/uIYp7aZgBUABC7SvLeITRz4rnQW5SvCNyuJAKQh84uF82g47S7Oaz
|
||||
2dp6NO1nQ/N9SD6y0CyuIXf1KbSk4+lXa3+rGyqpF1aovpXCgvcA3tWrI/Lg2t5E
|
||||
uPoiHegKGKyWUZeVh8eKY2ZBCl+uRmwLqTTdzj1HcoK5T1slg0X+K9Q1UsGy23Pw
|
||||
RHFtGuel8msESgTnspzQF3T1uOscOOiQFG3xnoZtxH92gFT+pI7DoEY=
|
||||
-----END CERTIFICATE REQUEST-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEA7la10S9Iu+ctEKW5BTO4dYyMGyjkGHZAkbQKeGhY0QJxxNQ7
|
||||
Yl7nsaMobNIW8LcZhRdEaT4zlS7y5fwGbeouuXQuYJdXMy5ph584wc1BeIzOaiYq
|
||||
D/Ou70dvkg5w+mFgkK8GBvGx3hSr6aQJU2O4PGKEw/29yTZ1dbfrmj8jSr7t96Tj
|
||||
9rz/8P+9PVhVRMHf99+ERRen4wMmKzoGIL6nIMiehOk+HH/1ZabIC2aSe6OFaBR6
|
||||
tTHT+kaPh8ysB1LA2x+d1OsCEnt3UQZh40yR9rKdSrieYEdSqAoolX6vggjzsRij
|
||||
Z4EHthKgx5rlbl7t9FRbvNoc535F3ZYbs0xknwIDAQABAoIBAFcXgGDsMlvXYfRP
|
||||
Woi4GZN6xEe4bYEy1O1pKNpO5wWZKxGNrBWKMIgM4tzA+HkFr2Ge2vTKMfc1rLS1
|
||||
n3PSuzgxaDELnGWrdAyG9ip7Yo02hsbrIzupBCeTpwVsGYSkyLCWBFHNR/2q+Bbs
|
||||
RiweqFgIeBNWSV+ZctqNVp6Kq87HuYfm/ka8ewVnPYhEMewuE0vqfVjc+fdPr/5I
|
||||
4uQCCw0/ZTFFP++hkyNsH1ZCdUeT83xbgUwFA0M/3ckjMhzcP7lncq6Gvy8NpBhI
|
||||
mle/Ev82yaDRl5VKoenpy2d8L+qvIjRbhZiZuTAU9AWRvOKrTMtzKSpyMgWAQZ64
|
||||
69ResmECgYEA+2Ws4qBiYd3BKF5tc0fWbS0omThT60oLc6aLu5NoryogHHNwPOud
|
||||
69nCDHSyYp+PqK1HLrOAVoTLmuwyys15juizewO809gYRgXlNZ9TKED8Znyg004o
|
||||
EQVYxMevq2kfDOBJkMphLXAvFrRFQVB2Km8EfKkrI++1rhxKGJD+FzMCgYEA8rPU
|
||||
G1v3/uemBxYO/bEmdjvsDfLI7FBYNmjgvBGJocSwb2sG/tRr0imZBPAuDlCKcZ1E
|
||||
G3rZOJ0VsLzxX5RCVYFKRQvUtbaNO+uDJjChxQ/fQQdbIoaIMjyAVLI7t3Ei4+nY
|
||||
7eHYjcHeMX54drO8YqQ6OoWZ4x8DI8KNcxBnzOUCgYA+uMRkmn1RS4For/6At5ih
|
||||
DpZFfA878fJffVr5hrKkmU7/qjGDkYmKEX9fmjHzdznhbLIIzdIkQ+eElI+rl45P
|
||||
gHFfLLSM6ipMNiZUtZaKwYP3kfqSHbrTXFEkb2m9y3Fqxf60uDl8m7Oz53Ar9oY0
|
||||
2hP1gkN4KNNcSESYUnyCjwKBgAR9+ZYMDLoGFZeZ++sMJVcY4tSbQsbE8e0H4ej5
|
||||
Nh/tYQqe44FB80Dvjip+O4v+R6G0tHcBvhWDKsyboqgPOW8Vtocyodw/JbwPLt09
|
||||
FzFrislMVo58CPdNEV7/8YUCrg+j22UDwhtVlEQ8QASKbRkySvWcVW3TvB4kUrPn
|
||||
gNRVAoGAI99QzqSRBSLeDgxxRgTM7l5wzyVEmJfmMqQsIbHvYy6zG9iYjFI6UZ8I
|
||||
U3C/Sdnq7wCWa70b3L8A1iN2fYVwvkEH5WGbEp5B2Cye50avegbPi1FgGw2VSIuS
|
||||
ysAkWaVJXsb2oQNtjidRuEflhy4nr7eybwa6cgarh7ci3JB+tQ8=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: insecure-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
spec:
|
||||
tls:
|
||||
- secretName: app1-tls
|
||||
hosts:
|
||||
- app1.kube.example.com
|
||||
rules:
|
||||
- host: app1.kube.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test-app1-service
|
||||
servicePort: 80
|
||||
- host: home.kube.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test-app-home-service
|
||||
servicePort: 80
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: secure-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
nginx.ingress.kubernetes.io/auth-url: "http://authelia-service.authelia.svc.cluster.local/api/verify"
|
||||
nginx.ingress.kubernetes.io/auth-signin: "https://login.kube.example.com"
|
||||
spec:
|
||||
tls:
|
||||
- secretName: app2-tls
|
||||
hosts:
|
||||
- app2.kube.example.com
|
||||
rules:
|
||||
- host: app2.kube.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: test-app2-service
|
||||
servicePort: 80
|
|
@ -0,0 +1,211 @@
|
|||
###############################################################
|
||||
# Authelia configuration #
|
||||
###############################################################
|
||||
|
||||
# The port to listen on
|
||||
port: 80
|
||||
|
||||
# Log level
|
||||
#
|
||||
# Level of verbosity for logs
|
||||
logs_level: debug
|
||||
|
||||
# Default redirection URL
|
||||
#
|
||||
# If user tries to authenticate without any referer, Authelia
|
||||
# does not know where to redirect the user to at the end of the
|
||||
# authentication process.
|
||||
# This parameter allows you to specify the default redirection
|
||||
# URL Authelia will use in such a case.
|
||||
#
|
||||
# Note: this parameter is optional. If not provided, user won't
|
||||
# be redirected upon successful authentication.
|
||||
default_redirection_url: https://login.kube.example.com
|
||||
|
||||
# LDAP configuration
|
||||
#
|
||||
# Example: for user john, the DN will be cn=john,ou=users,dc=example,dc=com
|
||||
ldap:
|
||||
# The url of the ldap server
|
||||
url: ldap://ldap-service
|
||||
|
||||
# The base dn for every entries
|
||||
base_dn: dc=example,dc=com
|
||||
|
||||
# An additional dn to define the scope to all users
|
||||
additional_users_dn: ou=users
|
||||
|
||||
# The users filter used to find the user DN
|
||||
# {0} is a matcher replaced by username.
|
||||
# 'cn={0}' by default.
|
||||
users_filter: cn={0}
|
||||
|
||||
# An additional dn to define the scope of groups
|
||||
additional_groups_dn: ou=groups
|
||||
|
||||
# The groups filter used for retrieving groups of a given user.
|
||||
# {0} is a matcher replaced by username.
|
||||
# {dn} is a matcher replaced by user DN.
|
||||
# 'member={dn}' by default.
|
||||
groups_filter: (&(member={dn})(objectclass=groupOfNames))
|
||||
|
||||
# The attribute holding the name of the group
|
||||
group_name_attribute: cn
|
||||
|
||||
# The attribute holding the mail address of the user
|
||||
mail_attribute: mail
|
||||
|
||||
# The username and password of the admin user.
|
||||
user: cn=admin,dc=example,dc=com
|
||||
password: password
|
||||
|
||||
|
||||
# Authentication methods
|
||||
#
|
||||
# Authentication methods can be defined per subdomain.
|
||||
# There are currently two available methods: "single_factor" and "two_factor"
|
||||
#
|
||||
# Note: by default a domain uses "two_factor" method.
|
||||
#
|
||||
# Note: 'per_subdomain_methods' is a dictionary where keys must be subdomains and
|
||||
# values must be one of the two possible methods.
|
||||
#
|
||||
# Note: 'per_subdomain_methods' is optional.
|
||||
#
|
||||
# Note: authentication_methods is optional. If it is not set all sub-domains
|
||||
# are protected by two factors.
|
||||
authentication_methods:
|
||||
default_method: two_factor
|
||||
# per_subdomain_methods:
|
||||
# single_factor.example.com: single_factor
|
||||
|
||||
# Access Control
|
||||
#
|
||||
# Access control is a set of rules you can use to restrict user access to certain
|
||||
# resources.
|
||||
# Any (apply to anyone), per-user or per-group rules can be defined.
|
||||
#
|
||||
# If 'access_control' is not defined, ACL rules are disabled and the `allow` default
|
||||
# policy is applied, i.e., access is allowed to anyone. Otherwise restrictions follow
|
||||
# the rules defined.
|
||||
#
|
||||
# Note: One can use the wildcard * to match any subdomain.
|
||||
# It must stand at the beginning of the pattern. (example: *.mydomain.com)
|
||||
#
|
||||
# Note: You must put the pattern in simple quotes when using the wildcard for the YAML
|
||||
# to be syntaxically correct.
|
||||
#
|
||||
# Definition: A `rule` is an object with the following keys: `domain`, `policy`
|
||||
# and `resources`.
|
||||
# - `domain` defines which domain or set of domains the rule applies to.
|
||||
# - `policy` is the policy to apply to resources. It must be either `allow` or `deny`.
|
||||
# - `resources` is a list of regular expressions that matches a set of resources to
|
||||
# apply the policy to.
|
||||
#
|
||||
# Note: Rules follow an order of priority defined as follows:
|
||||
# In each category (`any`, `groups`, `users`), the latest rules have the highest
|
||||
# priority. In other words, it means that if a given resource matches two rules in the
|
||||
# same category, the latest one overrides the first one.
|
||||
# Each category has also its own priority. That is, `users` has the highest priority, then
|
||||
# `groups` and `any` has the lowest priority. It means if two rules in different categories
|
||||
# match a given resource, the one in the category with the highest priority overrides the
|
||||
# other one.
|
||||
#
|
||||
access_control:
|
||||
# Default policy can either be `allow` or `deny`.
|
||||
# It is the policy applied to any resource if it has not been overriden
|
||||
# in the `any`, `groups` or `users` category.
|
||||
default_policy: deny
|
||||
|
||||
# The rules that apply to anyone.
|
||||
# The value is a list of rules.
|
||||
any:
|
||||
- domain: '*.example.com'
|
||||
policy: allow
|
||||
|
||||
# Group-based rules. The key is a group name and the value
|
||||
# is a list of rules.
|
||||
groups: {}
|
||||
|
||||
# User-based rules. The key is a user name and the value
|
||||
# is a list of rules.
|
||||
users: {}
|
||||
|
||||
|
||||
# Configuration of session cookies
|
||||
#
|
||||
# The session cookies identify the user once logged in.
|
||||
session:
|
||||
# The secret to encrypt the session cookie.
|
||||
secret: unsecure_password
|
||||
|
||||
# The time in ms before the cookie expires and session is reset.
|
||||
expiration: 3600000 # 1 hour
|
||||
|
||||
# The inactivity time in ms before the session is reset.
|
||||
inactivity: 300000 # 5 minutes
|
||||
|
||||
# The domain to protect.
|
||||
# Note: the authenticator must also be in that domain. If empty, the cookie
|
||||
# is restricted to the subdomain of the issuer.
|
||||
domain: example.com
|
||||
|
||||
# The redis connection details
|
||||
redis:
|
||||
host: redis-service
|
||||
port: 6379
|
||||
|
||||
# Configuration of the authentication regulation mechanism.
|
||||
#
|
||||
# This mechanism prevents attackers from brute forcing the first factor.
|
||||
# It bans the user if too many attempts are done in a short period of
|
||||
# time.
|
||||
regulation:
|
||||
# The number of failed login attempts before user is banned.
|
||||
# Set it to 0 for disabling regulation.
|
||||
max_retries: 3
|
||||
|
||||
# The length of time between login attempts before user is banned.
|
||||
find_time: 120
|
||||
|
||||
# The length of time before a banned user can login again.
|
||||
ban_time: 300
|
||||
|
||||
# Configuration of the storage backend used to store data and secrets.
|
||||
#
|
||||
# You must use only an available configuration: local, mongo
|
||||
storage:
|
||||
# The directory where the DB files will be saved
|
||||
# local: /var/lib/authelia/store
|
||||
|
||||
# Settings to connect to mongo server
|
||||
mongo:
|
||||
url: mongodb://mongo-service
|
||||
database: authelia
|
||||
|
||||
# Configuration of the notification system.
|
||||
#
|
||||
# Notifications are sent to users when they require a password reset, a u2f
|
||||
# registration or a TOTP registration.
|
||||
# Use only an available configuration: filesystem, gmail
|
||||
notifier:
|
||||
# For testing purpose, notifications can be sent in a file
|
||||
# filesystem:
|
||||
# filename: /tmp/authelia/notification.txt
|
||||
|
||||
# Use your email account to send the notifications. You can use an app password.
|
||||
# List of valid services can be found here: https://nodemailer.com/smtp/well-known/
|
||||
# email:
|
||||
# username: authelia@gmail.com
|
||||
# password: password
|
||||
# sender: authelia@example.com
|
||||
# service: gmail
|
||||
|
||||
# Use a SMTP server for sending notifications
|
||||
smtp:
|
||||
username: test
|
||||
password: password
|
||||
secure: false
|
||||
host: 'mailcatcher-service'
|
||||
port: 1025
|
||||
sender: admin@example.com
|
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: authelia
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: authelia
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: authelia
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: authelia
|
||||
spec:
|
||||
containers:
|
||||
- name: authelia
|
||||
image: localhost:5000/authelia:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /etc/authelia
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: authelia-config
|
||||
items:
|
||||
- key: config.yml
|
||||
path: config.yml
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: authelia-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
spec:
|
||||
tls:
|
||||
- secretName: authelia-tls
|
||||
hosts:
|
||||
- login.kube.example.com
|
||||
rules:
|
||||
rules:
|
||||
- host: login.kube.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: authelia-service
|
||||
servicePort: 80
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: authelia-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: authelia
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 80
|
|
@ -0,0 +1,17 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICvjCCAaYCCQCJYt0VhOelKjANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDDBZs
|
||||
b2dpbi5rdWJlLmV4YW1wbGUuY29tMB4XDTE4MDMwNDE1MTQzMVoXDTE5MDMwNDE1
|
||||
MTQzMVowITEfMB0GA1UEAwwWbG9naW4ua3ViZS5leGFtcGxlLmNvbTCCASIwDQYJ
|
||||
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIlUUppqDLXQCey+OqC4YIhsZFhus0S
|
||||
0OcNKBhMcUpKdaqtMf8n8mUtGCByUTf+LMBOyv/WrdcGH5pwlylyERPfDsUFF+5W
|
||||
LjhHGjMZVKWHOadb25HpO9IZUyyC+5PepfrHlxS5EhTQXymA7yjaXSizfH0uF9Le
|
||||
mF/RoqArtDfq/2/golcX5YkRt6FwbGrypHG0MuREyMN7H+XmKyC4Cwc1ECbROrWv
|
||||
C5491Fvw4fW0zWa6M1z56kzA+X7ZleiemiY0vm7hzlm8qztd449pJzweb/Gl2r7n
|
||||
LdFK+H2jbkn07Z//rwlm8Wlwtb3GLOTgisNv5jALpCDdgiSmUc+G+f0CAwEAATAN
|
||||
BgkqhkiG9w0BAQsFAAOCAQEAUm+gRqlUIGK3UKA+z1Si2EpFeOpSkfBbMjwWQAea
|
||||
yEY+XtUxQSWmbTx6Cp1miVwSp4ldd0nYVCpesv94FoI3ahktZGafcfviYgyCNPXl
|
||||
QBREQ3NU9TBLHOmCygL8JlzKLtKABKTiGsDahPmBaMogCbvswFqccZ1EtLRcrI48
|
||||
FFGS7K4ku561AK+WqFS8yxFKcudJSfmLeEZ0uNazEbh8kIgA5dXtapv6lBhPQ6nN
|
||||
MPZO321PWGysvj3RXDagYQOPBLX7NhnoFDCoeJKbPQ9lTLOAI0aQnpNoFZnoiWc3
|
||||
NNLboVSTPQ3jyumAAm7tXS/KWI5Samfp8Cgu7uqhPLdHYg==
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,15 @@
|
|||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIICZjCCAU4CAQAwITEfMB0GA1UEAwwWbG9naW4ua3ViZS5leGFtcGxlLmNvbTCC
|
||||
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIlUUppqDLXQCey+OqC4YIh
|
||||
sZFhus0S0OcNKBhMcUpKdaqtMf8n8mUtGCByUTf+LMBOyv/WrdcGH5pwlylyERPf
|
||||
DsUFF+5WLjhHGjMZVKWHOadb25HpO9IZUyyC+5PepfrHlxS5EhTQXymA7yjaXSiz
|
||||
fH0uF9LemF/RoqArtDfq/2/golcX5YkRt6FwbGrypHG0MuREyMN7H+XmKyC4Cwc1
|
||||
ECbROrWvC5491Fvw4fW0zWa6M1z56kzA+X7ZleiemiY0vm7hzlm8qztd449pJzwe
|
||||
b/Gl2r7nLdFK+H2jbkn07Z//rwlm8Wlwtb3GLOTgisNv5jALpCDdgiSmUc+G+f0C
|
||||
AwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQCHO3wzf1jCOcTmo5NBnCendtEb/IAl
|
||||
aTBCW3b2+QDRQBGgpQb+JeDjHjIzp5FgzzJVF0XTA8H8jmR56lPTXNlWESzUh1oV
|
||||
on8QcbPi97nuhIEJNfk7K6gAiK11fULBoNUgI7PsRvAneo2PsCEHGtNsdoU4Ii7A
|
||||
CuUtKeeZCdbxVM2HradSJ9vvxRmOuIfsQJbUaH0F/Z3A0l0UQbp1AUOWFcJ6XDkX
|
||||
SgDkMCkXJV53SlwGZm8q6Hj8zwP7Tlk6Nkzcn3ZMDB76o92QSVoi1V07NrvRUvcc
|
||||
2/eekJBWfpzy1LkaovYGBow4ose8V5nMyH9feXlReCVk2aHYTYbEmQRj
|
||||
-----END CERTIFICATE REQUEST-----
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAwiVRSmmoMtdAJ7L46oLhgiGxkWG6zRLQ5w0oGExxSkp1qq0x
|
||||
/yfyZS0YIHJRN/4swE7K/9at1wYfmnCXKXIRE98OxQUX7lYuOEcaMxlUpYc5p1vb
|
||||
kek70hlTLIL7k96l+seXFLkSFNBfKYDvKNpdKLN8fS4X0t6YX9GioCu0N+r/b+Ci
|
||||
VxfliRG3oXBsavKkcbQy5ETIw3sf5eYrILgLBzUQJtE6ta8Lnj3UW/Dh9bTNZroz
|
||||
XPnqTMD5ftmV6J6aJjS+buHOWbyrO13jj2knPB5v8aXavuct0Ur4faNuSfTtn/+v
|
||||
CWbxaXC1vcYs5OCKw2/mMAukIN2CJKZRz4b5/QIDAQABAoIBAQCkTwLqcFs6k/Om
|
||||
5ZBGoPgLs0pdmRGIR7lnIjphvihPUI8fIK9km8FIoY5+v2E/ey0SoFyrg1vi1Drg
|
||||
8RLtr60GXUxZsALd4jABzyM8Rd7erIA9xL8iUPsgx/Adhsk2D0P35v1VO4Ay/1ra
|
||||
fFVsBMq9DJJ6Ow1MmLjqtzfkSLigbRRSPwaS081oW570cg9ABc1Cpp9sdLjG2Il0
|
||||
Eyet0qe0fiJAOlnE+tMRls9AoGYLG61msb1OhkpKfaNdw6IolkSGQZDqqsf1cSE3
|
||||
I7ypsE0LLtDeCU/jsUMjDHBwerqTANUHO5Y4PZ3hSJN55p/IGEiUeAMYs+dqtFx8
|
||||
xc/KfV2BAoGBAP+2nR73QjWdqJ0A4IdRq811eZM+NTWbobKRSay+T3Ve8QcRqc41
|
||||
YXJYqRhX23me3p9CxHDMVoXYtWS1nlXnsOxk60idffEIf5tbjzEYi1dIdLoCfbVW
|
||||
dZS1ZsZh4GZ3If8e78R+9IBQ6+SFvsVocRXpkf6VHp6jB3mXH0XCyNXdAoGBAMJd
|
||||
CORqmdrmCbfZnn7G3cZ7kTS05inMkj/svtDb+tkcy2x+pfL9y+SfeAf+o5AGl6pN
|
||||
CsiiGJTVj/Wtic572zdT198UFyWjDrgYUMNzvL9430hnZkySF/E8f1XHD8Sb4P65
|
||||
CVGJeVKuEHTXcas9F3VYln/87WGDVrtVowO408KhAoGACFiSej9BtvRFW5J6wY/l
|
||||
1pfd9vNR00UYGvbo+61edIs7vKpT63oMiynfov7DGA4aYAJS3QeeT1IKYZYX69/b
|
||||
A2wrzbvuL17Co3RykPynF5syzBtmtPN0dP0StKjfJRkAUA5XbwdhvYpmmJfQ6SqG
|
||||
fluYO0HstOrHRK2tBJ7d5TUCgYBt9mDPihgdpkQdRfvL0gsq/kH6xdXqFBkyHWkf
|
||||
lTVonEfizAxrW3d9k1M/gqtbEr+/0/Kj7EFoAyN9ZX8v2Rb/SGo7hYxK+OOc9/TJ
|
||||
f7NryKDav9U6wPTWwNlx2DttiptSwbEp9lMzmdMpp7JhpSCefU44fwp2Pu5U8nBV
|
||||
7L2xwQKBgHln1Y4EZ9SQDA0jFiSUNoCkkUJFox8752FsPolCna3GmBAYJn8+Oumj
|
||||
VbLPJvJxHmXMn+JN+rxxFve/DxV1TJqsan5F7i5xp0Ck4rm+TU0ZxvHW75yNG8ER
|
||||
bNGkvo1dme3fh8YETH6sqePTtbJ04hMfNhn1/iu89s6+ft4cqnpk
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,61 @@
|
|||
#!/bin/bash
|
||||
|
||||
start_apps() {
|
||||
# Create the test application pages
|
||||
kubectl create configmap app1-page --namespace=authelia --from-file=apps/app1/index.html
|
||||
kubectl create configmap app2-page --namespace=authelia --from-file=apps/app2/index.html
|
||||
kubectl create configmap app-home-page --namespace=authelia --from-file=apps/app-home/index.html
|
||||
|
||||
# Create TLS certificate and key for HTTPS termination
|
||||
kubectl create secret generic app1-tls --namespace=authelia --from-file=apps/app1/ssl/tls.key --from-file=apps/app1/ssl/tls.crt
|
||||
kubectl create secret generic app2-tls --namespace=authelia --from-file=apps/app2/ssl/tls.key --from-file=apps/app2/ssl/tls.crt
|
||||
kubectl create secret generic authelia-tls --namespace=authelia --from-file=authelia/ssl/tls.key --from-file=authelia/ssl/tls.crt
|
||||
|
||||
# Spawn the applications
|
||||
kubectl apply -f apps
|
||||
kubectl apply -f apps/app1
|
||||
kubectl apply -f apps/app2
|
||||
kubectl apply -f apps/app-home
|
||||
}
|
||||
|
||||
start_ingress_controller() {
|
||||
kubectl apply -f ingress-controller
|
||||
}
|
||||
|
||||
start_authelia() {
|
||||
kubectl create configmap authelia-config --namespace=authelia --from-file=authelia/configs/config.yml
|
||||
kubectl apply -f authelia
|
||||
}
|
||||
|
||||
# Spawn Redis and Mongo as backend for Authelia
|
||||
# Please note they are not configured to be distributed on several machines
|
||||
start_storage() {
|
||||
kubectl apply -f storage
|
||||
}
|
||||
|
||||
# Create a fake mailbox to catch emails sent by Authelia
|
||||
start_mailcatcher() {
|
||||
kubectl apply -f mailcatcher
|
||||
}
|
||||
|
||||
start_ldap() {
|
||||
kubectl apply -f ldap
|
||||
}
|
||||
|
||||
start_docker_registry() {
|
||||
kubectl apply -f docker-registry
|
||||
}
|
||||
|
||||
# Create the Authelia namespace in the cluster
|
||||
create_namespace() {
|
||||
kubectl apply -f namespace.yml
|
||||
}
|
||||
|
||||
create_namespace
|
||||
start_docker_registry
|
||||
start_storage
|
||||
start_ldap
|
||||
start_mailcatcher
|
||||
start_ingress_controller
|
||||
start_authelia
|
||||
start_apps
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
build_and_push_authelia() {
|
||||
cd ../../
|
||||
docker build -t registry.kube.example.com:80/authelia .
|
||||
docker push registry.kube.example.com:80/authelia
|
||||
}
|
||||
|
||||
build_and_push_authelia
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: kube-registry-proxy
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: kube-registry-proxy
|
||||
kubernetes.io/cluster-service: "true"
|
||||
version: v0.4
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kube-registry-proxy
|
||||
kubernetes.io/name: "kube-registry-proxy"
|
||||
kubernetes.io/cluster-service: "true"
|
||||
version: v0.4
|
||||
spec:
|
||||
containers:
|
||||
- name: kube-registry-proxy
|
||||
image: gcr.io/google_containers/kube-registry-proxy:0.4
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 50Mi
|
||||
env:
|
||||
- name: REGISTRY_HOST
|
||||
value: kube-registry.kube-system.svc.cluster.local
|
||||
- name: REGISTRY_PORT
|
||||
value: "5000"
|
||||
ports:
|
||||
- name: registry
|
||||
containerPort: 80
|
||||
hostPort: 5000
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: registry-ingress
|
||||
namespace: kube-system
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: 100m # Avoid 413 Request entity too large
|
||||
spec:
|
||||
rules:
|
||||
- host: registry.kube.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: kube-registry
|
||||
servicePort: 5000
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: ReplicationController
|
||||
metadata:
|
||||
name: kube-registry-v0
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: kube-registry-upstream
|
||||
version: v0
|
||||
kubernetes.io/cluster-service: "true"
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
k8s-app: kube-registry-upstream
|
||||
version: v0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: kube-registry-upstream
|
||||
version: v0
|
||||
kubernetes.io/cluster-service: "true"
|
||||
spec:
|
||||
containers:
|
||||
- name: registry
|
||||
image: registry:2
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
env:
|
||||
- name: REGISTRY_HTTP_ADDR
|
||||
value: :5000
|
||||
- name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
|
||||
value: /var/lib/registry
|
||||
volumeMounts:
|
||||
- name: image-store
|
||||
mountPath: /var/lib/registry
|
||||
ports:
|
||||
- containerPort: 5000
|
||||
name: registry
|
||||
protocol: TCP
|
||||
volumes:
|
||||
- name: image-store
|
||||
emptyDir: {}
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: kube-registry
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: kube-registry-upstream
|
||||
kubernetes.io/cluster-service: "true"
|
||||
kubernetes.io/name: "KubeRegistry"
|
||||
spec:
|
||||
selector:
|
||||
k8s-app: kube-registry-upstream
|
||||
ports:
|
||||
- name: registry
|
||||
port: 5000
|
||||
protocol: TCP
|
|
@ -0,0 +1,48 @@
|
|||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: default-http-backend
|
||||
labels:
|
||||
app: default-http-backend
|
||||
namespace: authelia
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: default-http-backend
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 60
|
||||
containers:
|
||||
- name: default-http-backend
|
||||
image: gcr.io/google_containers/defaultbackend:1.4
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8080
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 30
|
||||
timeoutSeconds: 5
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
resources:
|
||||
limits:
|
||||
cpu: 10m
|
||||
memory: 20Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 20Mi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: default-http-backend
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: default-http-backend
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: default-http-backend
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-ingress-controller-external
|
||||
namespace: authelia
|
||||
labels:
|
||||
k8s-app: nginx-ingress-controller-external
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: nginx-ingress-controller-external
|
||||
name: nginx-ingress-controller-external
|
||||
annotations:
|
||||
prometheus.io/port: '10254'
|
||||
prometheus.io/scrape: 'true'
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 60
|
||||
containers:
|
||||
- image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.13.0
|
||||
name: nginx-ingress-controller-external
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 80
|
||||
- containerPort: 443
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
args:
|
||||
- /nginx-ingress-controller
|
||||
- --ingress-class=nginx
|
||||
- --election-id=ingress-controller-leader-external
|
||||
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx-ingress-controller-external-service
|
||||
namespace: authelia
|
||||
labels:
|
||||
k8s-app: nginx-ingress-controller-external
|
||||
spec:
|
||||
selector:
|
||||
k8s-app: nginx-ingress-controller-external
|
||||
ports:
|
||||
- port: 80
|
||||
name: http
|
||||
- port: 443
|
||||
name: https
|
||||
externalIPs:
|
||||
- 192.168.39.26
|
|
@ -0,0 +1,12 @@
|
|||
FROM clems4ever/openldap
|
||||
|
||||
ENV SLAPD_ORGANISATION=MyCompany
|
||||
ENV SLAPD_DOMAIN=example.com
|
||||
ENV SLAPD_PASSWORD=password
|
||||
ENV SLAPD_CONFIG_PASSWORD=password
|
||||
ENV SLAPD_ADDITIONAL_MODULES=memberof
|
||||
ENV SLAPD_ADDITIONAL_SCHEMAS=openldap
|
||||
ENV SLAPD_FORCE_RECONFIGURE=true
|
||||
|
||||
ADD base.ldif /etc/ldap.dist/prepopulate/base.ldif
|
||||
ADD access.rules /etc/ldap.dist/prepopulate/access.rules
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ldap
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: ldap
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ldap
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ldap
|
||||
spec:
|
||||
containers:
|
||||
- name: ldap
|
||||
image: clems4ever/authelia-test-ldap
|
||||
ports:
|
||||
- containerPort: 389
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ldap-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: ldap
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 389
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mailcatcher
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: mailcatcher
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mailcatcher
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mailcatcher
|
||||
spec:
|
||||
containers:
|
||||
- name: mailcatcher
|
||||
image: schickling/mailcatcher
|
||||
ports:
|
||||
- containerPort: 1025
|
||||
- containerPort: 1080
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: mailcatcher-ingress
|
||||
namespace: authelia
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "nginx"
|
||||
spec:
|
||||
rules:
|
||||
- host: mail.kube.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: mailcatcher-service
|
||||
servicePort: 1080
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mailcatcher-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: mailcatcher
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 1080
|
||||
name: ui
|
||||
- protocol: TCP
|
||||
port: 1025
|
||||
name: smtp
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: authelia
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mongo
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: mongo
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mongo
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mongo
|
||||
spec:
|
||||
containers:
|
||||
- name: mongo
|
||||
image: mongo:3.4
|
||||
ports:
|
||||
- containerPort: 27017
|
||||
volumeMounts:
|
||||
- name: data-volume
|
||||
mountPath: /data/db
|
||||
- name: config-volume
|
||||
mountPath: /data/configdb
|
||||
volumes:
|
||||
- name: data-volume
|
||||
hostPath:
|
||||
path: /data/storage/mongo/data
|
||||
- name: config-volume
|
||||
hostPath:
|
||||
path: /data/storage/mongo/config
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mongo-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: mongo
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 27017
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis
|
||||
namespace: authelia
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: redis:3.2.11-alpine
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: redis-service
|
||||
namespace: authelia
|
||||
spec:
|
||||
selector:
|
||||
app: redis
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 6379
|
|
@ -1,9 +0,0 @@
|
|||
version: '2'
|
||||
services:
|
||||
nginx-backend:
|
||||
image: nginx:alpine
|
||||
volumes:
|
||||
- ./example/nginx/backend/html:/usr/share/nginx/html
|
||||
- ./example/nginx/backend/nginx.conf:/etc/nginx/nginx.conf
|
||||
networks:
|
||||
- example-network
|
Binary file not shown.
After Width: | Height: | Size: 280 KiB |
|
@ -4,14 +4,14 @@ set -e
|
|||
|
||||
docker-compose \
|
||||
-f docker-compose.yml \
|
||||
-f example/docker-compose.base.yml \
|
||||
-f example/authelia/docker-compose.dev.yml \
|
||||
-f example/mongo/docker-compose.yml \
|
||||
-f example/redis/docker-compose.yml \
|
||||
-f example/nginx/authelia/docker-compose.yml \
|
||||
-f example/nginx/backend/docker-compose.yml \
|
||||
-f example/nginx/portal/docker-compose.yml \
|
||||
-f example/smtp/docker-compose.yml \
|
||||
-f example/httpbin/docker-compose.yml \
|
||||
-f example/ldap/docker-compose.admin.yml \
|
||||
-f example/ldap/docker-compose.yml $*
|
||||
-f example/compose/docker-compose.base.yml \
|
||||
-f example/compose/authelia/docker-compose.dev.yml \
|
||||
-f example/compose/mongo/docker-compose.yml \
|
||||
-f example/compose/redis/docker-compose.yml \
|
||||
-f example/compose/nginx/authelia/docker-compose.yml \
|
||||
-f example/compose/nginx/backend/docker-compose.yml \
|
||||
-f example/compose/nginx/portal/docker-compose.yml \
|
||||
-f example/compose/smtp/docker-compose.yml \
|
||||
-f example/compose/httpbin/docker-compose.yml \
|
||||
-f example/compose/ldap/docker-compose.admin.yml \
|
||||
-f example/compose/ldap/docker-compose.yml $*
|
||||
|
|
|
@ -4,12 +4,12 @@ set -e
|
|||
|
||||
docker-compose \
|
||||
-f docker-compose.yml \
|
||||
-f example/docker-compose.base.yml \
|
||||
-f example/mongo/docker-compose.yml \
|
||||
-f example/redis/docker-compose.yml \
|
||||
-f example/nginx/authelia/docker-compose.yml \
|
||||
-f example/nginx/backend/docker-compose.yml \
|
||||
-f example/nginx/portal/docker-compose.yml \
|
||||
-f example/smtp/docker-compose.yml \
|
||||
-f example/httpbin/docker-compose.yml \
|
||||
-f example/ldap/docker-compose.yml $*
|
||||
-f example/compose/docker-compose.base.yml \
|
||||
-f example/compose/mongo/docker-compose.yml \
|
||||
-f example/compose/redis/docker-compose.yml \
|
||||
-f example/compose/nginx/authelia/docker-compose.yml \
|
||||
-f example/compose/nginx/backend/docker-compose.yml \
|
||||
-f example/compose/nginx/portal/docker-compose.yml \
|
||||
-f example/compose/smtp/docker-compose.yml \
|
||||
-f example/compose/httpbin/docker-compose.yml \
|
||||
-f example/compose/ldap/docker-compose.yml $*
|
||||
|
|
|
@ -4,12 +4,12 @@ set -e
|
|||
|
||||
docker-compose \
|
||||
-f docker-compose.dockerhub.yml \
|
||||
-f example/docker-compose.base.yml \
|
||||
-f example/mongo/docker-compose.yml \
|
||||
-f example/redis/docker-compose.yml \
|
||||
-f example/nginx/authelia/docker-compose.yml \
|
||||
-f example/nginx/backend/docker-compose.yml \
|
||||
-f example/nginx/portal/docker-compose.yml \
|
||||
-f example/smtp/docker-compose.yml \
|
||||
-f example/httpbin/docker-compose.yml \
|
||||
-f example/ldap/docker-compose.yml $*
|
||||
-f example/compose/docker-compose.base.yml \
|
||||
-f example/compose/mongo/docker-compose.yml \
|
||||
-f example/compose/redis/docker-compose.yml \
|
||||
-f example/compose/nginx/authelia/docker-compose.yml \
|
||||
-f example/compose/nginx/backend/docker-compose.yml \
|
||||
-f example/compose/nginx/portal/docker-compose.yml \
|
||||
-f example/compose/smtp/docker-compose.yml \
|
||||
-f example/compose/httpbin/docker-compose.yml \
|
||||
-f example/compose/ldap/docker-compose.yml $*
|
||||
|
|
|
@ -20,8 +20,9 @@ function redirectToSecondFactorPage(req: express.Request, res: express.Response)
|
|||
if (!redirectUrl)
|
||||
res.redirect(Endpoints.SECOND_FACTOR_GET);
|
||||
else
|
||||
res.redirect(Util.format("%s?redirect=%s", Endpoints.SECOND_FACTOR_GET,
|
||||
encodeURIComponent(redirectUrl)));
|
||||
res.redirect(Util.format("%s?%s=%s", Endpoints.SECOND_FACTOR_GET,
|
||||
Constants.REDIRECT_QUERY_PARAM,
|
||||
redirectUrl));
|
||||
}
|
||||
|
||||
function redirectToService(req: express.Request, res: express.Response) {
|
||||
|
|
|
@ -75,7 +75,7 @@ export default function (vars: ServerVariables) {
|
|||
let newRedirectUrl = Endpoint.SECOND_FACTOR_GET;
|
||||
if (redirectUrl) {
|
||||
newRedirectUrl += "?" + Constants.REDIRECT_QUERY_PARAM + "="
|
||||
+ encodeURIComponent(redirectUrl);
|
||||
+ redirectUrl;
|
||||
}
|
||||
vars.logger.debug(req, "Redirect to '%s'", newRedirectUrl);
|
||||
res.send({
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
|
||||
import express = require("express");
|
||||
import { AuthenticationSessionHandler } from "../../AuthenticationSessionHandler";
|
||||
import Constants = require("../../../../../shared/constants");
|
||||
import { ServerVariables } from "../../ServerVariables";
|
||||
|
||||
export default function(req: express.Request, res: express.Response) {
|
||||
const redirect_param = req.query.redirect;
|
||||
const redirect_url = redirect_param || "/";
|
||||
AuthenticationSessionHandler.reset(req);
|
||||
res.redirect(redirect_url);
|
||||
function getRedirectParam(req: express.Request) {
|
||||
return req.query[Constants.REDIRECT_QUERY_PARAM] != "undefined"
|
||||
? req.query[Constants.REDIRECT_QUERY_PARAM]
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export default function (vars: ServerVariables) {
|
||||
return function(req: express.Request, res: express.Response) {
|
||||
const redirect_param = getRedirectParam(req);
|
||||
const redirect_url = redirect_param || "/";
|
||||
AuthenticationSessionHandler.reset(req);
|
||||
res.redirect(redirect_url);
|
||||
};
|
||||
}
|
|
@ -6,6 +6,7 @@ import { ServerVariables } from "../../ServerVariables";
|
|||
import GetWithSessionCookieMethod from "./get_session_cookie";
|
||||
import GetWithBasicAuthMethod from "./get_basic_auth";
|
||||
import Constants = require("../../../../../shared/constants");
|
||||
import ObjectPath = require("object-path");
|
||||
|
||||
import { AuthenticationSessionHandler }
|
||||
from "../../AuthenticationSessionHandler";
|
||||
|
@ -30,8 +31,9 @@ function verifyWithSelectedMethod(req: Express.Request, res: Express.Response,
|
|||
|
||||
function setRedirectHeader(req: Express.Request, res: Express.Response) {
|
||||
return function () {
|
||||
res.set("Redirect", encodeURIComponent("https://" + req.headers["host"] +
|
||||
req.headers["x-original-uri"]));
|
||||
const originalUrl = ObjectPath.get<Express.Request, string>(
|
||||
req, "headers.x-original-url");
|
||||
res.set("Redirect", originalUrl);
|
||||
return BluebirdPromise.resolve();
|
||||
};
|
||||
}
|
||||
|
|
|
@ -14,12 +14,12 @@ export default function (req: Express.Request, res: Express.Response,
|
|||
let username: string;
|
||||
let groups: string[];
|
||||
let domain: string;
|
||||
let path: string;
|
||||
let originalUri: string;
|
||||
|
||||
return new BluebirdPromise<[string, string]>(function (resolve, reject) {
|
||||
const host = ObjectPath.get<Express.Request, string>(req, "headers.host");
|
||||
domain = DomainExtractor.fromHostHeader(host);
|
||||
path =
|
||||
const originalUrl = ObjectPath.get<Express.Request, string>(req, "headers.x-original-url");
|
||||
domain = DomainExtractor.fromUrl(originalUrl);
|
||||
originalUri =
|
||||
ObjectPath.get<Express.Request, string>(req, "headers.x-original-uri");
|
||||
const authenticationMethod =
|
||||
MethodCalculator.compute(vars.config.authentication_methods, domain);
|
||||
|
@ -59,7 +59,7 @@ export default function (req: Express.Request, res: Express.Response,
|
|||
})
|
||||
.then(function (groupsAndEmails) {
|
||||
groups = groupsAndEmails.groups;
|
||||
return AccessControl(req, vars, domain, path, username, groups);
|
||||
return AccessControl(req, vars, domain, originalUri, username, groups);
|
||||
})
|
||||
.then(function () {
|
||||
return BluebirdPromise.resolve({
|
||||
|
|
|
@ -51,7 +51,7 @@ export default function (req: Express.Request, res: Express.Response,
|
|||
let username: string;
|
||||
let groups: string[];
|
||||
let domain: string;
|
||||
let path: string;
|
||||
let originalUri: string;
|
||||
|
||||
return new BluebirdPromise(function (resolve, reject) {
|
||||
username = authSession.userid;
|
||||
|
@ -64,15 +64,15 @@ export default function (req: Express.Request, res: Express.Response,
|
|||
return;
|
||||
}
|
||||
|
||||
const host = ObjectPath.get<Express.Request, string>(req, "headers.host");
|
||||
path =
|
||||
const originalUrl = ObjectPath.get<Express.Request, string>(req, "headers.x-original-url");
|
||||
originalUri =
|
||||
ObjectPath.get<Express.Request, string>(req, "headers.x-original-uri");
|
||||
|
||||
domain = DomainExtractor.fromHostHeader(host);
|
||||
domain = DomainExtractor.fromUrl(originalUrl);
|
||||
const authenticationMethod =
|
||||
MethodCalculator.compute(vars.config.authentication_methods, domain);
|
||||
vars.logger.debug(req, "domain=%s, path=%s, user=%s, groups=%s", domain,
|
||||
path, username, groups.join(","));
|
||||
vars.logger.debug(req, "domain=%s, request_uri=%s, user=%s, groups=%s", domain,
|
||||
originalUri, username, groups.join(","));
|
||||
|
||||
if (!authSession.first_factor)
|
||||
return reject(new Exceptions.AccessDeniedError(
|
||||
|
@ -87,7 +87,7 @@ export default function (req: Express.Request, res: Express.Response,
|
|||
resolve();
|
||||
})
|
||||
.then(function () {
|
||||
return AccessControl(req, vars, domain, path, username, groups);
|
||||
return AccessControl(req, vars, domain, originalUri, username, groups);
|
||||
})
|
||||
.then(function () {
|
||||
return verify_inactivity(req, authSession,
|
||||
|
|
|
@ -3,9 +3,4 @@ export class DomainExtractor {
|
|||
if (!url) return "";
|
||||
return url.match(/https?:\/\/([^\/:]+).*/)[1];
|
||||
}
|
||||
|
||||
static fromHostHeader(host: string): string {
|
||||
if (!host) return "";
|
||||
return host.split(":")[0];
|
||||
}
|
||||
}
|
|
@ -129,7 +129,7 @@ export class RestApi {
|
|||
RequireValidatedFirstFactor.middleware(vars.logger),
|
||||
SecondFactorGet.default(vars));
|
||||
|
||||
app.get(Endpoints.LOGOUT_GET, LogoutGet.default);
|
||||
app.get(Endpoints.LOGOUT_GET, LogoutGet.default(vars));
|
||||
|
||||
app.get(Endpoints.VERIFY_GET, VerifyGet.default(vars));
|
||||
app.post(Endpoints.FIRST_FACTOR_POST, FirstFactorPost.default(vars));
|
||||
|
|
|
@ -27,7 +27,7 @@ describe("test /api/verify endpoint", function () {
|
|||
redirect: "undefined"
|
||||
};
|
||||
AuthenticationSessionHandler.reset(req as any);
|
||||
req.headers.host = "secret.example.com";
|
||||
req.headers["x-original-url"] = "https://secret.example.com/";
|
||||
const s = ServerVariablesMockBuilder.build(false);
|
||||
mocks = s.mocks;
|
||||
vars = s.variables;
|
||||
|
@ -130,7 +130,7 @@ describe("test /api/verify endpoint", function () {
|
|||
authSession.first_factor = true;
|
||||
authSession.second_factor = true;
|
||||
authSession.userid = "myuser";
|
||||
req.headers.host = "test.example.com";
|
||||
req.headers["x-original-url"] = "https://test.example.com/";
|
||||
mocks.accessController.isAccessAllowedMock.returns(false);
|
||||
|
||||
return test_unauthorized_403({
|
||||
|
@ -147,7 +147,7 @@ describe("test /api/verify endpoint", function () {
|
|||
|
||||
describe("given user tries to access a single factor endpoint", function () {
|
||||
beforeEach(function () {
|
||||
req.headers["host"] = "redirect.url";
|
||||
req.headers["x-original-url"] = "https://redirect.url/";
|
||||
mocks.config.authentication_methods.per_subdomain_methods = {
|
||||
"redirect.url": "single_factor"
|
||||
};
|
||||
|
@ -238,7 +238,7 @@ describe("test /api/verify endpoint", function () {
|
|||
mocks.ldapAuthenticator.authenticateStub.rejects(new Error(
|
||||
"Invalid credentials"));
|
||||
req.headers["proxy-authorization"] = "Basic am9objpwYXNzd29yZA==";
|
||||
req.query["redirect"] = REDIRECT_URL;
|
||||
req.query["rd"] = REDIRECT_URL;
|
||||
|
||||
return VerifyGet.default(vars)(req as express.Request, res as any)
|
||||
.then(function () {
|
||||
|
|
|
@ -18,16 +18,4 @@ describe("test DomainExtractor", function () {
|
|||
Assert.equal(domain, "www.example.com");
|
||||
});
|
||||
});
|
||||
|
||||
describe("test fromHostHeader", function () {
|
||||
it("should return domain when default port is used", function () {
|
||||
const domain = DomainExtractor.fromHostHeader("www.example.com");
|
||||
Assert.equal(domain, "www.example.com");
|
||||
});
|
||||
|
||||
it("should return domain when non default port is used", function () {
|
||||
const domain = DomainExtractor.fromHostHeader("www.example.com:8080");
|
||||
Assert.equal(domain, "www.example.com");
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1 +1 @@
|
|||
export const REDIRECT_QUERY_PARAM = "redirect";
|
||||
export const REDIRECT_QUERY_PARAM = "rd";
|
|
@ -2,7 +2,7 @@ Feature: User has access restricted access to domains
|
|||
|
||||
@need-registered-user-john
|
||||
Scenario: User john has admin access
|
||||
When I visit "https://login.example.com:8080?redirect=https%3A%2F%2Fhome.example.com%3A8080%2F"
|
||||
When I visit "https://login.example.com:8080?rd=https://home.example.com:8080/"
|
||||
And I login with user "john" and password "password"
|
||||
And I use "REGISTERED" as TOTP token handle
|
||||
And I click on "Sign in"
|
||||
|
@ -20,7 +20,7 @@ Feature: User has access restricted access to domains
|
|||
|
||||
@need-registered-user-bob
|
||||
Scenario: User bob has restricted access
|
||||
When I visit "https://login.example.com:8080?redirect=https%3A%2F%2Fhome.example.com%3A8080%2F"
|
||||
When I visit "https://login.example.com:8080?rd=https://home.example.com:8080/"
|
||||
And I login with user "bob" and password "password"
|
||||
And I use "REGISTERED" as TOTP token handle
|
||||
And I click on "Sign in"
|
||||
|
@ -38,7 +38,7 @@ Feature: User has access restricted access to domains
|
|||
|
||||
@need-registered-user-harry
|
||||
Scenario: User harry has restricted access
|
||||
When I visit "https://login.example.com:8080?redirect=https%3A%2F%2Fhome.example.com%3A8080%2F"
|
||||
When I visit "https://login.example.com:8080?rd=https://home.example.com:8080/"
|
||||
And I login with user "harry" and password "password"
|
||||
And I use "REGISTERED" as TOTP token handle
|
||||
And I click on "Sign in"
|
||||
|
|
|
@ -3,16 +3,16 @@ Feature: User is redirected when factors are already validated
|
|||
@need-registered-user-john
|
||||
Scenario: User has validated first factor and tries to access service protected by second factor. He is then redirect to second factor step.
|
||||
When I visit "https://single_factor.example.com:8080/secret.html"
|
||||
And I'm redirected to "https://login.example.com:8080/?redirect=https%3A%2F%2Fsingle_factor.example.com%3A8080%2Fsecret.html"
|
||||
And I'm redirected to "https://login.example.com:8080/?rd=https://single_factor.example.com:8080/secret.html"
|
||||
And I login with user "john" and password "password"
|
||||
And I'm redirected to "https://single_factor.example.com:8080/secret.html"
|
||||
And I visit "https://public.example.com:8080/secret.html"
|
||||
Then I'm redirected to "https://login.example.com:8080/secondfactor?redirect=https%3A%2F%2Fpublic.example.com%3A8080%2Fsecret.html"
|
||||
Then I'm redirected to "https://login.example.com:8080/secondfactor?rd=https://public.example.com:8080/secret.html"
|
||||
|
||||
@need-registered-user-john
|
||||
Scenario: User who has validated second factor and access auth portal should be redirected to "Already logged in page" and redirected to default URL declared in configuration
|
||||
When I visit "https://public.example.com:8080/secret.html"
|
||||
And I'm redirected to "https://login.example.com:8080/?redirect=https%3A%2F%2Fpublic.example.com%3A8080%2Fsecret.html"
|
||||
And I'm redirected to "https://login.example.com:8080/?rd=https://public.example.com:8080/secret.html"
|
||||
And I login with user "john" and password "password"
|
||||
And I use "REGISTERED" as TOTP token handle
|
||||
And I click on "Sign in"
|
||||
|
@ -25,10 +25,10 @@ Feature: User is redirected when factors are already validated
|
|||
@need-registered-user-john
|
||||
Scenario: User who has validated second factor and access auth portal with rediction param should be redirected to that URL
|
||||
When I visit "https://public.example.com:8080/secret.html"
|
||||
And I'm redirected to "https://login.example.com:8080/?redirect=https%3A%2F%2Fpublic.example.com%3A8080%2Fsecret.html"
|
||||
And I'm redirected to "https://login.example.com:8080/?rd=https://public.example.com:8080/secret.html"
|
||||
And I login with user "john" and password "password"
|
||||
And I use "REGISTERED" as TOTP token handle
|
||||
And I click on "Sign in"
|
||||
And I'm redirected to "https://public.example.com:8080/secret.html"
|
||||
And I visit "https://login.example.com:8080?redirect=https://public.example.com:8080/secret.html"
|
||||
And I visit "https://login.example.com:8080?rd=https://public.example.com:8080/secret.html"
|
||||
Then I'm redirected to "https://public.example.com:8080/secret.html"
|
||||
|
|
|
@ -5,5 +5,5 @@ Feature: Generic tests on Authelia endpoints
|
|||
Then I get error code 401
|
||||
|
||||
Scenario: /api/verify redirects when redirect parameter is provided
|
||||
When I query "https://authelia.example.com:8080/api/verify?redirect=http://login.example.com:8080"
|
||||
When I query "https://authelia.example.com:8080/api/verify?rd=http://login.example.com:8080"
|
||||
Then I get redirected to "http://login.example.com:8080"
|
|
@ -19,7 +19,7 @@ Feature: Authentication scenarii
|
|||
And I login with user "john" and password "password"
|
||||
And I register a TOTP secret called "Sec0"
|
||||
When I visit "https://admin.example.com:8080/secret.html"
|
||||
And I'm redirected to "https://login.example.com:8080/?redirect=https%3A%2F%2Fadmin.example.com%3A8080%2Fsecret.html"
|
||||
And I'm redirected to "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html"
|
||||
And I login with user "john" and password "password"
|
||||
And I use "Sec0" as TOTP token handle
|
||||
And I click on "Sign in"
|
||||
|
@ -27,12 +27,12 @@ Feature: Authentication scenarii
|
|||
|
||||
Scenario: User fails TOTP second factor
|
||||
When I visit "https://admin.example.com:8080/secret.html"
|
||||
And I'm redirected to "https://login.example.com:8080/?redirect=https%3A%2F%2Fadmin.example.com%3A8080%2Fsecret.html"
|
||||
And I'm redirected to "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html"
|
||||
And I login with user "john" and password "password"
|
||||
And I use "BADTOKEN" as TOTP token
|
||||
And I click on "Sign in"
|
||||
Then I get a notification of type "error" with message "Authentication failed. Have you already registered your secret?"
|
||||
|
||||
Scenario: Logout redirects user to redirect URL given in parameter
|
||||
When I visit "https://login.example.com:8080/logout?redirect=https://home.example.com:8080/"
|
||||
When I visit "https://login.example.com:8080/logout?rd=https://home.example.com:8080/"
|
||||
Then I'm redirected to "https://home.example.com:8080/"
|
||||
|
|
|
@ -2,7 +2,7 @@ Feature: User is correctly redirected
|
|||
|
||||
Scenario: User is redirected to authelia when he is not authenticated
|
||||
When I visit "https://public.example.com:8080"
|
||||
Then I'm redirected to "https://login.example.com:8080/?redirect=https%3A%2F%2Fpublic.example.com%3A8080%2F"
|
||||
Then I'm redirected to "https://login.example.com:8080/?rd=https://public.example.com:8080/"
|
||||
|
||||
@need-registered-user-john
|
||||
Scenario: User is redirected to home page after several authentication tries
|
||||
|
@ -22,7 +22,7 @@ Feature: User is correctly redirected
|
|||
|
||||
Scenario: Redirection URL is propagated from restricted page to first factor
|
||||
When I visit "https://public.example.com:8080/secret.html"
|
||||
Then I'm redirected to "https://login.example.com:8080/?redirect=https%3A%2F%2Fpublic.example.com%3A8080%2Fsecret.html"
|
||||
Then I'm redirected to "https://login.example.com:8080/?rd=https://public.example.com:8080/secret.html"
|
||||
|
||||
Scenario: Redirection URL is propagated from first factor to second factor
|
||||
Given I visit "https://login.example.com:8080/"
|
||||
|
@ -30,7 +30,7 @@ Feature: User is correctly redirected
|
|||
And I register a TOTP secret called "Sec0"
|
||||
When I visit "https://public.example.com:8080/secret.html"
|
||||
And I login with user "john" and password "password"
|
||||
Then I'm redirected to "https://login.example.com:8080/secondfactor?redirect=https%3A%2F%2Fpublic.example.com%3A8080%2Fsecret.html"
|
||||
Then I'm redirected to "https://login.example.com:8080/secondfactor?rd=https://public.example.com:8080/secret.html"
|
||||
|
||||
Scenario: Redirection URL is used to send user from second factor to target page
|
||||
Given I visit "https://login.example.com:8080/"
|
||||
|
|
|
@ -20,7 +20,7 @@ Feature: Authelia regulates authentication to avoid brute force
|
|||
|
||||
@need-registered-user-blackhat
|
||||
Scenario: User is unbanned after a configured amount of time
|
||||
Given I visit "https://login.example.com:8080/?redirect=https%3A%2F%2Fpublic.example.com%3A8080%2Fsecret.html"
|
||||
Given I visit "https://login.example.com:8080/?rd=https://public.example.com:8080/secret.html"
|
||||
And I set field "username" to "blackhat"
|
||||
And I set field "password" to "bad-password"
|
||||
And I click on "Sign in"
|
||||
|
|
|
@ -8,7 +8,7 @@ Feature: Authelia keeps user sessions despite the application restart
|
|||
@need-registered-user-john
|
||||
Scenario: Secrets are stored even when Authelia restarts
|
||||
When the application restarts
|
||||
And I visit "https://admin.example.com:8080/secret.html" and get redirected "https://login.example.com:8080/?redirect=https%3A%2F%2Fadmin.example.com%3A8080%2Fsecret.html"
|
||||
And I visit "https://admin.example.com:8080/secret.html" and get redirected "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html"
|
||||
And I login with user "john" and password "password"
|
||||
And I use "REGISTERED" as TOTP token handle
|
||||
And I click on "Sign in"
|
||||
|
|
|
@ -6,7 +6,7 @@ Feature: Session is closed after a certain amount of time
|
|||
Given I have access to "https://public.example.com:8080/secret.html"
|
||||
When I sleep for 6 seconds
|
||||
And I visit "https://public.example.com:8080/secret.html"
|
||||
Then I'm redirected to "https://login.example.com:8080/?redirect=https%3A%2F%2Fpublic.example.com%3A8080%2Fsecret.html"
|
||||
Then I'm redirected to "https://login.example.com:8080/?rd=https://public.example.com:8080/secret.html"
|
||||
|
||||
@need-authenticated-user-john
|
||||
Scenario: An authenticated user is disconnected after session expiration period
|
||||
|
@ -17,4 +17,4 @@ Feature: Session is closed after a certain amount of time
|
|||
And I visit "https://public.example.com:8080/secret.html"
|
||||
And I sleep for 4 seconds
|
||||
And I visit "https://public.example.com:8080/secret.html"
|
||||
Then I'm redirected to "https://login.example.com:8080/?redirect=https%3A%2F%2Fpublic.example.com%3A8080%2Fsecret.html"
|
||||
Then I'm redirected to "https://login.example.com:8080/?rd=https://public.example.com:8080/secret.html"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue