我正在使用tomcat 8.0。 我在context.xml文件中配置了一个realm元素,该文件指定我将实现DataSourceRealm。 另外,根据tomcat 8领域配置说明(https://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html) 我在realm元素中嵌套了一个CredentialHandler元素,以指定诸如salt length和iterations之类的属性。 context.xml文件的相关部分如下:
<Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"
dataSourceName="jdbc/board" localDataSource="true"
userTable="test_user" userNameCol="Email" userCredCol="HashedPassword"
userRoleTable="test_user_role" roleNameCol="Role">
<CredentialHandler className="MessageDigestCredentialHandler" algorithm="SHA-1"
iterations="1000" saltLength="48"/>
</Realm>
当我在我的Web应用程序中调用servlet时,我希望能够引用上面的realm对象,以便我可以调用RealmBase类的非静态方法(例如:digest()(不是静态摘要( ) 方法))。 我想调用初始化的realm对象的digest方法,因为这是包含我指定的所有属性的对象(salt length等)。 如何从servlet访问DataSourceRealm对象? (调用静态方法并手动指定散列算法似乎不合逻辑,更不用说在静态方法中没有用于输入salt详细信息的参数这一事实。)
我尝试在ServletContext和HttpServletRequest API中搜索一个检索RealmBase对象或其容器对象但没有找到任何相关内容的方法。
编辑:我尝试获取InitialContext对象并使用lookup
方法,因为这是我用来获取也位于context.xml中的资源元素的方法文件:
InitialContext ic = new InitialContext();
DataSourceRealm realm = (DataSourceRealm) ic.lookup("org.apache.catalina.realm.DataSourceRealm");
但这也没有用。
谢谢
答案 0 :(得分:0)
在上下文应用程序中,我们不使用类(等效),即不使用 ic.lookup(&#34; org.apache.catalina.realm.DataSourceRealm&#34)
但是名字 ic.lookup(&#34; JDBC /板&#34)
(这不是测试,只有解决方法)
答案 1 :(得分:0)
这是一个旧的(呃)问题,但如果您愿意使用反射,则 是可能的。以下代码将从ServletContext中检索配置的CredentialHandler:
public CredentialHandler getCredentialHandler(ServletContext context) {
Realm realm = getRealm(context);
if (realm != null) {
return realm.getCredentialHandler();
}
return null;
}
private Realm getRealm(ServletContext context) {
if (context instanceof ApplicationContextFacade) {
ApplicationContext applicationContext = getApplicationContext(
(ApplicationContextFacade)context
);
if (applicationContext != null) {
StandardContext standardContext = getStandardContext(
applicationContext
);
if (standardContext != null) {
return standardContext.getRealm();
}
}
}
return null;
}
private ApplicationContext getApplicationContext(
ApplicationContextFacade facade) {
try {
Field context = ApplicationContextFacade.class.getDeclaredField(
"context"
);
if (context != null) {
context.setAccessible(true);
Object obj = context.get(facade);
if (obj instanceof ApplicationContext) {
return (ApplicationContext)obj;
}
}
} catch (Exception ex) {
}
return null;
}
private StandardContext getStandardContext(
ApplicationContext applicationContext) {
try {
Field context = ApplicationContext.class.getDeclaredField(
"context"
);
if (context != null) {
context.setAccessible(true);
Object obj = context.get(applicationContext);
if (obj instanceof StandardContext) {
return (StandardContext)obj;
}
}
} catch (Exception ex) {
}
return null;
}
您可以在应用程序的早期调用它,例如在ServletContextListener或ServletContainerInitializer中,并存储处理程序以供以后使用。
丑陋,但我不认为还有另一种方式。
戴夫