如何在OAuth2-Proxy认证的OpenGrok实例中获取用户名
已通过OAuth2-Proxy完成OpenGrok的企业SSO认证,但无法在OpenGrok UI中显示用户名,request.getRemoteUser()及读取X-Forwarded-Email等请求头均返回null,核心问题是OAuth2-Proxy传递的用户信息未被OpenGrok正确接收或解析。
1. 确认OAuth2-Proxy配置是否正确转发用户头
首先需确保OAuth2-Proxy在认证后向OpenGrok转发用户相关请求头,检查docker-compose中oauth2-proxy服务的command配置,需包含以下关键参数:
command: - --provider=oidc - --oidc-issuer-url=https://你的Okta域名/oauth2/default - --client-id=你的客户端ID - --client-secret=你的客户端密钥 - --cookie-secret=你的Cookie密钥 - --http-address=0.0.0.0:4180 - --upstream=http://opengrok:8080/source/ - --redirect-url=https://你的OpenGrok域名/oauth2/callback - --set-xauthrequest # 启用X-Auth-Request-*头传递用户信息 - --scope=openid email profile # 确保获取用户基本信息的权限 - --email-domain=你的企业域名
2. 配置OpenGrok接收转发的用户头
方案一:修改Tomcat配置信任代理并映射用户头
OpenGrok默认运行在Tomcat中,需配置Tomcat信任OAuth2-Proxy的转发,并将X-Auth-Request-*头映射为远程用户:
- 修改Tomcat的
server.xml,在Connector节点添加RemoteIpValve(根据你的Docker网络调整内部代理IP段):
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"> <Valve className="org.apache.catalina.valves.RemoteIpValve" internalProxies="172.17.0.0/16" remoteIpHeader="X-Forwarded-For" proxiesHeader="X-Forwarded-By" protocolHeader="X-Forwarded-Proto"/> </Connector>
- 添加自定义Filter读取X-Auth-Request-User头并设置为remoteUser:
- 在OpenGrok的
web.xml中添加Filter配置:
<filter> <filter-name>XAuthRequestFilter</filter-name> <filter-class>com.opengrok.web.XAuthRequestFilter</filter-class> </filter> <filter-mapping> <filter-name>XAuthRequestFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>- 编写对应的Java Filter(编译后放入OpenGrok的WEB-INF/lib目录):
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.IOException; public class XAuthRequestFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; String remoteUser = req.getHeader("X-Auth-Request-User"); if (remoteUser != null) { chain.doFilter(new HttpServletRequestWrapper(req) { @Override public String getRemoteUser() { return remoteUser; } }, response); } else { chain.doFilter(request, response); } } @Override public void destroy() {} } - 在OpenGrok的
方案二:直接修改pageheader.jspf读取正确请求头
若不想修改Tomcat配置,可直接在ROOT/pageheader.jspf中读取OAuth2-Proxy转发的X-Auth-Request-Preferred-Username或X-Auth-Request-Email头,同时修正登出链接指向OAuth2-Proxy的登出地址:
--%><%@page import="org.opengrok.web.PageConfig"%> <% /* ---------------------- pageheader.jspf start --------------------- */ { PageConfig cfg = PageConfig.get(request); %> <%= cfg.getEnv().getIncludeFiles().getHeaderIncludeFileContent(false) %> <div class="logout"> <span id="logout"> Welcome, <%= request.getHeader("X-Auth-Request-Preferred-Username") != null ? request.getHeader("X-Auth-Request-Preferred-Username") : "Guest" %>! | <a href="/oauth2/sign_out">Logout</a> </span> </div> <% } /* ---------------------- pageheader.jspf end --------------------- */ %>
3. 调试验证请求头
可在OpenGrok容器内添加调试代码,确认请求头是否被正确传递:
<% // 输出所有请求头用于调试 java.util.Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); out.println(headerName + ": " + request.getHeader(headerName) + "<br>"); } %>
也可通过curl模拟OAuth2-Proxy的请求,测试页面是否能读取到头信息:
# 进入OpenGrok容器 docker exec -it 你的opengrok容器名 bash # 模拟带用户头的请求 curl -H "X-Auth-Request-Preferred-Username: test-user" http://localhost:8080/source/
4. 检查网络连通性
确保docker-compose中oauth2-proxy和opengrok服务处于同一网络,upstream配置正确指向opengrok的服务名与端口(如http://opengrok:8080/source/),无网络策略阻止请求头传递。
内容的提问来源于stack exchange,提问作者undefined

