Skip to content

Commit 24060da

Browse files
committed
updates
1 parent 971cb8c commit 24060da

File tree

6 files changed

+247
-17
lines changed

6 files changed

+247
-17
lines changed

JSON-File-Server/README.md

+91-14
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,107 @@
1-
# WebDAV and Web File Server With User Database and ACL
1+
# Authentication and Authorization Example
22

3-
This document includes the example 2 source code for the [How to Create a Cloud Storage Server Tutorial](https://makoserver.net/articles/How-to-Create-a-Cloud-Storage-Server#udb). This example is compatible with any [BAS](https://realtimelogic.com/products/barracuda-application-server/) derivative product with a file system, including the Mako Server and Xedge32.
3+
This example shows how to enable both authentication and authorization using an Access Control List (ACL). The **Barracuda App Server (BAS)** provides several API functions for managing authentication and, optionally, authorization. See the [authenticator documentation](https://realtimelogic.com/ba/doc/en/lua/lua.html#auth_overview) for details.
44

5-
Run the example, using the Mako Server, as follows:
5+
## Authentication vs. Authorization
66

7-
```
7+
- **Authentication** verifies the identity of a user.
8+
- **Authorization** determines what resources a user can access after authentication.
9+
10+
While applications may implement their own ACL directly, this example utilizes both authentication and authorization APIs provided by BAS. We use the easy-to-use **[JSON Authenticator](https://realtimelogic.com/ba/doc/en/lua/lua.html#ba_create_jsonuser)**, which includes an optional authorizer that assigns permissions based on the following:
11+
- The authenticated user
12+
- A predefined set of URIs
13+
- The HTTP method used
14+
15+
## File Server Integration
16+
17+
This example applies the combined authenticator and authorizer to a **[File Server object](https://realtimelogic.com/ba/doc/en/lua/lua.html#ba_create_wfs)**, which integrates:
18+
- **WebDAV**, enabling file management through WebDAV clients.
19+
- **Web File Manager**, allowing users to browse and manage files through a web interface.
20+
21+
For details on using WebDAV, refer to the tutorial [How to Create a Cloud Storage Server](https://makoserver.net/articles/How-to-Create-a-Cloud-Storage-Server).
22+
23+
**Note:** The **JSON Authenticator** is not restricted to use with a **File Server** object. It can also be used in standard web applications, offering an easy to implement authentication mechanism. Additionally, its built-in authorization capabilities provide a convenient way to manage access control within your application.
24+
25+
26+
## User Database and ACL Configuration
27+
28+
The user database and ACL setup are also covered in the tutorial **How to Create a Cloud Storage**, section **[Creating a User Database](https://makoserver.net/articles/How-to-Create-a-Cloud-Storage-Server#udb)**.
29+
30+
To keep the example concise, user credentials and ACL rules are **hardcoded** within the [.preload](www/.preload) script.
31+
32+
## Authentication and Authorization
33+
34+
### HTTP Digest Authentication
35+
36+
This example uses **[HTTP Digest Authentication](https://realtimelogic.com/ba/doc/en/authentication.html#authtypes)**, which prompts users for credentials via a browser pop-up. Note that:
37+
- Browsers **cache** the HTTP credentials until they are completely closed.
38+
- Some browsers may keep processes in memory even after closing all windows, retaining authentication.
39+
40+
### Hardcoded User Credentials
41+
42+
The following credentials are preconfigured in this example:
43+
44+
| Username | Password |
45+
|----------|----------|
46+
| guest | guest |
47+
| kids | kids |
48+
| mom | mom |
49+
| dad | dad |
50+
51+
52+
### Server-Side Authentication via request:login()
53+
54+
This example also shows how to use the [request:login()](https://realtimelogic.com/ba/doc/en/lua/lua.html#request_login) method, which allows server-side code to authenticate a user without relying on **HTTP authentication** or the web-based authentication mechanisms provided by **BAS**. This method is designed for integrating authentication systems not natively supported by the server, such as **[Single Sign-On](../fs-sso/README.md) (SSO)** or **WebAuthn**.
55+
56+
#### Using `request:login()` with an Authorizer
57+
58+
In this example, `request:login()` is used alongside an **authorizer**. When an authorizer is enabled:
59+
- `request:login()` **must** be called with valid user credentials.
60+
- Attempting to log in without arguments or with a non-existent user will be denied.
61+
62+
The `index.lsp` page demonstrates this by allowing authentication with the registered users: **mom, dad, kids, and guest**. It also provides options to:
63+
- Attempt authentication with `nil` (Lua's equivalent of "no value").
64+
- Logging in as an unregistered user.
65+
66+
When using an unregistered user, authentication succeeds, but the authorizer **blocks access** and returns a "No Access" message.
67+
68+
#### Testing Without an Authorizer
69+
70+
The included `mako.conf` file contains a setting that is read by the `.preload` script. This setting allows you to **disable the authorizer** for testing purposes. Without an authorizer, `request:login()` grants access to the protected **File Server** resource regardless of the username provided.
71+
72+
73+
74+
75+
## How to Use the Example
76+
77+
This example is designed to run on the **[Mako Server](https://makoserver.net/download/overview/)**. To start the example, navigate to the project directory and launch the server with the following command:
78+
79+
```sh
880
cd JSON-File-Server
981
mako -l::www
1082
```
1183

1284
For detailed instructions on starting the Mako Server, please refer to our [Mako Server command line video tutorial](https://youtu.be/vwQ52ZC5RRg) and review the [server's command line options](https://realtimelogic.com/ba/doc/?url=Mako.html#loadapp) in our documentation.
1385

14-
Once you've successfully started the Mako Server, open a web browser and go to http://localhost:portno/fs/, where 'portno' represents the HTTP port number used by the Mako Server (this number is displayed in the console).
86+
Once you have successfully started the Mako Server, open a web browser and navigate to http://localhost:portno, where 'portno' represents the HTTP port number used by the Mako Server (this number is displayed in the console).
1587

16-
To access the system, use the following login credentials:
88+
On this page, you can:
89+
- **Access the File Server** at `fs/` and log in using **HTTP Digest Authentication**.
90+
- **Test `request:login()`** to authenticate users programmatically.
1791

18-
| Username | Password |
19-
|----------|----------|
20-
| guest | guest |
21-
| kids | kids |
22-
| mom | mom |
23-
| dad | dad |
92+
Try the different login methods and observe how authentication works. When using **HTTP Digest Authentication**, the browser's login dialog will prompt for credentials - enter one of the **usernames and passwords** [listed above](#hardcoded-user-credentials).
2493

25-
For guidance on how to map the WebDAV drive, watch this instructional video: https://youtu.be/i5ubScGwUOc
94+
After testing the login methods, stop the server and open [mako.conf](mako.conf) in an editor, remove the comment to disable the authorizer, and re-start the server.
2695

27-
Please be aware that this application does not contain any web pages or resources except for the WebDAV/file-server installed at /fs/. Additional information can be found in the www/.preload Lua script.
96+
## Files in the `www` Directory
2897

98+
- **`.preload`** - The [.preload startup script](https://realtimelogic.com/ba/doc/en/Mako.html#preload) configures the **authenticator** and **authorizer** using hardcoded values. It initializes a **File Server instance** and integrates it into the **[Virtual File System](https://realtimelogic.com/ba/doc/en/VirtualFileSystem.html) (VFS)**. Additionally, the script sets up a directory structure on your hard drive for use by the File Server.
2999

100+
- **`index.lsp`** - Provides navigation options:
101+
- Access the **File Server** at `fs/` and log in using **Digest Authentication**.
102+
- Authenticate using `request:login()`.
103+
- If already authenticated, accessing this page will redirect you to `logout.lsp`.
30104

105+
- **`logout.lsp`** - Handles user logout:
106+
- Logs the user out and redirects the users back to `index.lsp`, except for those using **Digest Authentication** (due to browser-based credential caching).
107+
- Displays additional logout-related details when not redirected.

JSON-File-Server/mako.conf

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
-- Remove comment below to disable
3+
-- authorize=false

JSON-File-Server/www/.preload

+10-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ local maxUploads = mako and 200 or 10 -- Assume resource constr. if not mako
2727
local maxLocks=100
2828
require"wfs" -- install ba.create.wfs
2929
local fsdir=ba.create.wfs("fs",10,wdio,ldir,maxUploads,maxLocks)
30+
fsdir:configure{logouturi=dir:baseuri().."logout.lsp"}
3031
fsdir:insert() -- Insert as a root node with name 'fs' in the VFS
3132

3233
-- Create the user db with the users: guest, kids, dad, and mom.
@@ -70,8 +71,15 @@ authuser:set(createUserDB())
7071
local authenticator=ba.create.authenticator(authuser)
7172

7273
-- Create the authorizer and install the constraints.
73-
local authorizer=authuser:authorizer()
74-
authorizer:set(createConstraints())
74+
local authorizer
75+
local authorize = false ~= require"loadconf".authorize or false
76+
if authorize then
77+
authorizer=authuser:authorizer()
78+
authorizer:set(createConstraints())
79+
trace"Installing authorizer"
80+
else
81+
trace"Authorizer not installed!!!"
82+
end
7583

7684
-- Install the authenticator and the ACL
7785
fsdir:setauth(authenticator,authorizer)

JSON-File-Server/www/index.lsp

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
2+
<?lsp
3+
4+
if request:user() then
5+
response:sendredirect"logout.lsp"
6+
end
7+
8+
local username=request:data"username"
9+
if username and "POST" == request:method() then
10+
if "nil" == username then
11+
username=nil
12+
trace"Setting username to nil"
13+
end
14+
trace(string.format("Auto logging in using the username '%s'",username))
15+
if request:login(username) then
16+
response:sendredirect"fs/"
17+
else
18+
trace"Cannot login"
19+
response:sendredirect""
20+
end
21+
end
22+
?>
23+
24+
25+
<!DOCTYPE html>
26+
<html lang="en">
27+
<head>
28+
<meta charset="UTF-8">
29+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
30+
<title>Auto Login</title>
31+
<style>
32+
body {
33+
font-family: Arial, sans-serif;
34+
display: flex;
35+
justify-content: center;
36+
align-items: center;
37+
height: 100vh;
38+
background-color: #f4f4f4;
39+
}
40+
.login-container {
41+
background: white;
42+
padding: 20px;
43+
border-radius: 10px;
44+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
45+
text-align: center;
46+
}
47+
select, button {
48+
padding: 10px;
49+
margin-top: 10px;
50+
font-size: 16px;
51+
}
52+
li{
53+
list-style: none;
54+
text-align: left;
55+
margin-bottom:5px;
56+
57+
}
58+
li::before{
59+
content: "\1F882";
60+
61+
}
62+
li
63+
</style>
64+
</head>
65+
<body>
66+
<div class="login-container">
67+
<h2>Two Login Options:</h2>
68+
<ul>
69+
<li><a href="fs/">Navigate to the File Server</a> and log in using HTTP Digest Authentication</li>
70+
<li>Select a user below to auto-login via <code>request:login(username)</code></li>
71+
</ul>
72+
73+
<h2>Auto Login</h2>
74+
<form method="POST" action="">
75+
<select id="userSelect" name="username">
76+
<option value="mom">Mom</option>
77+
<option value="dad">Dad</option>
78+
<option value="kids">Kids</option>
79+
<option value="guest">Guest</option>
80+
<option value="anonymous">Anonymous</option>
81+
<option value="nil">(nil)</option>
82+
</select>
83+
<br>
84+
<button type="submit">Login</button>
85+
</form>
86+
</div>
87+
</body>
88+
</html>

JSON-File-Server/www/logout.lsp

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?lsp
2+
3+
local user,_,authtype=request:user()
4+
5+
request:logout(true)
6+
7+
trace("Authenticator type:", "?" == authtype and "request:login()" or authtype)
8+
9+
if not user or "digest" ~= authtype then
10+
response:sendredirect"./"
11+
end
12+
13+
?>
14+
<!DOCTYPE html>
15+
<html lang="en">
16+
<head>
17+
<meta charset="UTF-8">
18+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
19+
<title>Cannot Log Out</title>
20+
<style>
21+
body {
22+
font-family: Arial, sans-serif;
23+
display: flex;
24+
justify-content: center;
25+
align-items: center;
26+
height: 100vh;
27+
background-color: #f4f4f4;
28+
}
29+
.message-container {
30+
background: white;
31+
padding: 20px;
32+
border-radius: 10px;
33+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
34+
max-width:500px;
35+
}
36+
h2{text-align: center;}
37+
</style>
38+
</head>
39+
<body>
40+
<div class="message-container">
41+
<h2>Cannot Log Out</h2>
42+
<p>You are using HTTP Digest Authentication and logged in as '<?lsp=user?>'. Even though you have been logged out on the server side, your browser will automatically re-authenticate when you navigate back to the <a href="fs/">File Server</a>.</p>
43+
<p>HTTP authentication credentials are cached by your browser until you fully close all browser windows. Be aware that some browsers may remain in memory even after all visible windows are closed.</p>
44+
<p>You can return to the <a href="./">main index page</a> and log in using the auto-login option. Additionally, you can switch users by selecting a different auto-login option, instantly assuming their identity. Automatic HTTP authentication occurs only when accessing the File Server while not already logged in on the server side.</p>
45+
</div>
46+
</body>
47+
</html>
48+

fs-sso/README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Follow these steps to configure your application in the Azure portal:
3636
5. Set the account type to **Single tenant** (in most cases).
3737
6. Click on **Select a platform** and choose **Web**.
3838
7. For the redirect URI, include all relevant sites (e.g., test sites).
39-
For testing purposes, you can use `http://localhost`.
39+
For testing purposes, you can use `http://localhost`. For deployment, see [Redirect URI Requirements](#redirect-uri-requirements).
4040
8. Click **Register** at the bottom of the page.
4141
9. On the following page, copy and save both the **Application (client)
4242
ID** and the **Directory (tenant) ID**.
@@ -252,3 +252,9 @@ sso = ssoModule.init(openid, login [, log])
252252
- `nil, errorMessage, errorCodes`
253253
+ **errorMessage:** A string detailing the error, which can be presented to the user.
254254
+ **errorCodes:** An array of [error codes](https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes) returned by MS Entra. The index.lsp example page manages the two error codes 7000215 and 7000222 related to invalid client secret.
255+
256+
## Redirect URI Requirements
257+
258+
For testing purposes, using HTTP on `localhost` is acceptable. However, in real-world deployments, MS Entra mandates using HTTPS to redirect URI. This requirement ensures that all communications are securely encrypted and that sensitive authentication tokens remain protected during transmission.
259+
260+
When deploying your product/device in a production environment, you must ensure that your web server is configured to use HTTPS and, more importantly, that the browser trusts the server certificate. One option is to use a technology like [SharkTrust](https://realtimelogic.com/services/SharkTrust/), which provides DNS and trusted certificates specifically designed for Intranet web servers. Alternatively, you can implement a similar solution that offers trusted certificate management for your Intranet deployment environment.

0 commit comments

Comments
 (0)