Annotate

plugins/mod_tokenauth.lua @ 12694:26a004c96ef8

util.paseto: Implementation of PASETO v4.public tokens PASETO provides an alternative to JWT with the promise of fewer implementation pitfalls. The v4.public algorithm allows asymmetric cryptographically-verified token issuance and validation. In summary, such tokens can be issued by one party and securely verified by any other party independently using the public key of the issuer. This has a number of potential applications in a decentralized network and ecosystem such as XMPP. For example, such tokens could be combined with XEP-0317 to allow hats to be verified even in the context of a third-party MUC service.
author Matthew Wild <mwild1@gmail.com>
date Fri, 24 Jun 2022 17:03:28 +0100
parent 12662:07424992d7fc
child 12742:126aefd2c4c6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local id = require "util.id";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 local jid = require "util.jid";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local base64 = require "util.encodings".base64;
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
4 local usermanager = require "core.usermanager";
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
5 local generate_identifier = require "util.id".short;
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 local token_store = module:open_store("auth_tokens", "map");
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
9 local function select_role(username, host, role)
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
10 if role then
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
11 return prosody.hosts[host].authz.get_role_by_name(role);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
12 end
12662
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12649
diff changeset
13 return usermanager.get_user_role(username, host);
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
14 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
15
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
16 function create_jid_token(actor_jid, token_jid, token_role, token_ttl)
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 token_jid = jid.prep(token_jid);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 if not actor_jid or token_jid ~= actor_jid and not jid.compare(token_jid, actor_jid) then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 return nil, "not-authorized";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 local token_username, token_host, token_resource = jid.split(token_jid);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 if token_host ~= module.host then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 return nil, "invalid-host";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 local token_info = {
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 owner = actor_jid;
10675
5efd6865486c mod_tokenauth: Track creation time of tokens
Matthew Wild <mwild1@gmail.com>
parents: 10674
diff changeset
30 created = os.time();
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 expires = token_ttl and (os.time() + token_ttl) or nil;
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 jid = token_jid;
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
34 resource = token_resource;
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
35 role = token_role;
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 };
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 local token_id = id.long();
10674
4459afac4d13 mod_tokenauth: Handle tokens issued to bare hosts (eg components)
Kim Alvefur <zash@zash.se>
parents: 10669
diff changeset
39 local token = base64.encode("1;"..jid.join(token_username, token_host)..";"..token_id);
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 token_store:set(token_username, token_id, token_info);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 return token, token_info;
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 local function parse_token(encoded_token)
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 local token = base64.decode(encoded_token);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 if not token then return nil; end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 local token_jid, token_id = token:match("^1;([^;]+);(.+)$");
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 if not token_jid then return nil; end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 local token_user, token_host = jid.split(token_jid);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 return token_id, token_user, token_host;
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
54 local function _get_parsed_token_info(token_id, token_user, token_host)
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 if token_host ~= module.host then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 return nil, "invalid-host";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 local token_info, err = token_store:get(token_user, token_id);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 if not token_info then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 if err then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 return nil, "internal-error";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 return nil, "not-authorized";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 if token_info.expires and token_info.expires < os.time() then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 return nil, "not-authorized";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 return token_info
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
74 function get_token_info(token)
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
75 local token_id, token_user, token_host = parse_token(token);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
76 if not token_id then
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
77 return nil, "invalid-token-format";
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
78 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
79 return _get_parsed_token_info(token_id, token_user, token_host);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
80 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
81
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
82 function get_token_session(token, resource)
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
83 local token_id, token_user, token_host = parse_token(token);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
84 if not token_id then
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
85 return nil, "invalid-token-format";
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
86 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
87
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
88 local token_info, err = _get_parsed_token_info(token_id, token_user, token_host);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
89 if not token_info then return nil, err; end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
90
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
91 return {
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
92 username = token_user;
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
93 host = token_host;
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
94 resource = token_info.resource or resource or generate_identifier();
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
95
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
96 role = select_role(token_user, token_host, token_info.role);
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
97 };
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
98 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
99
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
100
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 function revoke_token(token)
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 local token_id, token_user, token_host = parse_token(token);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 if not token_id then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 return nil, "invalid-token-format";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 if token_host ~= module.host then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 return nil, "invalid-host";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 return token_store:set(token_user, token_id, nil);
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 end