Spengo与Tomcat服务器下Java Jersey Rest Api集成方案咨询
Tomcat + Jersey REST API 集成 SPNEGO 认证实操指南(无Spring Security依赖)
前置准备
- 已配置完成的域控制器(AD/KDC),提前为Tomcat服务注册SPN,生成对应keytab文件,注意keytab权限仅开放给Tomcat运行用户可读
- Tomcat版本≥8.5,Jersey版本≥2.x,项目仅引入Jersey核心依赖即可,无需任何Spring相关组件
第一步:配置Tomcat内置SPNEGO认证阀
打开Tomcat conf 目录下的server.xml,在Host节点下新增SPNEGO Valve配置:
<Valve className="org.apache.catalina.authenticator.SpnegoAuthenticator" storeDelegatedCredential="true" />
再在项目的WEB-INF/web.xml或者Tomcat全局conf/web.xml中添加安全约束,指定需要认证的Jersey API路径:
<security-constraint> <web-resource-collection> <web-resource-name>Jersey REST APIs</web-resource-name> <url-pattern>/api/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>*</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>SPNEGO</auth-method> <realm-name>SPNEGO Realm</realm-name> </login-config> <security-role> <role-name>*</role-name> </security-role>
第二步:配置Tomcat Realm对接域账号体系
在server.xml的Engine节点下,配置JNDI Realm对接你的AD域服务,完成账号、角色校验:
<Realm className="org.apache.catalina.realm.JNDIRealm" connectionURL="ldap://你的主域控制器地址:389" alternateURL="ldap://你的备域控制器地址:389" connectionName="域绑定账号@你的域名" connectionPassword="域绑定账号密码" userSearch="(sAMAccountName={0})" userBase="OU=用户组织节点,DC=你的域名,DC=com" roleSearch="(member={0})" roleBase="OU=角色组织节点,DC=你的域名,DC=com" roleName="cn" roleSubtree="true" userSubtree="true" />
第三步:配置JVM Kerberos相关参数
在Tomcat的启动脚本(Linux为bin/setenv.sh,Windows为bin/setenv.bat)中添加以下JVM启动参数:
-Djava.security.krb5.conf=/path/to/krb5.conf -Djava.security.auth.login.config=/path/to/jaas.conf -Dsun.security.krb5.debug=false # 调试阶段可修改为true输出详细日志排错
krb5.conf配置参考:
[libdefaults] default_realm = 你的域名(全大写) dns_lookup_kdc = true dns_lookup_realm = true ticket_lifetime = 24h renew_lifetime = 7d [realms] 你的域名(全大写) = { kdc = 你的域控制器地址 admin_server = 你的域控制器地址 default_domain = 你的域名 } [domain_realm] .你的域名 = 你的域名(全大写) 你的域名 = 你的域名(全大写)
jaas.conf配置参考:
com.sun.security.jgss.krb5.accept { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true keyTab="/path/to/你的服务keytab文件路径" principal="HTTP/你的Tomcat服务对外域名@你的域名(全大写)" storeKey=true doNotPrompt=true debug=false; };
第四步:Jersey侧获取认证信息
你可以直接在Jersey接口中注入HttpServletRequest对象,获取已完成SPNEGO认证的用户身份:
import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.servlet.http.HttpServletRequest; @Path("/demo") public class DemoResource { @GET public String getCurrentUser(@Context HttpServletRequest request) { // 直接返回已认证的域账号名称 String authUser = request.getRemoteUser(); return "认证成功,当前登录用户:" + authUser; } }
验证与注意事项
- 测试时需要使用加入域的客户端设备,将Tomcat服务域名加入浏览器的本地Intranet站点列表,访问API时无需输入密码即可自动完成认证
- 未加入域的客户端访问受保护接口会直接返回401状态码
- Tomcat服务器、域控制器、客户端三者的时间差不能超过5分钟,否则Kerberos认证会直接失败
- 访问时必须使用注册SPN时对应的域名,不能用IP访问,否则SPNEGO认证不会生效
内容的提问来源于stack exchange,提问作者Vineel Pellella
相关产品推荐
相关产品推荐

