/
README
145 lines (107 loc) · 4.59 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
mod_auth_cookie for lighttpd
=== NOTE ===
This module is now renamed to "mod_auth_ticket" and development
page has moved to
https://github.com/tai/mod-auth-ticket-for-lighttpd
You can upgrade to mod_auth_ticket just by renaming directive in
lighttpd.conf from "auth-cookie" to "auth-ticket".
=== What is it? ===
This is a lighttpd module that
1) controls access to web page by cookie authentication, and
2) maps cookie content into HTTP Basic Authentication header.
Initial goal of this module was to map OpenID/SSO mechanism
onto HTTP BasicAuth mechanism, so I can move various legacy
HTTP-BA based services under the hood of Google Accounts SSO.
=== How does it work? ===
This module does not verify user identity, but simply checks
if UA has supplied verifiable authorization data in a cookie.
Once verified, this module accepts whatever was in that
encrypted cookie as user identity.
Since embedding plain username/password in a cookie is a
big NO-NO, this data is encrypted and signed by its issuer,
in many case, external OpenID RP logon page.
Typical session works as follows:
1. User tries to access protected page ("Page#1").
2. mod_auth_cookie checks for a cookie, and finds no
verifiable cookie exists. So it redirects UA to
external logon page ("Page#2").
3. At Page#2, the user is guided to OpenID SSO logon,
and comes back to Page#2 with verified identity.
4. At Page#2, verified identity is encrypted and signed
with shared key between Page#1 and #2, and finally
redirected back to Page#1.
5. mod_auth_cookie traps access to Page#1, and examines
cookie. Once verified, identity will be cached and
random token is generated as a replacement cookie
for given identity.
6. mod_auth_cookie overwrites cookie with previously-
generated token, so further UA access will not
contain identity info.
7. mod_auth_cookie maps identity info to HTTP-BA header, so
legacy webapps can recognize user identity.
8. Finally, the user is now allowed to view Page#1.
This is a lengthly process, but this trampoline-like flow is
needed to map complex OpenID-like authentication onto HTTP-BA
mechanism.
I first planned to implement mod_auth_openid which provides
OpenID RP feature directly, but abandoned as it'd be much
flexible to handle it in web application code. This modules
provides minimal feature needed by external OpenID RP to
inject identity information to HTTP-BA layer.
=== Configuration ===
$HTTP["url"] =~ "^/secret/" {
auth-cookie.loglevel = 255
# Ignore incoming Authorization: header
auth-cookie.override = 2
# Life-duration of generated auth token
auth-cookie.timeout = 3600
# Cookie name and option to use
auth-cookie.name = "TestAuth"
auth-cookie.options = "path=/;"
# URL of logon page to redirect to in case of unverified cookie
# Redirected URL will have a form of "/login.php?url=original-url"
auth-cookie.authurl = "/login.php"
# Shared key used to encrypt and sign cookie payload
auth-cookie.key = "shared-secret"
}
=== How to encrypt and sign cookie ===
Following is a sample code for generating verifiable auth
cookie using PHP.
<?php
// check identity
if (! check_user($_POST["username"], $POST["password"])) {
header("Location: login.php");
exit(0);
}
// core encryption functionality (basically an XOR)
function encrypt($buf, $key, $keylen) {
$n = strlen($buf);
for ($i = 0; $i < $n; $i++) {
$c = ord($buf[$i]);
$c ^= ($i > 0 ? ord($buf[$i - 1]) : 0) ^ ord($key[$i % $keylen]);
$buf[$i] = chr($c);
}
return $buf;
}
# create time-based temporal key for encryption/sign
$key = "shared-secret";
$now = time();
$now = $now - $now % 5;
$tmp = md5($now . $key, TRUE);
# encrypt and sign
$plaintext = base64_encode($_POST["username"] . ":dummytext");
$encrypted = bin2hex(encrypt($plaintext, $tmp, strlen($tmp)));
$signature = md5($key . $now . $encrypted);
$totaldata = "crypt:" . $signature . ":" . $encrypted;
# set as cookie, so mod_auth_cookie willl see it in further use
setcookie("TestAuth", $totaldata, 0, "/", "", FALSE, TRUE);
# redirect back to original protected page
header("Location: /protected/page.php");
?>
=== TODO/WISHLIST ===
- Clean up string/buffer handling
- Should clean up expired entries to free memory
- Introducing "srp:" cookie (encryption with Secure Remote Password)
- Allow authinfo injection using URL (for distributed auth)
- Add demo in other programming languages
- Make it compatible with Apache mod_auth_tkt/mod_auth_pubtkt.