15
15
-- limitations under the License.
16
16
--
17
17
18
- local core = require (" apisix.core" )
19
- local ngx_re = require (" ngx.re" )
20
- local openidc = require (" resty.openidc" )
21
- local random = require (" resty.random" )
22
- local string = string
23
- local ngx = ngx
24
- local ipairs = ipairs
25
- local type = type
26
- local concat = table.concat
18
+ local core = require (" apisix.core" )
19
+ local ngx_re = require (" ngx.re" )
20
+ local openidc = require (" resty.openidc" )
21
+ local random = require (" resty.random" )
22
+ local jsonschema = require (' jsonschema' )
23
+ local string = string
24
+ local ngx = ngx
25
+ local ipairs = ipairs
26
+ local type = type
27
+ local tostring = tostring
28
+ local pcall = pcall
29
+ local concat = table.concat
27
30
28
31
local ngx_encode_base64 = ngx .encode_base64
29
32
30
- local plugin_name = " openid-connect"
33
+ local plugin_name = " openid-connect"
31
34
32
35
33
36
local schema = {
@@ -317,6 +320,11 @@ local schema = {
317
320
items = {
318
321
type = " string"
319
322
}
323
+ },
324
+ claim_schema = {
325
+ description = " JSON schema of OIDC response claim" ,
326
+ type = " object" ,
327
+ default = nil ,
320
328
}
321
329
},
322
330
encrypt_fields = {" client_secret" , " client_rsa_private_key" },
@@ -331,7 +339,6 @@ local _M = {
331
339
schema = schema ,
332
340
}
333
341
334
-
335
342
function _M .check_schema (conf )
336
343
if conf .ssl_verify == " no" then
337
344
-- we used to set 'ssl_verify' to "no"
@@ -357,10 +364,16 @@ function _M.check_schema(conf)
357
364
return false , err
358
365
end
359
366
367
+ if conf .claim_schema then
368
+ local ok , res = pcall (jsonschema .generate_validator , conf .claim_schema )
369
+ if not ok then
370
+ return false , " check claim_schema failed: " .. tostring (res )
371
+ end
372
+ end
373
+
360
374
return true
361
375
end
362
376
363
-
364
377
local function get_bearer_access_token (ctx )
365
378
-- Get Authorization header, maybe.
366
379
local auth_header = core .request .header (ctx , " Authorization" )
@@ -528,6 +541,18 @@ local function required_scopes_present(required_scopes, http_scopes)
528
541
return true
529
542
end
530
543
544
+ local function validate_claims_in_oidcauth_response (resp , conf )
545
+ if not conf .claim_schema then
546
+ return true
547
+ end
548
+ local data = {
549
+ user = resp .user ,
550
+ access_token = resp .access_token ,
551
+ id_token = resp .id_token ,
552
+ }
553
+ return core .schema .check (conf .claim_schema , data )
554
+ end
555
+
531
556
function _M .rewrite (plugin_conf , ctx )
532
557
local conf = core .table .clone (plugin_conf )
533
558
@@ -682,6 +707,13 @@ function _M.rewrite(plugin_conf, ctx)
682
707
end
683
708
684
709
if response then
710
+ local ok , err = validate_claims_in_oidcauth_response (response , conf )
711
+ if not ok then
712
+ core .log .error (" OIDC claim validation failed: " , err )
713
+ ngx .header [" WWW-Authenticate" ] = ' Bearer realm="' .. conf .realm ..
714
+ ' ", error="invalid_token", error_description="' .. err .. ' "'
715
+ return ngx .HTTP_UNAUTHORIZED
716
+ end
685
717
-- If the openidc module has returned a response, it may contain,
686
718
-- respectively, the access token, the ID token, the refresh token,
687
719
-- and the userinfo.
0 commit comments