任何人都知道是否有可能使用NTLM的Windows身份validation做反向代理? 我无法find任何例子。 more_set_headers字段的值应该是多less?
location / { proxy_http_version 1.1; proxy_pass_request_headers on; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; more_set_input_headers 'Authorization: $http_authorization'; proxy_set_header Accept-Encoding ""; proxy_pass http://host/; proxy_redirect default; #This is what worked for me, but you need the headers-more mod more_set_headers -s 401 'WWW-Authenticate: Basic realm="host.local"'; }
如果我直接访问主机,那么如果我使用反向代理访问validation,每次validation都会失败。
使用Nginx启用NTLM传递 –
upstream http_backend { server 2.3.4.5:80; keepalive 16; } server { ... location / { proxy_pass http://http_backend/; proxy_http_version 1.1; proxy_set_header Connection ""; ... } }
拉蒙
据我所知,这对于nginx来说目前是不可能的。 我刚刚在一个小时前深入调查了这一点。 基本的问题是,NTLM身份验证将需要在后续请求使用相同的套接字,但代理不这样做。 在nginx开发团队为这种行为提供某种支持之前,我处理这个的方式是通过在反向代理中进行身份验证。 我目前正在做这个使用Apache 2.2,mod_proxy,mod_auth_sspi(不完美,但工程)。 祝你好运! 对不起,nginx,我爱你,但是我们真的可以为这个常见用例使用一些帮助。
我已经为此提出了另一个解决方案。 这与NTLM的nginx不一样(如果nginx团队实现这个功能,这将会很好)。 但是,现在,我正在为我们工作。
我写了一些使用加密cookie的lua代码。 加密的cookie包含用户的ID,认证的时间以及认证的IP地址。 我附上这个东西供参考。 它没有打磨,但也许你可以用它来开发你自己的类似的方案。
基本上,它是如何工作的是:
access.lua:
local enc = require("enc"); local strings = require("strings"); local dkjson = require("dkjson"); function beginAuth() local headers = ngx.req.get_headers(); local contentTypeOriginal = headers["Content-Type"]; print( contentTypeOriginal ); ngx.req.set_header( "Content-Type", "application/json" ); local method = ngx.req.get_method(); local body = ""; if method == "POST" then local requestedWith = headers["X-Requested-With"]; if requestedWith ~= nil and requestedWith == "XMLHttpRequest" then print( "bailing, won't allow post during re-authentication." ); ngx.exit(ngx.HTTP_GONE); -- for now, we are NOT supporting a post for re-authentication. user must do a get first. cookies can't be set on these ajax calls when redirecting, so for now we can't support it. ngx.say("Reload the page."); return; else print( "Attempting to handle POST for request uri: " .. ngx.var.uri ); end ngx.req.read_body(); local bodyData = ngx.req.get_body_data(); if bodyData ~= nil then body = bodyData; end end local json = dkjson.encode( { c = contentTypeOriginal, m = method, d = body } ); local origData = enc.base64encode( json ); local res = ngx.location.capture( "/preauth", { method = ngx.HTTP_POST, body = "{'clientIp':'" .. ngx.var.remote_addr .. "','originalUrl':'" .. ngx.var.FrontEndProtocol .. ngx.var.host .. ngx.var.uri .. "','originalData':'" .. origData .. "'}" } ); if contentTypeOriginal ~= nil then ngx.req.set_header( "Content-Type", contentTypeOriginal ); else ngx.req.clear_header( "Content-Type" ); end if res.status == 200 then ngx.header["Access-Control-Allow-Origin"] = "*"; ngx.header["Set-Cookie"] = "pca=guid:" .. enc.encrypt( res.body ) .. "; path=/" ngx.redirect( ngx.var.authurl .. "auth/" .. res.body ); else ngx.exit(res.status); end end function completeAuth( cookie ) local guid = enc.decrypt( string.sub( cookie, 6 ) ); local contentTypeOriginal = ngx.header["Content-Type"]; ngx.req.set_header( "Content-Type", "application/json" ); local res = ngx.location.capture( "/postauth", { method = ngx.HTTP_POST, body = "{'clientIp':'" .. ngx.var.remote_addr .. "','guid':'" .. guid .. "'}" } ); if contentTypeOriginal ~= nil then ngx.req.set_header( "Content-Type", contentTypeOriginal ); else ngx.req.clear_header( "Content-Type" ); end if res.status == 200 then local resJson = res.body; -- print( "here a1" ); -- print( resJson ); local resTbl = dkjson.decode( resJson ); if resTbl.StatusCode == 0 then resTbl = resTbl.Result; local time = os.time(); local sessionData = dkjson.encode( { u = resTbl.user, t = time, o = time } ); ngx.header["Set-Cookie"] = "pca=" .. enc.encrypt( sessionData ) .. "; path=/" ngx.req.set_header( "REMOTE_USER", resTbl.user ); if resTbl.originalData ~= nil and resTbl.originalData ~= "" then local tblJson = enc.base64decode( resTbl.originalData ); local tbl = dkjson.decode( tblJson ); if tbl.m ~= nil and tbl.m == "POST" then ngx.req.set_method( ngx.HTTP_POST ); ngx.req.set_header( "Content-Type", tbl.c ); ngx.req.read_body(); ngx.req.set_body_data( tbl.d ); end end else ngx.log( ngx.ERR, "error parsing json " .. resJson ); ngx.exit(500); end else print( "error completing auth." ); ngx.header["Set-Cookie"] = "pca=; path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; token=deleted;" print( res.status ); ngx.exit(res.status); end end local cookie = ngx.var.cookie_pca; print( cookie ); if cookie == nil then beginAuth(); elseif strings.starts( cookie, "guid:" ) then completeAuth( cookie ); else -- GOOD TO GO... local json = enc.decrypt( cookie ); local d = dkjson.decode( json ); local now = os.time(); local diff = now - dt; local diffOriginal = 0; if do ~= nil then diffOriginal = now - do; end if diff > 3600 or diffOriginal > 43200 then beginAuth(); elseif diff > 300 then print( "regenerating new cookie after " .. tostring( diff ) .. " seconds." ); local sessionData = dkjson.encode( { u = du, t = now, o = dt } ); ngx.header["Set-Cookie"] = "pca=" .. enc.encrypt( sessionData ) .. "; path=/" end ngx.req.set_header( "REMOTE_USER", du ); end
strings.lua:
local private = {}; local public = {}; strings = public; function public.starts(String,Start) return string.sub(String,1,string.len(Start))==Start end function public.ends(String,End) return End=='' or string.sub(String,-string.len(End))==End end return strings;
enc.lua:
-- for base64, try something like: http://lua-users.org/wiki/BaseSixtyFour local private = {}; local public = {}; enc = public; local aeslua = require("aeslua"); private.key = "f8d7shfkdjfhhggf"; function public.encrypt( s ) return base64.base64encode( aeslua.encrypt( private.key, s ) ); end function public.decrypt( s ) return aeslua.decrypt( private.key, base64.base64decode( s ) ); end return enc;
sample nginx conf:
upstream dev { ip_hash; server app.server.local:8080; } set $authurl http://auth.server.local:8082/root/; set $FrontEndProtocol https://; location / { proxy_pass http://dev/; proxy_set_header Host $host; proxy_redirect default; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header X-Real-IP $remote_addr; proxy_buffers 128 8k; access_by_lua_file conf/lua/app/dev/access.lua; }