我用的是Tomcat8.0。我在context.xml文件中配置了一个领域元素,它指定我将实现DataSourceRealm。此外,根据tomcat 8领域配置指令(https://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html),我在王国元素中嵌套了一个CredentialHandler元素,以便指定属性,比如盐分长度和迭代。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时,我希望能够引用上面的领域对象,这样我就可以调用RealmBase类的非静态方法(例如:摘要()(而不是静态摘要()方法))。我想调用初始化的领域对象的摘要方法,因为它包含了我指定的所有属性(盐分长度等)。如何从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");
但这也没用。
谢谢
发布于 2015-08-01 04:36:28
在上下文应用程序中,我们不使用类(等效),即不使用ic.lookup("org.apache.catalina.realm.DataSourceRealm")
但是命名为ic.lookup("jdbc/board")
(这是没有测试的,唯一的解决办法)
发布于 2016-02-11 10:18:37
这是一个古老的(呃)问题,但如果你愿意使用反射,这是可能的。下面的代码将从CredentialHandler中检索配置的ServletContext:
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中,并存储处理程序以供以后使用。
很丑,但我不认为还有别的办法。
戴夫
https://stackoverflow.com/questions/30330576
复制相似问题