Software / code / prosody-modules
Changeset
6325:6ea80b73d8f2
mod_http_oauth2: Only require redirect URIs when using grant types that need it
In the Device flow, no redirect URI is used because the client instead
receives responses by polling. It is therefore unnecessary to enforce a
requirement that these include redirect URI(s).
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Thu, 03 Jul 2025 15:42:42 +0200 |
| parents | 6324:5dc4ec836ce2 |
| children | 6326:17d9533f7596 |
| files | mod_http_oauth2/mod_http_oauth2.lua |
| diffstat | 1 files changed, 30 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/mod_http_oauth2/mod_http_oauth2.lua Thu Jul 03 15:34:57 2025 +0200 +++ b/mod_http_oauth2/mod_http_oauth2.lua Thu Jul 03 15:42:42 2025 +0200 @@ -375,7 +375,13 @@ end local function get_redirect_uri(client, query_redirect_uri) -- record client, string : string - if not query_redirect_uri then + if query_redirect_uri == device_uri and client.grant_types then + if array_contains(client.grant_types, device_uri) then + return query_redirect_uri; + end + -- Tried to use device authorization flow without registering it. + return; + elseif not query_redirect_uri and client.redirect_uris then if #client.redirect_uris ~= 1 then -- Client registered multiple URIs, it needs specify which one to use return; @@ -383,15 +389,6 @@ -- When only a single URI is registered, that's the default return client.redirect_uris[1]; end - if query_redirect_uri == device_uri and client.grant_types then - for _, grant_type in ipairs(client.grant_types) do - if grant_type == device_uri then - return query_redirect_uri; - end - end - -- Tried to use device authorization flow without registering it. - return; - end -- Verify the client-provided URI matches one previously registered for _, redirect_uri in ipairs(client.redirect_uris) do if query_redirect_uri == redirect_uri then @@ -1288,8 +1285,6 @@ -- These are shown to users in the template "client_name"; "client_uri"; - -- We need at least one redirect URI for things to work - "redirect_uris"; }; properties = { redirect_uris = { @@ -1306,8 +1301,10 @@ "http://localhost:8080/redirect"; "com.example.app:/redirect"; oob_uri; - device_uri; }; + ["not"] = { + const = device_uri; + } }; }; token_endpoint_auth_method = { @@ -1479,9 +1476,12 @@ return nil, oauth_error("invalid_client_metadata", "Missing, invalid or insecure client_uri"); end - if not client_metadata.application_type and redirect_uri_allowed(client_metadata.redirect_uris[1], client_uri, "native") then - client_metadata.application_type = "native"; - -- else defaults to "web" + if not client_metadata.application_type then + if client_metadata.redirect_uris and redirect_uri_allowed(client_metadata.redirect_uris[1], client_uri, "native") then + client_metadata.application_type = "native"; + elseif array_contains(client_metadata.grant_types, device_uri) then + client_metadata.application_type = "native"; + end end -- Fill in default values @@ -1498,9 +1498,11 @@ end end - for _, redirect_uri in ipairs(client_metadata.redirect_uris) do - if not redirect_uri_allowed(redirect_uri, client_uri, client_metadata.application_type) then - return nil, oauth_error("invalid_redirect_uri", "Invalid, insecure or inappropriate redirect URI."); + if client_metadata.redirect_uris then + for _, redirect_uri in ipairs(client_metadata.redirect_uris) do + if not redirect_uri_allowed(redirect_uri, client_uri, client_metadata.application_type) then + return nil, oauth_error("invalid_redirect_uri", "Invalid, insecure or inappropriate redirect URI."); + end end end @@ -1521,6 +1523,15 @@ return nil, oauth_error("invalid_client_metadata", "Disallowed 'response_types' specified"); end + + if not client_metadata.redirect_uris then + if grant_types:contains("authorization_code") then + return nil, oauth_error("invalid_client_metadata", "The 'authorization_code' grant requires 'redirect_uris' to be present."); + elseif grant_types:contains("implicit") then + return nil, oauth_error("invalid_client_metadata", "The 'implicit' grant requires 'redirect_uris' to be present."); + end + end + if grant_types:contains("authorization_code") and not response_types:contains("code") then return nil, oauth_error("invalid_client_metadata", "Inconsistency between 'grant_types' and 'response_types'"); elseif grant_types:contains("implicit") and not response_types:contains("token") then