authentication - 在tomcat自定义JNDIRealm中访问会话信息
问题描述
我正在尝试编写自定义 JNDIRealm 但如何访问 Request 对象?
我这样做的原因是我有 2 个 LDAP 服务器,其中一个执行 2-Factor 检查。我需要访问 Request 对象以查看请求的来源。对于 Intranet 用户,我使用普通 LDAP 服务器,但对于 Internet 用户,我使用 2-Factor LDAP 服务器
解决方案
似乎不可能......我必须更新我的 login.jsp 并在那里访问 Request 对象并在 j_username 中传递我需要的信息
var isWebProxyRequest = "<%= request.getHeader("PROXY_HEADER") != null ? "Y" : "N" %>";
getElement("j_username").value = (isWebProxyRequest == "Y" ? "WEB::" : "INTERNAL::") + getElement("username").value;
在我的情况下,我有一个 apache 代理,它执行我的 DDOS 和 WEB 和设置标题属性的 TOMCAT 之间的其他保护。这是通过在 apache ssl.conf 中进行以下设置来完成的
RequestHeader set PROXY_HEADER xxxx
如上所示,我检测并将一个名为 TYPE 的变量设置为 WEB 或 INTRANET
我将 TYPE 传递给 j_username 所以当 j_username 传递给 Realm 时会看到 ::
然后我编写了自己的自定义领域,称为 SelectorRealm,如下所示
package xxxx;
public class SelectionRealm extends CombinedRealm {
private static final Log log = LogFactory.getLog(SelectionRealm.class);
public boolean checkSelector(Realm realm, String selector) {
return ((SelectorRealm) realm).getSelector().equals(selector);
}
public String getUserName(String username) {
return username.replaceAll("^.*::", "");
}
public String getSelector(String username) {
return username.replaceAll("::.*$", "");
}
public Principal authenticate(String _username, String clientDigest, String nonce, String nc, String cnonce, String qop, String realmName, String md5a2) {
Principal authenticatedUser = null;
String username = getUserName(_username);
String selector = getSelector(_username);
log.info("username=" + username + " selector=" + selector);
for (Realm realm : realms) {
if (!checkSelector(realm, selector)) continue;
authenticatedUser = realm.authenticate(username, clientDigest, nonce, nc, cnonce, qop, realmName, md5a2);
break;
}
return authenticatedUser;
}
public Principal authenticate(String _username) {
Principal authenticatedUser = null;
String username = getUserName(_username);
String selector = getSelector(_username);
log.info("SelectionRealm: username=" + username + " selector=" + selector);
for (Realm realm : realms) {
if (!checkSelector(realm, selector)) continue;
authenticatedUser = realm.authenticate(username);
break;
}
return authenticatedUser;
}
public Principal authenticate(String _username, String credentials) {
Principal authenticatedUser = null;
String username = getUserName(_username);
String selector = getSelector(_username);
log.info("SelectionRealm: username=" + username + " selector=" + selector);
for (Realm realm : realms) {
if (!checkSelector(realm, selector)) continue;
authenticatedUser = realm.authenticate(username, credentials);
break;
}
return authenticatedUser;
}
public Principal authenticate(GSSContext gssContext, boolean storeCred) {
UnsupportedOperationException uoe = new UnsupportedOperationException("SelectionRealm.authenticate.GSSContext");
log.error("SelectionRealm.unexpectedMethod", uoe);
throw uoe;
}
public Principal authenticate(GSSName gssName, GSSCredential gssCredential) {
UnsupportedOperationException uoe = new UnsupportedOperationException("SelectionRealm.authenticate.GSSName");
log.error("SelectionRealm.unexpectedMethod", uoe);
throw uoe;
}
}
和 SelectorRealm 为
package xxxx;
public interface SelectorRealm {
public void setSelector(String selector);
public String getSelector();
}
和实现 SelectorRealm 的自定义 JNDIRealm
package xxxx;
public class JNDIRealm extends org.apache.catalina.realm.JNDIRealm implements SelectorRealm {
protected String selector = null;
public void setSelector(String selector) {
this.selector = selector;
}
public String getSelector() {
return this.selector;
}
}
所以现在我的 tomcat context.xml 设置为
<Realm className="xxxx.SelectionRealm" >
<Realm className="xxxx.JNDIRealm" debug="99"
connectionURL="ldaps://${LDAP_INTERNAL_SERVER}:${LDAP_INTERNAL_PORT}"
selector="INTERNAL"
... />
<Realm className="xxxx.JNDIRealm" debug="99"
connectionURL="ldaps://${LDAP_WEB_SERVER}:${LDAP_WEB_PORT}"
selector="WEB"
... />
</Realm>
推荐阅读
- typescript - 打字稿记录,无需手动键入键
- javascript - 如何在 svelte 文件中使用电子方法 - Svelte 3 - 还是有其他方法可以做到这一点?
- algorithm - 水合节点
- gremlin - 找不到类的类型标识符:class java.lang.Short
- wordpress - 如果有 2 级,则将唯一的类添加到 0 级
- typescript - PIXI js 加载资产导致缓存警告我纹理已加载到缓存中
- spring-boot - 增加 OAuth 客户端
- c# - 值不能为空。参数名称:path1
- javascript - 在 HTML 表格中输入数据
- javascript - onkeypress() 未调用函数