增加应用程序op端点,增加openidc使用的端口,目前为测试数据
This commit is contained in:
parent
a43ee358d8
commit
2cbc0e3d3f
|
|
@ -26,7 +26,7 @@ http {
|
|||
|
||||
#在Nginx启动时执行的Lua代码块
|
||||
#oauth2.0第三方验证后将code放到共享内存中
|
||||
lua_shared_dict codeDict 5m;
|
||||
lua_shared_dict codeDict 10m;
|
||||
#init_by_lua_block {
|
||||
# -- 定义一个全局变量
|
||||
# ngx.log(ngx.INFO, "Initializing global variable")
|
||||
|
|
@ -65,6 +65,25 @@ http {
|
|||
end
|
||||
}
|
||||
|
||||
#OP端点配置
|
||||
location /yum/v1/.well-known/openid-configuration {
|
||||
content_by_lua_block {
|
||||
local cjson = require "cjson"
|
||||
local config = {
|
||||
issuer = "http://localhost:9080",
|
||||
authorization_endpoint = "http://localhost:9080/yum/v1/oauth/v2/authorize",
|
||||
token_endpoint = "http://localhost:9080yum/v1/oauth/v2/token",
|
||||
userinfo_endpoint = "http://localhost:9080yum/v1/oauth/v2/userinfo",
|
||||
--jwks_uri = "http://localhost:9080/jwks", -- 公钥端点(可选)
|
||||
response_types_supported = {"code"},
|
||||
subject_types_supported = {"public"},
|
||||
id_token_signing_alg_values_supported = {"HS256"}
|
||||
}
|
||||
ngx.header["Content-Type"] = "application/json"
|
||||
ngx.say(cjson.encode(config))
|
||||
}
|
||||
}
|
||||
|
||||
#数据列表配置
|
||||
include 'system/system.conf';
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ function _M:authorize()
|
|||
return ngx.exit(ngx.HTTP_BAD_REQUEST)
|
||||
end
|
||||
-- 校验客户端请求参数
|
||||
ok = validator.validatorAuthorize(data)
|
||||
ok = validator.validateAuthorize(data)
|
||||
--验证失败则返回
|
||||
if not ok then
|
||||
return ngx.exit(ngx.HTTP_BAD_REQUEST)
|
||||
|
|
@ -69,9 +69,9 @@ function _M:authorize()
|
|||
return str.to_hex(bytes)
|
||||
end
|
||||
local code = generate_code()
|
||||
print("authorize generate_code:", code)
|
||||
--print("authorize generate_code:", code)
|
||||
-- 5、存储授权码信息(用户ID、客户端ID、scope、生成时间)
|
||||
local code_key = "auth_code:" .. code
|
||||
local code_key = "auth_code-"..code
|
||||
local code_data = cjson.encode({
|
||||
user_id = "123456",
|
||||
client_id = args.client_id,
|
||||
|
|
@ -80,11 +80,16 @@ function _M:authorize()
|
|||
created_at = ngx.time()
|
||||
})
|
||||
local shared_dict = ngx.shared.codeDict
|
||||
shared_dict:set(code_key, code_data, 5 * 60)
|
||||
|
||||
shared_dict:set(code_key, code_data)
|
||||
shared_dict:expire(code_key, 300) --时效性为5分钟
|
||||
--print("token set shared dict key:",code_key)
|
||||
-- 6. 重定向到客户端回调地址,携带授权码和原始 state(防 CSRF)
|
||||
local redirect_url = args.redirect_uri .. "?code=" .. code .. "&state=" .. args.state
|
||||
local result = resp:json(ngx.HTTP_OK, redirect_url)
|
||||
local rest = {}
|
||||
rest.redirect_uri = args.redirect_uri
|
||||
rest.code = code
|
||||
rest.state = args.state
|
||||
local result = resp:json(ngx.HTTP_OK, rest)
|
||||
resp:send(result)
|
||||
return
|
||||
end
|
||||
|
|
@ -94,22 +99,30 @@ function _M:token()
|
|||
-- 1. 解析请求参数(支持 form-data 和 json)
|
||||
local content_type = ngx.req.get_headers()["Content-Type"] or ""
|
||||
local args = {}
|
||||
--print("token content_type:", content_type)
|
||||
if string.find(content_type, "application/json") then
|
||||
local body = ngx.req.get_body_data()
|
||||
if not body then
|
||||
-- 读取请求体的数据
|
||||
ngx.req.read_body()
|
||||
-- 获取请求数据
|
||||
local body_data = ngx.req.get_body_data()
|
||||
if not body_data then
|
||||
return ngx.exit(ngx.HTTP_BAD_REQUEST)
|
||||
end
|
||||
args = cjson.decode(body)
|
||||
-- 验证json数据是否正确
|
||||
local ok, data = pcall(cjson.decode, body_data)
|
||||
if not ok then
|
||||
return ngx.exit(ngx.HTTP_BAD_REQUEST)
|
||||
end
|
||||
args = data
|
||||
else
|
||||
-- 默认解析 form-urlencoded
|
||||
args = ngx.req.get_post_args()
|
||||
end
|
||||
print("args:", args)
|
||||
|
||||
-- 2. 校验必填参数验证数据是否符合json
|
||||
local ok = validator.validatorToken(args)
|
||||
local ok = validator.validateToken(args)
|
||||
--验证失败则返回
|
||||
if not ok then
|
||||
print("validatorToken failed")
|
||||
local result = resp:json(0x000001)
|
||||
resp:send(result)
|
||||
return
|
||||
|
|
@ -117,10 +130,10 @@ function _M:token()
|
|||
|
||||
-- 4. 校验 code 有效性
|
||||
local code = args.code
|
||||
local code_key = "auth_code:" .. code
|
||||
local code_key = "auth_code-"..code
|
||||
local shared_dict = ngx.shared.codeDict
|
||||
local code_data = shared_dict:get(code_key)
|
||||
if code_data ~= nil then
|
||||
if code_data == nil then
|
||||
-- code 超出时效,需要重新获取code
|
||||
--local result = resp:json(0x000001)
|
||||
--resp:send(result)
|
||||
|
|
@ -129,12 +142,17 @@ function _M:token()
|
|||
resp:send(result)
|
||||
return
|
||||
end
|
||||
--print("token code_data:", code_data)
|
||||
local jsonData = cjson.decode(code_data)
|
||||
-- 5、验证redirect_url地址的正确性
|
||||
local request_uri = code_data["request_uri"]
|
||||
local request_uri = jsonData.redirect_uri
|
||||
print("token request_uri:", request_uri)
|
||||
if request_uri ~= args.redirect_url then
|
||||
--print("token redirect_url:", request_uri, args.redirect_url)
|
||||
local login_url = "/login?redirect=" .. ngx.escape_uri(request_uri)
|
||||
local result = resp:json(ngx.HTTP_MOVED_TEMPORARILY, login_url)
|
||||
resp:send(result)
|
||||
return
|
||||
end
|
||||
-- 验证成功删除
|
||||
shared_dict:delete(code_key)
|
||||
|
|
@ -142,14 +160,18 @@ function _M:token()
|
|||
-- 6. 生成密钥对
|
||||
local pub_key, priv_key, err = rsa.generate_rsa_keys(2048)
|
||||
if err then
|
||||
print("密钥生成失败: ", err)
|
||||
--print("密钥生成失败: ", err)
|
||||
local result = resp:json(0x00001)
|
||||
resp:send(result)
|
||||
return
|
||||
end
|
||||
local user_id = code_data["user_id"]
|
||||
local client_id = code_data["client_id"]
|
||||
local scope = code_data["scope"]
|
||||
print("token pubkey:", pub_key)
|
||||
local user_id = jsonData.user_id
|
||||
--print("token user_id:", user_id)
|
||||
local client_id = jsonData.client_id
|
||||
--print("token client_id:", client_id)
|
||||
local scope = jsonData.scope
|
||||
--print("token scope:", scope)
|
||||
local access_token_ttl = 10 * 60 --十分钟
|
||||
local refresh_token_ttl = 7 * 24 * 3600 --7天
|
||||
-- 7 生成新 Access Token
|
||||
|
|
@ -225,13 +247,12 @@ function _M:login()
|
|||
--验证json数据是否正确
|
||||
local ok, data = pcall(cjson.decode, body_data)
|
||||
if not ok then
|
||||
print("JSON解析失败:", data)
|
||||
local result = resp:json(0x000001)
|
||||
resp:send(result)
|
||||
return
|
||||
end
|
||||
-- 验证数据是否符合json
|
||||
local valid, errors = validator.validatorLogin(data)
|
||||
local valid, errors = validator.validateLogin(data)
|
||||
--验证失败则返回
|
||||
if not valid then
|
||||
local result = resp:json(0x000001)
|
||||
|
|
@ -265,18 +286,62 @@ end
|
|||
|
||||
--根据Access-Token获取相应用户的账户信息
|
||||
function _M:userinfo()
|
||||
--读取请求体的数据
|
||||
ngx.req.read_body()
|
||||
--获取请求数据
|
||||
local body_data = ngx.req.get_body_data()
|
||||
-- 验证数据是否符合json
|
||||
local ok = validator.validatorUserinfo(body_data)
|
||||
--验证失败则返回
|
||||
--获取用户认证数据信息
|
||||
local auth_header = ngx.var.http_Authorization
|
||||
|
||||
--如果请求头中没有令牌,则直接返回401
|
||||
if auth_header == nil or auth_header == "" then
|
||||
ngx.log(ngx.WARN, "没有找到令牌数据")
|
||||
ngx.status = ngx.HTTP_UNAUTHORIZED
|
||||
ngx.exit(ngx.HTTP_UNAUTHORIZED)
|
||||
end
|
||||
|
||||
--查找令牌中的Bearer前缀字符
|
||||
local data = {}
|
||||
data.Authorization = auth_header
|
||||
local ok = validator.validateUserinfo(data)
|
||||
if not ok then
|
||||
local result = resp:json(0x000001)
|
||||
ngx.log(ngx.WARN, "令牌格式不正确")
|
||||
ngx.status = ngx.HTTP_UNAUTHORIZED
|
||||
ngx.exit(ngx.HTTP_UNAUTHORIZED)
|
||||
end
|
||||
--获取token的数据值
|
||||
local token = string.sub(auth_header,8)
|
||||
--校验令牌
|
||||
local pub_key, priv_key, err = rsa.generate_rsa_keys(2048)
|
||||
if err then
|
||||
--print("密钥生成失败: ", err)
|
||||
local result = resp:json(0x00001)
|
||||
resp:send(result)
|
||||
return
|
||||
end
|
||||
print("userinfo pubkey:", pub_key)
|
||||
local jwt_obj = jwt:verify(pub_key, token)
|
||||
--如果校验结果中的verified==false,则表示令牌无效
|
||||
if jwt_obj.verified == false then
|
||||
ngx.log(ngx.WARN, "Invalid token: ".. jwt_obj.reason)
|
||||
ngx.status = ngx.HTTP_UNAUTHORIZED
|
||||
ngx.exit(ngx.HTTP_UNAUTHORIZED)
|
||||
end
|
||||
|
||||
--判断token是否超时 --令牌已过期
|
||||
if jwt_obj.payload.exp and ngx.time() > jwt_obj.payload.exp then
|
||||
ngx.log(ngx.WARN, "token timeout ".. jwt_obj.reason)
|
||||
ngx.status = ngx.HTTP_UNAUTHORIZED
|
||||
ngx.exit(ngx.HTTP_UNAUTHORIZED)
|
||||
end
|
||||
--获取token中的信息进行所需用户的信息返回
|
||||
|
||||
--
|
||||
local ret = {}
|
||||
ret.sub = 248289761001
|
||||
ret.name = "Jane Doe"
|
||||
ret.given_name = "Jane"
|
||||
ret.family_name = "Doe"
|
||||
ret.preferred_username = "j.doe"
|
||||
ret.email = "janedoe@example.com"
|
||||
local result = resp:json(ngx.HTTP_OK, ret)
|
||||
resp:send(result)
|
||||
end
|
||||
|
||||
--回收Access-Token
|
||||
|
|
@ -285,8 +350,15 @@ function _M:logout()
|
|||
ngx.req.read_body()
|
||||
--获取请求数据
|
||||
local body_data = ngx.req.get_body_data()
|
||||
--验证json数据是否正确
|
||||
local ok, data = pcall(cjson.decode, body_data)
|
||||
if not ok then
|
||||
local result = resp:json(0x000001)
|
||||
resp:send(result)
|
||||
return
|
||||
end
|
||||
-- 验证数据是否符合json
|
||||
local ok = validator.validatorLogout(body_data)
|
||||
local ok = validator.validateLogout(data)
|
||||
--验证失败则返回
|
||||
if not ok then
|
||||
local result = resp:json(0x000001)
|
||||
|
|
@ -315,8 +387,15 @@ function _M:refresh()
|
|||
ngx.req.read_body()
|
||||
--获取请求数据
|
||||
local body_data = ngx.req.get_body_data()
|
||||
--验证json数据是否正确
|
||||
local ok, data = pcall(cjson.decode, body_data)
|
||||
if not ok then
|
||||
local result = resp:json(0x000001)
|
||||
resp:send(result)
|
||||
return
|
||||
end
|
||||
-- 验证数据是否符合json
|
||||
local ok = validator.validatorRefresh(body_data)
|
||||
local ok = validator.validateRefresh(data)
|
||||
--验证失败则返回
|
||||
if not ok then
|
||||
local result = resp:json(0x000001)
|
||||
|
|
@ -331,8 +410,15 @@ function _M:checklogin()
|
|||
ngx.req.read_body()
|
||||
--获取请求数据
|
||||
local body_data = ngx.req.get_body_data()
|
||||
--验证json数据是否正确
|
||||
local ok, data = pcall(cjson.decode, body_data)
|
||||
if not ok then
|
||||
local result = resp:json(0x000001)
|
||||
resp:send(result)
|
||||
return
|
||||
end
|
||||
-- 验证数据是否符合json
|
||||
local ok = validator.validatorLogout(body_data)
|
||||
local ok = validator.validateChecklogin(data)
|
||||
--验证失败则返回
|
||||
if not ok then
|
||||
local result = resp:json(0x000001)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,16 @@ local schema = {
|
|||
required = { "username", "password" } -- 必填字段
|
||||
}
|
||||
|
||||
local schemaToken = {
|
||||
type = "object",
|
||||
properties = {
|
||||
grant_type = { type = "string" },
|
||||
code = { type = "string" },
|
||||
redirect_uri = { type = "string" },
|
||||
},
|
||||
required = { "grant_type", "code", "redirect_uri" }
|
||||
}
|
||||
|
||||
-- 原始JSON字符串
|
||||
--local jsonStr = [[
|
||||
--{
|
||||
|
|
@ -109,7 +119,7 @@ end
|
|||
|
||||
-- 验证函数
|
||||
local function validateJson(data)
|
||||
local validator = jsonschema.generate_validator(schema)
|
||||
local validator = jsonschema.generate_validator(schemaToken)
|
||||
local valid, errors = validator(data) -- 注意返回两个值
|
||||
|
||||
if not valid then
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ local schemaAuth = {
|
|||
}
|
||||
|
||||
--获取授权码
|
||||
function _M:validatorAuthorize(jsonData)
|
||||
function _M.validateAuthorize(jsonData)
|
||||
-- 验证数据是否符合schema
|
||||
local validator = jsonschema.generate_validator(schemaAuth)
|
||||
local result = validator(jsonData)
|
||||
|
|
@ -39,7 +39,7 @@ local schemaToken = {
|
|||
}
|
||||
|
||||
--根据授权码获取Access-Token
|
||||
function _M:validatorToken(jsonData)
|
||||
function _M.validateToken(jsonData)
|
||||
-- 验证数据是否符合schema
|
||||
local validator = jsonschema.generate_validator(schemaToken)
|
||||
local result = validator(jsonData)
|
||||
|
|
@ -58,7 +58,7 @@ local schemaLogin = {
|
|||
}
|
||||
|
||||
--回收Access-Token
|
||||
function _M:validatorLogin(jsonData)
|
||||
function _M.validateLogin(jsonData)
|
||||
-- 验证数据是否符合schema
|
||||
local validator = jsonschema.generate_validator(schemaLogin)
|
||||
local result = validator(jsonData)
|
||||
|
|
@ -66,15 +66,14 @@ function _M:validatorLogin(jsonData)
|
|||
end
|
||||
|
||||
local schemaUserInfo = {
|
||||
type = "object",
|
||||
type = 'object',
|
||||
properties = {
|
||||
Authorization = { type = "string" },
|
||||
},
|
||||
required = { "Authorization" }
|
||||
Authorization = {type = 'string', minLength = 8, pattern = 'Bearer\\s+(.+)$'},
|
||||
}, required = {"Authorization"}
|
||||
}
|
||||
|
||||
--根据Access-Token获取相应用户的账户信息
|
||||
function _M:validatorUserinfo(jsonData)
|
||||
function _M.validateUserinfo(jsonData)
|
||||
-- 验证数据是否符合schema
|
||||
local validator = jsonschema.generate_validator(schemaUserInfo)
|
||||
local result = validator(jsonData)
|
||||
|
|
@ -90,7 +89,7 @@ local schemaLogout = {
|
|||
}
|
||||
|
||||
--回收Access-Token
|
||||
function _M:validatorLogout(jsonData)
|
||||
function _M.validateLogout(jsonData)
|
||||
-- 验证数据是否符合schema
|
||||
local validator = jsonschema.generate_validator(schemaLogout)
|
||||
local result = validator(jsonData)
|
||||
|
|
@ -106,7 +105,7 @@ local schemaRefresh = {
|
|||
}
|
||||
|
||||
--根据Refresh-Token刷新Access-Token
|
||||
function _M:validatorRefresh(jsonData)
|
||||
function _M.validateRefresh(jsonData)
|
||||
-- 验证数据是否符合schema
|
||||
local validator = jsonschema.generate_validator(schemaRefresh)
|
||||
local result = validator(jsonData)
|
||||
|
|
@ -122,7 +121,7 @@ local schemaChecklogin = {
|
|||
}
|
||||
|
||||
--验证token是否有效
|
||||
function _M:validatorChecklogin(jsonData)
|
||||
function _M.validateChecklogin(jsonData)
|
||||
-- 验证数据是否符合schema
|
||||
local validator = jsonschema.generate_validator(schemaChecklogin)
|
||||
local result = validator(jsonData)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user