Skip to content

Commit 0208ad1

Browse files
committed
feat: add "valid_issuers" field in openidc plugin
1 parent 4c7918f commit 0208ad1

File tree

2 files changed

+199
-3
lines changed

2 files changed

+199
-3
lines changed

apisix/plugins/openid-connect.lua

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,14 @@ local schema = {
275275
items = {
276276
type = "string"
277277
}
278-
}
278+
},
279+
valid_issuers = {
280+
description = "Whitelist the vetted issuers of the jwt",
281+
type = "array",
282+
items = {
283+
type = "string"
284+
}
285+
},
279286
},
280287
encrypt_fields = {"client_secret", "client_rsa_private_key"},
281288
required = {"client_id", "client_secret", "discovery"}
@@ -384,8 +391,22 @@ local function introspect(ctx, conf)
384391
-- It is inefficient that we also need to extract it (just from headers)
385392
-- so we can add it in the configured header. Find a way to use openidc
386393
-- module's internal methods to extract the token.
387-
local res, err = openidc.bearer_jwt_verify(conf)
388-
394+
local valid_issuers
395+
local opts = {}
396+
if conf.valid_issuers then
397+
valid_issuers = conf.valid_issuers
398+
else
399+
local discovery, discovery_err = openidc.get_discovery_doc(conf)
400+
if discovery_err then
401+
core.log.warn("OIDC access discovery url failed : ", discovery_err)
402+
else
403+
valid_issuers = {discovery.issuer}
404+
end
405+
end
406+
if valid_issuers then
407+
opts.valid_issuers = valid_issuers
408+
end
409+
local res, err = openidc.bearer_jwt_verify(conf, opts)
389410
if err then
390411
-- Error while validating or token invalid.
391412
ngx.header["WWW-Authenticate"] = 'Bearer realm="' .. conf.realm ..

t/plugin/openid-connect7.t

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
use t::APISIX 'no_plan';
18+
19+
log_level('debug');
20+
repeat_each(1);
21+
no_long_string();
22+
no_root_location();
23+
# no_shuffle();
24+
25+
add_block_preprocessor(sub {
26+
my ($block) = @_;
27+
28+
if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
29+
$block->set_value("no_error_log", "[error]");
30+
}
31+
32+
if (!defined $block->request) {
33+
$block->set_value("request", "GET /t");
34+
}
35+
my $http_config = $block->http_config // <<_EOC_;
36+
37+
server {
38+
listen 8089;
39+
40+
location /realms/University/.well-known/openid-configuration {
41+
content_by_lua_block {
42+
ngx.say("{
43+
"issuer": "https://securetoken.google.com/test-firebase-project",
44+
"jwks_uri": "https://www.googleapis.com/service_accounts/v1/jwk/securetoken\@system.gserviceaccount.com",
45+
"response_types_supported": [
46+
"id_token"
47+
],
48+
"subject_types_supported": [
49+
"public"
50+
],
51+
"id_token_signing_alg_values_supported": [
52+
"RS256"
53+
]
54+
}")
55+
}
56+
}
57+
}
58+
_EOC_
59+
60+
$block->set_value("http_config", $http_config);
61+
});
62+
63+
run_tests();
64+
65+
__DATA__
66+
67+
=== TEST 1: Check configuration of cookie
68+
--- config
69+
location /t {
70+
content_by_lua_block {
71+
local test_cases = {
72+
{
73+
client_id = "course_management",
74+
client_secret = "tbsmDOpsHwdgIqYl2NltGRTKzjIzvEmT",
75+
discovery = "http://127.0.0.1:8089/realms/University/.well-known/openid-configuration",
76+
session = {
77+
secret = "6S8IO+Pydgb33LIor8T9ClER0T/sglFAjClFeAF3RsY=",
78+
cookie = {
79+
lifetime = 86400
80+
}
81+
}
82+
},
83+
}
84+
local plugin = require("apisix.plugins.openid-connect")
85+
for _, case in ipairs(test_cases) do
86+
local ok, err = plugin.check_schema(case)
87+
ngx.say(ok and "done" or err)
88+
end
89+
}
90+
}
91+
--- response_body
92+
done
93+
94+
95+
96+
=== TEST 2: Set up new route with wrong valid_issuers
97+
--- config
98+
location /t {
99+
content_by_lua_block {
100+
local t = require("lib.test_admin").test
101+
local code, body = t('/apisix/admin/routes/1',
102+
ngx.HTTP_PUT,
103+
[[{
104+
"plugins": {
105+
"openid-connect": {
106+
"client_id": "dummy",
107+
"client_secret": "dummy",
108+
"discovery": "http://127.0.0.1:8080/realms/University/.well-known/openid-configuration",
109+
"ssl_verify": true,
110+
"timeout": 10,
111+
"bearer_only": true,
112+
"use_jwks": true,
113+
"valid_issuers": 123
114+
}
115+
},
116+
"upstream": {
117+
"nodes": {
118+
"127.0.0.1:1980": 1
119+
},
120+
"type": "roundrobin"
121+
},
122+
"uri": "/*"
123+
}]]
124+
)
125+
126+
if code >= 300 then
127+
ngx.status = code
128+
end
129+
ngx.say(body)
130+
}
131+
}
132+
--- error_code: 400
133+
--- response_body eval
134+
qr/\{"error_msg":"failed to check the configuration of plugin openid-connect err: property \\"valid_issuers\\" validation failed.*"\}/
135+
136+
137+
138+
=== TEST 3: Set up new route with valid valid_issuers
139+
--- config
140+
location /t {
141+
content_by_lua_block {
142+
local t = require("lib.test_admin").test
143+
local code, body = t('/apisix/admin/routes/1',
144+
ngx.HTTP_PUT,
145+
[[{
146+
"plugins": {
147+
"openid-connect": {
148+
"client_id": "dummy",
149+
"client_secret": "dummy",
150+
"discovery": "http://127.0.0.1:8080/realms/University/.well-known/openid-configuration",
151+
"ssl_verify": true,
152+
"timeout": 10,
153+
"bearer_only": true,
154+
"use_jwks": true,
155+
"valid_issuers": ["https://securetoken.google.com/test-firebase-project"]
156+
}
157+
},
158+
"upstream": {
159+
"nodes": {
160+
"127.0.0.1:1980": 1
161+
},
162+
"type": "roundrobin"
163+
},
164+
"uri": "/*"
165+
}]]
166+
)
167+
168+
if code >= 300 then
169+
ngx.status = code
170+
end
171+
ngx.say(body)
172+
}
173+
}
174+
--- response_body
175+
passed

0 commit comments

Comments
 (0)