Add network criteria in ACLs to specify policy based on network subnet.
parent
3c6e2ae448
commit
8a76b5118d
|
@ -35,7 +35,7 @@ Here is the list of the main available features:
|
|||
* Password reset with identity verification using email.
|
||||
* Single-factor only authentication method available.
|
||||
* Access restriction after too many authentication attempts.
|
||||
* User-defined access control per subdomain and resource.
|
||||
* Fine-grained access control per subdomain, user, resource and network.
|
||||
* Support of [basic authentication] for endpoints protected by single factor.
|
||||
* High-availability using distributed database and KV store.
|
||||
* Compatible with Kubernetes ingress-nginx controller out of the box.
|
||||
|
|
|
@ -140,8 +140,15 @@ access_control:
|
|||
# Rules applied to everyone
|
||||
- domain: public.example.com
|
||||
policy: bypass
|
||||
|
||||
- domain: secure.example.com
|
||||
policy: one_factor
|
||||
# Network based rule, if not provided any network matches.
|
||||
networks:
|
||||
- 192.168.1.0/24
|
||||
- domain: secure.example.com
|
||||
policy: two_factor
|
||||
|
||||
- domain: singlefactor.example.com
|
||||
policy: one_factor
|
||||
|
||||
|
|
|
@ -61,19 +61,8 @@ Here are the versions used for testing in Travis:
|
|||
|
||||
### How am I supposed to access the subdomains of example.com?
|
||||
|
||||
Well, in order to test Authelia, we will fake your browser that example.com is
|
||||
served by your machine. To do that, open */etc/hosts* and append the following
|
||||
lines:
|
||||
|
||||
127.0.0.1 home.example.com
|
||||
127.0.0.1 public.example.com
|
||||
127.0.0.1 secure.example.com
|
||||
127.0.0.1 dev.example.com
|
||||
127.0.0.1 admin.example.com
|
||||
127.0.0.1 mx1.mail.example.com
|
||||
127.0.0.1 mx2.mail.example.com
|
||||
127.0.0.1 singlefactor.example.com
|
||||
127.0.0.1 login.example.com
|
||||
Well, in order to test Authelia, Authelia fakes your browser by adding entries
|
||||
in /etc/hosts when you first source the bootstrap.sh script.
|
||||
|
||||
### What should I do if I want to contribute?
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
version: '2'
|
||||
services:
|
||||
kubernetes:
|
||||
image: nginx:alpine
|
||||
volumes:
|
||||
- ./example/compose/nginx/kubernetes/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./example/compose/nginx/kubernetes/ssl:/etc/ssl
|
||||
networks:
|
||||
authelianet:
|
||||
aliases:
|
||||
- public.example.com
|
||||
- secure.example.com
|
||||
- login.example.com
|
||||
- admin.example.com
|
||||
- dev.example.com
|
||||
- mail.example.com
|
||||
# Set the IP to be able to query on port 443
|
||||
ipv4_address: 192.168.240.100
|
|
@ -0,0 +1,30 @@
|
|||
#
|
||||
# You can find a documented example of configuration in ./docs/proxies/nginx.md.
|
||||
#
|
||||
|
||||
|
||||
worker_processes 1;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
server {
|
||||
listen 8080 ssl;
|
||||
|
||||
resolver 127.0.0.11 ipv6=off;
|
||||
|
||||
ssl_certificate /etc/ssl/server.crt;
|
||||
ssl_certificate_key /etc/ssl/server.key;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
|
||||
location / {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_pass https://192.168.240.1:8080;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICATCCAWoCCQCvH2RvyOshNzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
|
||||
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
|
||||
cyBQdHkgTHRkMB4XDTE3MDExNzIzMTc0M1oXDTE4MDExNzIzMTc0M1owRTELMAkG
|
||||
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
|
||||
IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzZaE
|
||||
4XE1QyFNbrHBHRhSA53anAsJ5mBeG7Om6SdQcZAYahlDWEbtdoY4hy0gPNGcITcW
|
||||
eE+WA+PvNRr7PczKEhneIyUUgV+nrz010fM5JnECPxLTe1oFzl4U8dyYiBpTziNz
|
||||
hiUfq733PRYjcd9BQtcKcN4LdmQvjUHnnQ73TysCAwEAATANBgkqhkiG9w0BAQsF
|
||||
AAOBgQAUFICtbuqXgL4HBRAg7yGbwokoH8Ar1QKZGe+F2WTR8vaDLOYUL7VsltLE
|
||||
EJIGrcfs31nItHOBcLJuflrS8y0CQqes5puRw33LL2usSvO8z2q7JhCx+DSBi6yN
|
||||
RbhcrGOllIdjsrbmd/zAMBVTUyxSisq3Nmk1cZayDvKg+GSAEA==
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,11 @@
|
|||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIBhDCB7gIBADBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh
|
||||
MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEB
|
||||
AQUAA4GNADCBiQKBgQDNloThcTVDIU1uscEdGFIDndqcCwnmYF4bs6bpJ1BxkBhq
|
||||
GUNYRu12hjiHLSA80ZwhNxZ4T5YD4+81Gvs9zMoSGd4jJRSBX6evPTXR8zkmcQI/
|
||||
EtN7WgXOXhTx3JiIGlPOI3OGJR+rvfc9FiNx30FC1wpw3gt2ZC+NQeedDvdPKwID
|
||||
AQABoAAwDQYJKoZIhvcNAQELBQADgYEAmCX60kspIw1Zfb79AQOarFW5Q2K2h5Vx
|
||||
/cRbDyHlKtbmG77EtICccULyqf76B1gNRw5Zq3lSotSUcLzsWcdesXCFDC7k87Qf
|
||||
mpQKPj6GdTYJvdWf8aDwt32tAqWuBIRoAbdx5WbFPPWVfDcm7zDJefBrhNUDH0Qd
|
||||
vcnxjvPMmOM=
|
||||
-----END CERTIFICATE REQUEST-----
|
|
@ -0,0 +1,15 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQDNloThcTVDIU1uscEdGFIDndqcCwnmYF4bs6bpJ1BxkBhqGUNY
|
||||
Ru12hjiHLSA80ZwhNxZ4T5YD4+81Gvs9zMoSGd4jJRSBX6evPTXR8zkmcQI/EtN7
|
||||
WgXOXhTx3JiIGlPOI3OGJR+rvfc9FiNx30FC1wpw3gt2ZC+NQeedDvdPKwIDAQAB
|
||||
AoGBAIwGcfkO30UawJ+daDeF4g5ejI/toM+NYWuiwBNbWJoQl+Bj1o+gt4obvxKq
|
||||
tKNX7OxelepZ4oZB0CIuf2LHQfU6cVGdu//or7nfS2FLBYStopZyL6KorZbkqsj1
|
||||
ikQN4GosJQqaYkexnwjItMFaHaRRX6YnIXp42Jl1glitO3+5AkEA+thn/vwFo24I
|
||||
fC+7ORpmLi+BVAkTuhMm+C6TIV6s64B+A5oQ82OBCYK9YCOWmS6JHHFDrxJla+3M
|
||||
2U9KXky63wJBANHQCFCirfuT6esSjbqpCeqtmZG5LWHtL12V9DF7yjHPjmHL9uRu
|
||||
e9W+Uz33IJbqd82gtZ/ARfpYEjD0JEieQTUCQFo872xzDTQ1qSfDo/5u2MNUo5mv
|
||||
ikEuEp7FYnhmrp4poyt4iRCFgy4Ask+bfdmtO/XXaRnZ7FJfQYoLVB2ITNECQQCN
|
||||
gOiauZztl4yj5heAVJFDnWF9To61BOp1C7VtyjdL8NfuTUluNrV+KqapnAp2vhue
|
||||
q0zTOTH47X0XVxFBiLohAkBuQzPey5I3Ui8inE4sDt/fqX8r/GMhBTxIb9KlV/H6
|
||||
jKZNs/83n5/ohaX36er8svW9PB4pcqENZ+kBpvDtKVwS
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -6,8 +6,12 @@ services:
|
|||
- ./example/compose/nginx/portal/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./example/compose/nginx/portal/ssl:/etc/ssl
|
||||
ports:
|
||||
- "8080:443"
|
||||
- "8080:8080"
|
||||
networks:
|
||||
authelianet:
|
||||
aliases:
|
||||
- public.example.com
|
||||
- secure.example.com
|
||||
- login.example.com
|
||||
# Set the IP to be able to query on port 443
|
||||
ipv4_address: 192.168.240.100
|
||||
|
|
|
@ -12,7 +12,7 @@ events {
|
|||
http {
|
||||
<% if (production) { %>
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen 8080 ssl;
|
||||
server_name login.example.com;
|
||||
|
||||
resolver 127.0.0.11 ipv6=off;
|
||||
|
@ -39,6 +39,10 @@ http {
|
|||
proxy_set_header X-Original-URI $request_uri;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
# Needed for network ACLs to work. It appends the IP of the client to the list of IPs
|
||||
# and allows Authelia to use it to match the network-based ACLs.
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
proxy_intercept_errors on;
|
||||
|
||||
proxy_pass $backend_endpoint;
|
||||
|
@ -46,7 +50,7 @@ http {
|
|||
}
|
||||
<% } else { %>
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen 8080 ssl;
|
||||
server_name login.example.com;
|
||||
|
||||
resolver 127.0.0.11 ipv6=off;
|
||||
|
@ -59,6 +63,22 @@ http {
|
|||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
|
||||
# Serve the backend API for the portal.
|
||||
location /api {
|
||||
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 X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# Needed for network ACLs to work. It appends the IP of the client to the list of IPs
|
||||
# and allows Authelia to use it to match the network-based ACLs.
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
proxy_intercept_errors on;
|
||||
|
||||
proxy_pass $backend_endpoint;
|
||||
}
|
||||
|
||||
# Serves the portal application.
|
||||
location / {
|
||||
# Allow websockets for webpack to auto-reload.
|
||||
|
@ -68,23 +88,12 @@ http {
|
|||
|
||||
proxy_pass $frontend_endpoint;
|
||||
}
|
||||
|
||||
# Serve the backend API for the portal.
|
||||
location /api {
|
||||
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_intercept_errors on;
|
||||
|
||||
proxy_pass $backend_endpoint;
|
||||
}
|
||||
}
|
||||
<% } %>
|
||||
|
||||
# Serves the home page.
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen 8080 ssl;
|
||||
server_name home.example.com;
|
||||
|
||||
resolver 127.0.0.11 ipv6=off;
|
||||
|
@ -104,7 +113,7 @@ http {
|
|||
|
||||
# Example configuration of domains protected by Authelia.
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen 8080 ssl;
|
||||
server_name public.example.com
|
||||
admin.example.com
|
||||
secure.example.com
|
||||
|
@ -188,21 +197,9 @@ http {
|
|||
}
|
||||
}
|
||||
|
||||
# Matches all domains. It redirects to the home page.
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name _;
|
||||
|
||||
ssl_certificate /etc/ssl/server.crt;
|
||||
ssl_certificate_key /etc/ssl/server.key;
|
||||
|
||||
return 301 https://home.example.com:8080/;
|
||||
}
|
||||
|
||||
|
||||
# Fake Web Mail used to receive emails sent by Authelia.
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen 8080 ssl;
|
||||
server_name mail.example.com;
|
||||
|
||||
resolver 127.0.0.11 ipv6=off;
|
||||
|
@ -239,5 +236,16 @@ http {
|
|||
proxy_pass $upstream_endpoint;
|
||||
}
|
||||
}
|
||||
|
||||
# Matches all domains. It redirects to the home page.
|
||||
server {
|
||||
listen 8080 ssl;
|
||||
server_name _;
|
||||
|
||||
ssl_certificate /etc/ssl/server.crt;
|
||||
ssl_certificate_key /etc/ssl/server.key;
|
||||
|
||||
return 301 https://home.example.com:8080/;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
version: '2'
|
||||
services:
|
||||
# Simulates client 1.
|
||||
client-1:
|
||||
image: sameersbn/squid:3.5.27-1
|
||||
volumes:
|
||||
- ./example/compose/squid/squid.conf:/etc/squid/squid.conf
|
||||
networks:
|
||||
authelianet:
|
||||
# Set the IP to be able to query on port 443
|
||||
ipv4_address: 192.168.240.201
|
||||
client-2:
|
||||
image: sameersbn/squid:3.5.27-1
|
||||
volumes:
|
||||
- ./example/compose/squid/squid.conf:/etc/squid/squid.conf
|
||||
networks:
|
||||
authelianet:
|
||||
# Set the IP to be able to query on port 443
|
||||
ipv4_address: 192.168.240.202
|
File diff suppressed because it is too large
Load Diff
|
@ -4032,6 +4032,14 @@
|
|||
"integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
|
||||
"dev": true
|
||||
},
|
||||
"ip-range-check": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/ip-range-check/-/ip-range-check-0.0.2.tgz",
|
||||
"integrity": "sha1-YFyFloeqTxhGORjUYZDYs2maKTw=",
|
||||
"requires": {
|
||||
"ipaddr.js": "1.6.0"
|
||||
}
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz",
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
"express-request-id": "^1.4.0",
|
||||
"express-session": "^1.14.2",
|
||||
"helmet": "^3.12.0",
|
||||
"ip-range-check": "0.0.2",
|
||||
"ldapjs": "^1.0.2",
|
||||
"mongodb": "^3.0.5",
|
||||
"nedb": "^1.8.0",
|
||||
|
|
|
@ -39,18 +39,22 @@ async function checkHostsFile() {
|
|||
const actualEntries = fs.readFileSync("/etc/hosts").toString("utf-8")
|
||||
.split("\n").filter(l => l !== '').map(l => l.split(" ").filter(w => w !== ''));
|
||||
|
||||
await checkAndFixEntry(actualEntries, 'login.example.com', '127.0.0.1');
|
||||
await checkAndFixEntry(actualEntries, 'admin.example.com', '127.0.0.1');
|
||||
await checkAndFixEntry(actualEntries, 'singlefactor.example.com', '127.0.0.1');
|
||||
await checkAndFixEntry(actualEntries, 'dev.example.com', '127.0.0.1');
|
||||
await checkAndFixEntry(actualEntries, 'home.example.com', '127.0.0.1');
|
||||
await checkAndFixEntry(actualEntries, 'mx1.mail.example.com', '127.0.0.1');
|
||||
await checkAndFixEntry(actualEntries, 'mx2.mail.example.com', '127.0.0.1');
|
||||
await checkAndFixEntry(actualEntries, 'public.example.com', '127.0.0.1');
|
||||
await checkAndFixEntry(actualEntries, 'secure.example.com', '127.0.0.1');
|
||||
await checkAndFixEntry(actualEntries, 'mail.example.com', '127.0.0.1');
|
||||
|
||||
await checkAndFixEntry(actualEntries, 'login.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'admin.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'singlefactor.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'dev.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'home.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'mx1.mail.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'mx2.mail.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'public.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'secure.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'mail.example.com', '192.168.240.100');
|
||||
await checkAndFixEntry(actualEntries, 'duo.example.com', '192.168.240.100');
|
||||
|
||||
// For testing network ACLs.
|
||||
await checkAndFixEntry(actualEntries, 'proxy-client1.example.com', '192.168.240.201');
|
||||
await checkAndFixEntry(actualEntries, 'proxy-client2.example.com', '192.168.240.202');
|
||||
await checkAndFixEntry(actualEntries, 'proxy-client3.example.com', '192.168.240.203');
|
||||
}
|
||||
|
||||
async function checkKubernetesDependencies() {
|
||||
|
|
|
@ -14,10 +14,10 @@ describe("authorization/Authorizer", function () {
|
|||
configuration = undefined;
|
||||
authorizer = new Authorizer(configuration, winston);
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1", "group2"]}), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/abc"}, {user: "user1", groups: ["group1", "group2"]}), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user2", groups: ["group1", "group2"]}), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "admin.example.com", resource: "/"}, {user: "user3", groups: ["group3"]}), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1", "group2"]}, "127.0.0.1"), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/abc"}, {user: "user1", groups: ["group1", "group2"]}, "127.0.0.1"), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user2", groups: ["group1", "group2"]}, "127.0.0.1"), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "admin.example.com", resource: "/"}, {user: "user3", groups: ["group3"]}, "127.0.0.1"), Level.BYPASS);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -36,7 +36,7 @@ describe("authorization/Authorizer", function () {
|
|||
});
|
||||
|
||||
it("should deny access when no rule is provided", function () {
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
|
||||
it("should control access when multiple domain matcher is provided", function () {
|
||||
|
@ -46,10 +46,10 @@ describe("authorization/Authorizer", function () {
|
|||
subject: "user:user1",
|
||||
resources: [".*"]
|
||||
}];
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "mx1.mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "mx1.server.mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "mx1.mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "mx1.server.mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
|
||||
it("should allow access to all resources when resources is not provided", function () {
|
||||
|
@ -58,10 +58,10 @@ describe("authorization/Authorizer", function () {
|
|||
policy: "two_factor",
|
||||
subject: "user:user1"
|
||||
}];
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "mx1.mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "mx1.server.mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "mx1.mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "mx1.server.mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "mail.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
|
||||
describe("check user rules", function () {
|
||||
|
@ -72,9 +72,9 @@ describe("authorization/Authorizer", function () {
|
|||
resources: [".*"],
|
||||
subject: "user:user1"
|
||||
}];
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/another/resource"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "another.home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/another/resource"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "another.home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
|
||||
it("should deny to other users", function () {
|
||||
|
@ -84,9 +84,9 @@ describe("authorization/Authorizer", function () {
|
|||
resources: [".*"],
|
||||
subject: "user:user1"
|
||||
}];
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user2", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/another/resource"}, {user: "user2", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "another.home.example.com", resource: "/"}, {user: "user2", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user2", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/another/resource"}, {user: "user2", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "another.home.example.com", resource: "/"}, {user: "user2", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
|
||||
it("should allow user access only to specific resources", function () {
|
||||
|
@ -96,16 +96,16 @@ describe("authorization/Authorizer", function () {
|
|||
resources: ["/private/.*", "^/begin", "/end$"],
|
||||
subject: "user:user1"
|
||||
}];
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/class"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/middle/private/class"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/class"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/middle/private/class"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/begin"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/not/begin"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/begin"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/not/begin"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/abc/end"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/abc/end/x"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/abc/end"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/abc/end/x"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
|
||||
it("should allow access to multiple domains", function () {
|
||||
|
@ -125,10 +125,10 @@ describe("authorization/Authorizer", function () {
|
|||
resources: [".*"],
|
||||
subject: "user:user1"
|
||||
}];
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home1.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.ONE_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home2.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home3.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home1.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.ONE_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home2.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home3.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
|
||||
it("should apply rules in order", function () {
|
||||
|
@ -149,9 +149,9 @@ describe("authorization/Authorizer", function () {
|
|||
subject: "user:user1"
|
||||
}];
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/my/poney"}, {user: "user1", groups: ["group1"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/my/private/duck"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/my/private/resource"}, {user: "user1", groups: ["group1"]}), Level.ONE_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/my/poney"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/my/private/duck"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/my/private/resource"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.ONE_FACTOR);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -174,13 +174,13 @@ describe("authorization/Authorizer", function () {
|
|||
subject: "group:group2"
|
||||
}];
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"},
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}), Level.TWO_FACTOR);
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/test"},
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}), Level.ONE_FACTOR);
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}, "127.0.0.1"), Level.ONE_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private"},
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}), Level.DENY);
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "another.home.example.com", resource: "/"},
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}), Level.DENY);
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -197,13 +197,13 @@ describe("authorization/Authorizer", function () {
|
|||
resources: ["^/private$"]
|
||||
}];
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/public"},
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}), Level.BYPASS);
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}, "127.0.0.1"), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private"},
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}), Level.DENY);
|
||||
{user: "user1", groups: ["group1", "group2", "group3"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/public"},
|
||||
{user: "user4", groups: ["group5"]}), Level.BYPASS);
|
||||
{user: "user4", groups: ["group5"]}, "127.0.0.1"), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private"},
|
||||
{user: "user4", groups: ["group5"]}), Level.DENY);
|
||||
{user: "user4", groups: ["group5"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -213,9 +213,9 @@ describe("authorization/Authorizer", function () {
|
|||
});
|
||||
|
||||
it("should allow access to anything when no rule is provided", function () {
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/test"}, {user: "user1", groups: ["group1"]}), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev"}, {user: "user1", groups: ["group1"]}), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/test"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.BYPASS);
|
||||
});
|
||||
|
||||
it("should deny access to one resource when defined", function () {
|
||||
|
@ -225,9 +225,9 @@ describe("authorization/Authorizer", function () {
|
|||
resources: ["/test"],
|
||||
subject: "user:user1"
|
||||
}];
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/test"}, {user: "user1", groups: ["group1"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev"}, {user: "user1", groups: ["group1"]}), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/test"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev"}, {user: "user1", groups: ["group1"]}, "127.0.0.1"), Level.BYPASS);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -267,32 +267,32 @@ describe("authorization/Authorizer", function () {
|
|||
subject: "user:harry"
|
||||
}];
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "admin", groups: ["admins"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/public"}, {user: "admin", groups: ["admins"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev"}, {user: "admin", groups: ["admins"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "admin", groups: ["admins"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/admin"}, {user: "admin", groups: ["admins"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/josh"}, {user: "admin", groups: ["admins"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/john"}, {user: "admin", groups: ["admins"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/harry"}, {user: "admin", groups: ["admins"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "admin", groups: ["admins"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/public"}, {user: "admin", groups: ["admins"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev"}, {user: "admin", groups: ["admins"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "admin", groups: ["admins"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/admin"}, {user: "admin", groups: ["admins"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/josh"}, {user: "admin", groups: ["admins"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/john"}, {user: "admin", groups: ["admins"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/harry"}, {user: "admin", groups: ["admins"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "john", groups: ["dev", "admin-private"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/public"}, {user: "john", groups: ["dev", "admin-private"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev"}, {user: "john", groups: ["dev", "admin-private"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev", "admin-private"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/admin"}, {user: "john", groups: ["dev", "admin-private"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/josh"}, {user: "john", groups: ["dev", "admin-private"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/john"}, {user: "john", groups: ["dev", "admin-private"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/harry"}, {user: "john", groups: ["dev", "admin-private"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "john", groups: ["dev", "admin-private"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/public"}, {user: "john", groups: ["dev", "admin-private"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev"}, {user: "john", groups: ["dev", "admin-private"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev", "admin-private"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/admin"}, {user: "john", groups: ["dev", "admin-private"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/josh"}, {user: "john", groups: ["dev", "admin-private"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/john"}, {user: "john", groups: ["dev", "admin-private"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/harry"}, {user: "john", groups: ["dev", "admin-private"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "harry", groups: ["dev"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/public"}, {user: "harry", groups: ["dev"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev"}, {user: "harry", groups: ["dev"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "harry", groups: ["dev"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/admin"}, {user: "harry", groups: ["dev"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/josh"}, {user: "harry", groups: ["dev"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/john"}, {user: "harry", groups: ["dev"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/harry"}, {user: "harry", groups: ["dev"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/"}, {user: "harry", groups: ["dev"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/public"}, {user: "harry", groups: ["dev"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev"}, {user: "harry", groups: ["dev"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "harry", groups: ["dev"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/admin"}, {user: "harry", groups: ["dev"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/josh"}, {user: "harry", groups: ["dev"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/john"}, {user: "harry", groups: ["dev"]}, "127.0.0.1"), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/private/harry"}, {user: "harry", groups: ["dev"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
});
|
||||
|
||||
it("should allow when allowed at group level and denied at user level", function () {
|
||||
|
@ -308,8 +308,8 @@ describe("authorization/Authorizer", function () {
|
|||
subject: "group:dev"
|
||||
}];
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/john"}, {user: "john", groups: ["dev"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/john"}, {user: "john", groups: ["dev"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
|
||||
it("should allow access when allowed at 'any' level and denied at user level", function () {
|
||||
|
@ -324,8 +324,8 @@ describe("authorization/Authorizer", function () {
|
|||
resources: ["^/dev/?.*$"]
|
||||
}];
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/john"}, {user: "john", groups: ["dev"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/john"}, {user: "john", groups: ["dev"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
|
||||
it("should allow access when allowed at 'any' level and denied at group level", function () {
|
||||
|
@ -340,8 +340,8 @@ describe("authorization/Authorizer", function () {
|
|||
resources: ["^/dev/?.*$"]
|
||||
}];
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/john"}, {user: "john", groups: ["dev"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}), Level.DENY);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/john"}, {user: "john", groups: ["dev"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}, "127.0.0.1"), Level.DENY);
|
||||
});
|
||||
|
||||
it("should respect rules precedence", function () {
|
||||
|
@ -364,8 +364,36 @@ describe("authorization/Authorizer", function () {
|
|||
resources: ["^/dev/?.*$"]
|
||||
}];
|
||||
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/john"}, {user: "john", groups: ["dev"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/john"}, {user: "john", groups: ["dev"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}, "127.0.0.1"), Level.TWO_FACTOR);
|
||||
});
|
||||
});
|
||||
|
||||
describe("check network rules", function () {
|
||||
beforeEach(function () {
|
||||
configuration.rules = [{
|
||||
domain: "home.example.com",
|
||||
policy: "one_factor",
|
||||
subject: "user:john",
|
||||
networks: ["192.168.0.0/24", "10.0.0.0/8"]
|
||||
},
|
||||
{
|
||||
domain: "home.example.com",
|
||||
policy: "two_factor",
|
||||
subject: "user:john",
|
||||
},
|
||||
{
|
||||
domain: "public.example.com",
|
||||
policy: "bypass",
|
||||
networks: ["10.0.0.0/8"]
|
||||
}];
|
||||
});
|
||||
|
||||
it("should respect network ranges", function() {
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/john"}, {user: "john", groups: ["dev"]}, "192.168.4.1"), Level.TWO_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "home.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}, "192.168.0.5"), Level.ONE_FACTOR);
|
||||
Assert.equal(authorizer.authorization({domain: "public.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}, "10.1.3.0"), Level.BYPASS);
|
||||
Assert.equal(authorizer.authorization({domain: "public.example.com", resource: "/dev/bob"}, {user: "john", groups: ["dev"]}, "11.1.3.0"), Level.DENY);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ import { MultipleDomainMatcher } from "./MultipleDomainMatcher";
|
|||
import { Level } from "./Level";
|
||||
import { Object } from "./Object";
|
||||
import { Subject } from "./Subject";
|
||||
const IpRangeCheck = require("ip-range-check");
|
||||
|
||||
function MatchDomain(actualDomain: string) {
|
||||
return function (rule: ACLRule): boolean {
|
||||
|
@ -44,6 +45,16 @@ function MatchSubject(subject: Subject) {
|
|||
};
|
||||
}
|
||||
|
||||
function MatchNetworks(ip: string) {
|
||||
return (rule: ACLRule): boolean => {
|
||||
if (!rule.networks) return true; // all networks match
|
||||
|
||||
return rule.networks
|
||||
.map(net => IpRangeCheck(ip, net) as boolean)
|
||||
.reduce((acc, v) => acc || v, false);
|
||||
};
|
||||
}
|
||||
|
||||
export class Authorizer implements IAuthorizer {
|
||||
private readonly configuration: ACLConfiguration;
|
||||
|
||||
|
@ -51,13 +62,14 @@ export class Authorizer implements IAuthorizer {
|
|||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
private getMatchingRules(object: Object, subject: Subject): ACLRule[] {
|
||||
private getMatchingRules(object: Object, subject: Subject, ip: string): ACLRule[] {
|
||||
const rules = this.configuration.rules;
|
||||
if (!rules) return [];
|
||||
return rules
|
||||
.filter(MatchDomain(object.domain))
|
||||
.filter(MatchResource(object.resource))
|
||||
.filter(MatchSubject(subject));
|
||||
.filter(MatchSubject(subject))
|
||||
.filter(MatchNetworks(ip));
|
||||
}
|
||||
|
||||
private ruleToLevel(policy: ACLPolicy): Level {
|
||||
|
@ -71,10 +83,10 @@ export class Authorizer implements IAuthorizer {
|
|||
return Level.DENY;
|
||||
}
|
||||
|
||||
authorization(object: Object, subject: Subject): Level {
|
||||
authorization(object: Object, subject: Subject, ip: string): Level {
|
||||
if (!this.configuration) return Level.BYPASS;
|
||||
|
||||
const rules = this.getMatchingRules(object, subject);
|
||||
const rules = this.getMatchingRules(object, subject, ip);
|
||||
|
||||
return (rules.length > 0)
|
||||
? this.ruleToLevel(rules[0].policy) // extract the policy of the first matching rule
|
||||
|
|
|
@ -11,7 +11,7 @@ export default class AuthorizerStub implements IAuthorizer {
|
|||
this.authorizationMock = Sinon.stub();
|
||||
}
|
||||
|
||||
authorization(object: Object, subject: Subject): Level {
|
||||
return this.authorizationMock(object, subject);
|
||||
authorization(object: Object, subject: Subject, ip: string): Level {
|
||||
return this.authorizationMock(object, subject, ip);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@ import { Subject } from "./Subject";
|
|||
import { Object } from "./Object";
|
||||
|
||||
export interface IAuthorizer {
|
||||
authorization(object: Object, subject: Subject): Level;
|
||||
authorization(object: Object, subject: Subject, ip: string): Level;
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
|
||||
export type ACLPolicy = "deny" | "bypass" | "one_factor" | "two_factor";
|
||||
|
||||
export type ACLNetwork = string[];
|
||||
|
||||
export type ACLRule = {
|
||||
domain: string;
|
||||
resources?: string[];
|
||||
subject?: string;
|
||||
policy: ACLPolicy;
|
||||
networks?: ACLNetwork;
|
||||
};
|
||||
|
||||
export interface ACLConfiguration {
|
||||
|
|
|
@ -83,7 +83,7 @@ export default function (vars: ServerVariables) {
|
|||
groups: authSession.groups
|
||||
};
|
||||
|
||||
const authorizationLevel = vars.authorizer.authorization(resObject, subject);
|
||||
const authorizationLevel = vars.authorizer.authorization(resObject, subject, req.ip);
|
||||
if (authorizationLevel <= AuthorizationLevel.ONE_FACTOR) {
|
||||
if (IsRedirectionSafe(vars, new URLParse(targetUrl))) {
|
||||
res.json({redirect: targetUrl});
|
||||
|
|
|
@ -11,21 +11,21 @@ describe('routes/verify/CheckAuthorizations', function() {
|
|||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.BYPASS);
|
||||
CheckAuthorizations(authorizer, "public.example.com", "/index.html", undefined,
|
||||
undefined, Level.NOT_AUTHENTICATED);
|
||||
undefined, "127.0.0.1", Level.NOT_AUTHENTICATED);
|
||||
});
|
||||
|
||||
it('should allow an authenticated user (1FA)', function() {
|
||||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.BYPASS);
|
||||
CheckAuthorizations(authorizer, "public.example.com", "/index.html", "john",
|
||||
["group1", "group2"], Level.ONE_FACTOR);
|
||||
["group1", "group2"], "127.0.0.1", Level.ONE_FACTOR);
|
||||
});
|
||||
|
||||
it('should allow an authenticated user (2FA)', function() {
|
||||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.BYPASS);
|
||||
CheckAuthorizations(authorizer, "public.example.com", "/index.html", "john",
|
||||
["group1", "group2"], Level.TWO_FACTOR);
|
||||
["group1", "group2"], "127.0.0.1", Level.TWO_FACTOR);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -34,21 +34,21 @@ describe('routes/verify/CheckAuthorizations', function() {
|
|||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.ONE_FACTOR);
|
||||
Assert.throws(() => { CheckAuthorizations(authorizer, "public.example.com", "/index.html", undefined,
|
||||
undefined, Level.NOT_AUTHENTICATED) }, NotAuthenticatedError);
|
||||
undefined, "127.0.0.1", Level.NOT_AUTHENTICATED) }, NotAuthenticatedError);
|
||||
});
|
||||
|
||||
it('should allow an authenticated user (1FA)', function() {
|
||||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.ONE_FACTOR);
|
||||
CheckAuthorizations(authorizer, "public.example.com", "/index.html", "john",
|
||||
["group1", "group2"], Level.ONE_FACTOR);
|
||||
["group1", "group2"], "127.0.0.1", Level.ONE_FACTOR);
|
||||
});
|
||||
|
||||
it('should allow an authenticated user (2FA)', function() {
|
||||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.ONE_FACTOR);
|
||||
CheckAuthorizations(authorizer, "public.example.com", "/index.html", "john",
|
||||
["group1", "group2"], Level.TWO_FACTOR);
|
||||
["group1", "group2"], "127.0.0.1", Level.TWO_FACTOR);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -57,21 +57,21 @@ describe('routes/verify/CheckAuthorizations', function() {
|
|||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.TWO_FACTOR);
|
||||
Assert.throws(() => CheckAuthorizations(authorizer, "public.example.com", "/index.html", undefined,
|
||||
undefined, Level.NOT_AUTHENTICATED), NotAuthenticatedError);
|
||||
undefined, "127.0.0.1", Level.NOT_AUTHENTICATED), NotAuthenticatedError);
|
||||
});
|
||||
|
||||
it('should not allow an authenticated user (1FA)', function() {
|
||||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.TWO_FACTOR);
|
||||
Assert.throws(() => CheckAuthorizations(authorizer, "public.example.com", "/index.html", "john",
|
||||
["group1", "group2"], Level.ONE_FACTOR), NotAuthenticatedError);
|
||||
["group1", "group2"], "127.0.0.1", Level.ONE_FACTOR), NotAuthenticatedError);
|
||||
});
|
||||
|
||||
it('should allow an authenticated user (2FA)', function() {
|
||||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.TWO_FACTOR);
|
||||
CheckAuthorizations(authorizer, "public.example.com", "/index.html", "john",
|
||||
["group1", "group2"], Level.TWO_FACTOR);
|
||||
["group1", "group2"], "127.0.0.1", Level.TWO_FACTOR);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -80,21 +80,21 @@ describe('routes/verify/CheckAuthorizations', function() {
|
|||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.DENY);
|
||||
Assert.throws(() => CheckAuthorizations(authorizer, "public.example.com", "/index.html", undefined,
|
||||
undefined, Level.NOT_AUTHENTICATED), NotAuthenticatedError);
|
||||
undefined, "127.0.0.1", Level.NOT_AUTHENTICATED), NotAuthenticatedError);
|
||||
});
|
||||
|
||||
it('should not allow an authenticated user (1FA)', function() {
|
||||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.DENY);
|
||||
Assert.throws(() => CheckAuthorizations(authorizer, "public.example.com", "/index.html", "john",
|
||||
["group1", "group2"], Level.ONE_FACTOR), NotAuthorizedError);
|
||||
["group1", "group2"], "127.0.0.1", Level.ONE_FACTOR), NotAuthorizedError);
|
||||
});
|
||||
|
||||
it('should not allow an authenticated user (2FA)', function() {
|
||||
const authorizer = new AuthorizerStub();
|
||||
authorizer.authorizationMock.returns(AuthorizationLevel.DENY);
|
||||
Assert.throws(() => CheckAuthorizations(authorizer, "public.example.com", "/index.html", "john",
|
||||
["group1", "group2"], Level.TWO_FACTOR), NotAuthorizedError);
|
||||
["group1", "group2"], "127.0.0.1", Level.TWO_FACTOR), NotAuthorizedError);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -25,11 +25,11 @@ function isAuthorized(
|
|||
export default function (
|
||||
authorizer: IAuthorizer,
|
||||
domain: string, resource: string,
|
||||
user: string, groups: string[],
|
||||
user: string, groups: string[], ip: string,
|
||||
authenticationLevel: AuthenticationLevel): AuthorizationLevel {
|
||||
|
||||
const authorizationLevel = authorizer
|
||||
.authorization({domain, resource}, {user, groups});
|
||||
.authorization({domain, resource}, {user, groups}, ip);
|
||||
|
||||
if (authorizationLevel == AuthorizationLevel.BYPASS) {
|
||||
return authorizationLevel;
|
||||
|
|
|
@ -41,7 +41,7 @@ export default async function(req: Express.Request, res: Express.Response,
|
|||
const uri = GetHeader(req, HEADER_X_ORIGINAL_URL);
|
||||
const urlDecomposition = URLDecomposer.fromUrl(uri);
|
||||
const authorizationLevel = CheckAuthorizations(vars.authorizer, urlDecomposition.domain, urlDecomposition.path,
|
||||
username, groupsAndEmails.groups, Level.ONE_FACTOR);
|
||||
username, groupsAndEmails.groups, req.ip, Level.ONE_FACTOR);
|
||||
|
||||
if (authorizationLevel > AuthorizationLevel.BYPASS) {
|
||||
setUserAndGroupsHeaders(res, username, groupsAndEmails.groups);
|
||||
|
|
|
@ -31,9 +31,9 @@ export default async function (req: Express.Request, res: Express.Response,
|
|||
const username = authSession.userid;
|
||||
const groups = authSession.groups;
|
||||
|
||||
vars.logger.debug(req, "domain=%s, path=%s, user=%s, groups=%s", d.domain,
|
||||
d.path, (username) ? username : "unknown", (groups instanceof Array && groups.length > 0) ? groups.join(",") : "unknown");
|
||||
const authorizationLevel = CheckAuthorizations(vars.authorizer, d.domain, d.path, username, groups,
|
||||
vars.logger.debug(req, "domain=%s, path=%s, user=%s, groups=%s, ip=%s", d.domain,
|
||||
d.path, (username) ? username : "unknown", (groups instanceof Array && groups.length > 0) ? groups.join(",") : "unknown", req.ip);
|
||||
const authorizationLevel = CheckAuthorizations(vars.authorizer, d.domain, d.path, username, groups, req.ip,
|
||||
authSession.authentication_level);
|
||||
|
||||
if (authorizationLevel > AuthorizationLevel.BYPASS) {
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
require("chromedriver");
|
||||
import chrome from 'selenium-webdriver/chrome';
|
||||
import SeleniumWebdriver, { WebDriver } from "selenium-webdriver";
|
||||
import SeleniumWebdriver, { WebDriver, ProxyConfig } from "selenium-webdriver";
|
||||
|
||||
export async function StartDriver() {
|
||||
export async function StartDriver(proxy?: ProxyConfig) {
|
||||
let options = new chrome.Options();
|
||||
|
||||
if (process.env['HEADLESS'] == 'y') {
|
||||
options = options.headless();
|
||||
}
|
||||
|
||||
const driver = new SeleniumWebdriver.Builder()
|
||||
.forBrowser("chrome")
|
||||
.setChromeOptions(options)
|
||||
.build();
|
||||
return driver;
|
||||
let driverBuilder = new SeleniumWebdriver.Builder()
|
||||
.forBrowser("chrome");
|
||||
|
||||
if (proxy) {
|
||||
options = options.addArguments(`--proxy-server=${proxy.httpProxy}`)
|
||||
}
|
||||
|
||||
driverBuilder = driverBuilder.setChromeOptions(options);
|
||||
return await driverBuilder.build();
|
||||
}
|
||||
|
||||
export async function StopDriver(driver: WebDriver) {
|
||||
|
|
|
@ -4,7 +4,6 @@ import VerifyIsOneTimePasswordView from "../../../helpers/assertions/VerifyIsOne
|
|||
import ClickOnLink from "../../../helpers/ClickOnLink";
|
||||
import VerifyIsUseAnotherMethodView from "../../../helpers/assertions/VerifyIsUseAnotherMethodView";
|
||||
import ClickOnButton from "../../../helpers/behaviors/ClickOnButton";
|
||||
import VerifyIsSecurityKeyView from "../../../helpers/assertions/VerifyIsSecurityKeyView";
|
||||
import VerifyIsSecondFactorStage from "../../../helpers/assertions/VerifyIsSecondFactorStage";
|
||||
import VerifyIsDuoPushNotificationView from "../../../helpers/assertions/VerifyIsDuoPushNotificationView";
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import { spawn, execSync, ChildProcess } from 'child_process';
|
|||
import treeKill = require('tree-kill');
|
||||
import Redis, { RedisClient } from 'redis';
|
||||
import sleep from '../../helpers/utils/sleep';
|
||||
import DockerEnvironment from '../../helpers/context/DockerEnvironment';
|
||||
|
||||
let portFowardingProcess: ChildProcess;
|
||||
|
||||
|
@ -78,12 +79,20 @@ async function redisReady(kubernetes: Kubernetes): Promise<void> {
|
|||
|
||||
function startAutheliaPortForwarding(kubernetes: Kubernetes) {
|
||||
// Serve applications on port 8080
|
||||
portFowardingProcess = spawn('kubectl',
|
||||
['port-forward', '-n', 'authelia', 'service/nginx-ingress-controller-service', '8080:443'], {
|
||||
portFowardingProcess = spawn('kubectl port-forward --address 0.0.0.0 -n authelia service/nginx-ingress-controller-service 8080:443', {
|
||||
shell: true,
|
||||
env: {KUBECONFIG: kubernetes.kubeConfig, ...process.env}
|
||||
});
|
||||
} as any);
|
||||
portFowardingProcess.stdout.pipe(process.stdout);
|
||||
portFowardingProcess.stderr.pipe(process.stderr);
|
||||
}
|
||||
|
||||
const dockerEnv = new DockerEnvironment([
|
||||
'docker-compose.yml',
|
||||
'example/compose/nginx/kubernetes/docker-compose.yml',
|
||||
]);
|
||||
|
||||
|
||||
async function setup() {
|
||||
let kubernetes: Kubernetes;
|
||||
if (!process.env['KUBECONFIG']) {
|
||||
|
@ -108,6 +117,8 @@ async function setup() {
|
|||
});
|
||||
await servicesReady(kubernetes);
|
||||
|
||||
await dockerEnv.start();
|
||||
|
||||
startAutheliaPortForwarding(kubernetes);
|
||||
}
|
||||
|
||||
|
@ -119,8 +130,10 @@ async function teardown() {
|
|||
await sleep(1000);
|
||||
}
|
||||
|
||||
// if (process.env['KUBECONFIG']) return;
|
||||
// await KubernetesManager.delete();
|
||||
await dockerEnv.stop();
|
||||
|
||||
if (process.env['KUBECONFIG']) return;
|
||||
await KubernetesManager.delete();
|
||||
}
|
||||
|
||||
const setup_timeout = 300000;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# Basic suite
|
||||
|
||||
This suite has been created to test Authelia with basic feature in a non highly-available setup.
|
||||
Authelia basically use an in-memory cache to store user sessions and persist data on disk instead
|
||||
of using a remote database. Also, the user accounts are stored in file-based database.
|
||||
|
||||
## Components
|
||||
|
||||
Authelia, nginx, fake webmail for registering devices.
|
||||
|
||||
## Tests
|
||||
|
||||
Broad range of tests.
|
|
@ -0,0 +1,64 @@
|
|||
###############################################################
|
||||
# Authelia minimal configuration #
|
||||
###############################################################
|
||||
|
||||
port: 9091
|
||||
|
||||
logs_level: debug
|
||||
|
||||
authentication_backend:
|
||||
file:
|
||||
path: ./test/suites/basic/users_database.test.yml
|
||||
|
||||
session:
|
||||
secret: unsecure_session_secret
|
||||
domain: example.com
|
||||
expiration: 3600000 # 1 hour
|
||||
inactivity: 300000 # 5 minutes
|
||||
|
||||
# Configuration of the storage backend used to store data and secrets. i.e. totp data
|
||||
storage:
|
||||
local:
|
||||
path: /tmp/authelia/db
|
||||
|
||||
# Access Control
|
||||
#
|
||||
# Access control is a set of rules you can use to restrict user access to certain
|
||||
# resources.
|
||||
access_control:
|
||||
default_policy: deny
|
||||
rules:
|
||||
- domain: secure.example.com
|
||||
policy: one_factor
|
||||
networks:
|
||||
- 192.168.240.201/32
|
||||
|
||||
- domain: secure.example.com
|
||||
policy: bypass
|
||||
networks:
|
||||
- 192.168.240.202/32
|
||||
- 192.168.240.203/32
|
||||
|
||||
- domain: secure.example.com
|
||||
policy: two_factor
|
||||
|
||||
|
||||
# Configuration of the authentication regulation mechanism.
|
||||
regulation:
|
||||
# Set it to 0 to disable max_retries.
|
||||
max_retries: 3
|
||||
# The user is banned if the authenticaction failed `max_retries` times in a `find_time` seconds window.
|
||||
find_time: 300
|
||||
# The length of time before a banned user can login again.
|
||||
ban_time: 900
|
||||
|
||||
notifier:
|
||||
# Use a SMTP server for sending notifications
|
||||
smtp:
|
||||
username: test
|
||||
password: password
|
||||
secure: false
|
||||
host: 127.0.0.1
|
||||
port: 1025
|
||||
sender: admin@example.com
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import fs from 'fs';
|
||||
import { exec } from "../../helpers/utils/exec";
|
||||
import AutheliaServer from "../../helpers/context/AutheliaServer";
|
||||
import DockerEnvironment from "../../helpers/context/DockerEnvironment";
|
||||
|
||||
const autheliaServer = new AutheliaServer(__dirname + '/config.yml', [__dirname + '/users_database.yml']);
|
||||
const dockerEnv = new DockerEnvironment([
|
||||
'docker-compose.yml',
|
||||
'example/compose/nginx/backend/docker-compose.yml',
|
||||
'example/compose/nginx/portal/docker-compose.yml',
|
||||
'example/compose/squid/docker-compose.yml',
|
||||
'example/compose/smtp/docker-compose.yml',
|
||||
])
|
||||
|
||||
async function setup() {
|
||||
await exec(`cp ${__dirname}/users_database.yml ${__dirname}/users_database.test.yml`);
|
||||
await exec('mkdir -p /tmp/authelia/db');
|
||||
await exec('./example/compose/nginx/portal/render.js ' + (fs.existsSync('.suite') ? '': '--production'));
|
||||
await dockerEnv.start();
|
||||
await autheliaServer.start();
|
||||
}
|
||||
|
||||
async function teardown() {
|
||||
await autheliaServer.stop();
|
||||
await dockerEnv.stop();
|
||||
await exec('rm -rf /tmp/authelia/db');
|
||||
}
|
||||
|
||||
const setup_timeout = 30000;
|
||||
const teardown_timeout = 30000;
|
||||
|
||||
export {
|
||||
setup,
|
||||
setup_timeout,
|
||||
teardown,
|
||||
teardown_timeout
|
||||
};
|
|
@ -0,0 +1,77 @@
|
|||
import { StartDriver, StopDriver } from "../../../helpers/context/WithDriver";
|
||||
import LoginAndRegisterTotp from "../../../helpers/LoginAndRegisterTotp";
|
||||
import FillLoginPageAndClick from "../../../helpers/FillLoginPageAndClick";
|
||||
import ValidateTotp from "../../../helpers/ValidateTotp";
|
||||
import VerifySecretObserved from "../../../helpers/assertions/VerifySecretObserved";
|
||||
import VisitPageAndWaitUrlIs from "../../../helpers/behaviors/VisitPageAndWaitUrlIs";
|
||||
import VerifyUrlIs from "../../../helpers/assertions/VerifyUrlIs";
|
||||
import VisitPage from "../../../helpers/VisitPage";
|
||||
|
||||
async function createClient(id: number) {
|
||||
return await StartDriver({
|
||||
proxyType: "manual",
|
||||
httpProxy: `http://proxy-client${id}.example.com:3128`
|
||||
});
|
||||
}
|
||||
|
||||
export default function() {
|
||||
before(async function() {
|
||||
const driver = await StartDriver();
|
||||
this.secret = await LoginAndRegisterTotp(driver, "john", "password", true);
|
||||
if (!this.secret) throw new Error('No secret!');
|
||||
await StopDriver(driver);
|
||||
});
|
||||
|
||||
describe("Standard client (from public network)", function() {
|
||||
before(async function() {
|
||||
this.driver = await StartDriver();
|
||||
});
|
||||
|
||||
after(async function() {
|
||||
await StopDriver(this.driver);
|
||||
});
|
||||
|
||||
it("should require two factor", async function() {
|
||||
await VisitPage(this.driver, "https://secure.example.com:8080/secret.html");
|
||||
await VerifyUrlIs(this.driver, "https://login.example.com:8080/#/?rd=https://secure.example.com:8080/secret.html");
|
||||
await FillLoginPageAndClick(this.driver, 'john', 'password');
|
||||
await ValidateTotp(this.driver, this.secret);
|
||||
await VerifyUrlIs(this.driver, "https://secure.example.com:8080/secret.html");
|
||||
await VerifySecretObserved(this.driver);
|
||||
});
|
||||
})
|
||||
|
||||
describe("Client 1 (from network 192.168.240.201/32)", function() {
|
||||
before(async function() {
|
||||
this.client1 = await createClient(1);
|
||||
});
|
||||
|
||||
after(async function() {
|
||||
await StopDriver(this.client1);
|
||||
});
|
||||
|
||||
it("should require one factor", async function() {
|
||||
await VisitPage(this.client1, "https://secure.example.com:8080/secret.html");
|
||||
await VerifyUrlIs(this.client1, "https://login.example.com:8080/#/?rd=https://secure.example.com:8080/secret.html");
|
||||
await FillLoginPageAndClick(this.client1, 'john', 'password');
|
||||
await VerifyUrlIs(this.client1, "https://secure.example.com:8080/secret.html");
|
||||
await VerifySecretObserved(this.client1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Client 2 (from network 192.168.240.202/32)", function() {
|
||||
before(async function() {
|
||||
this.client2 = await createClient(2);
|
||||
});
|
||||
|
||||
after(async function() {
|
||||
await StopDriver(this.client2);
|
||||
});
|
||||
|
||||
it("should bypass", async function() {
|
||||
await VisitPageAndWaitUrlIs(this.client2, "https://secure.example.com:8080/secret.html");
|
||||
await VerifyUrlIs(this.client2, "https://secure.example.com:8080/secret.html");
|
||||
await VerifySecretObserved(this.client2);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import AutheliaSuite from "../../helpers/context/AutheliaSuite";
|
||||
import { exec } from '../../helpers/utils/exec';
|
||||
import NetworkACLs from "./scenarii/NetworkACLs";
|
||||
|
||||
AutheliaSuite(__dirname, function() {
|
||||
this.timeout(10000);
|
||||
|
||||
beforeEach(async function() {
|
||||
await exec(`cp ${__dirname}/users_database.yml ${__dirname}/users_database.test.yml`);
|
||||
});
|
||||
|
||||
describe("Network ACLs", NetworkACLs);
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
###############################################################
|
||||
# Users Database #
|
||||
###############################################################
|
||||
|
||||
# This file can be used if you do not have an LDAP set up.
|
||||
|
||||
# List of users
|
||||
users:
|
||||
john:
|
||||
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: john.doe@authelia.com
|
||||
groups:
|
||||
- admins
|
||||
- dev
|
||||
|
||||
harry:
|
||||
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: harry.potter@authelia.com
|
||||
groups: []
|
||||
|
||||
bob:
|
||||
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: bob.dylan@authelia.com
|
||||
groups:
|
||||
- dev
|
||||
|
||||
james:
|
||||
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
|
||||
email: james.dean@authelia.com
|
Loading…
Reference in New Issue