2015-05-19 95 views
0

我正在使用tomcat 8.0。 我在context.xml文件中配置了一个领域元素,它指定我将实现DataSourceRealm。 此外,根据tomcat 8域配置指令(https://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html) 我在realm元素中嵌套了一个CredentialHandler元素,以指定盐长度和迭代等属性。 context.xml文件的相关部分如下:从servlet获取DataSourceRealm的实例

<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类的静态方法(例如:digest()(不是静态的Digest()方法))。 我想调用初始化领域对象的摘要方法,因为这是包含我指定的所有属性(盐长度等)的对象。 如何从servlet访问DataSourceRealm对象? (调用静态方法并手动指定散列算法似乎不合逻辑,更不用说在静态方法中没有用于输入盐细节的参数)。

我尝试搜索ServletContext和HttpServletRequest API的方法来检索RealmBase对象或其容器对象,但没有找到任何相关的。

编辑:我尝试获取InitialContext对象,并使用lookup方法,因为这是我用它来获取资源元素也位于context.xml文件:

InitialContext ic = new InitialContext(); 
      DataSourceRealm realm = (DataSourceRealm) ic.lookup("org.apache.catalina.realm.DataSourceRealm"); 

但是,这也没有工作。

谢谢

+0

我问过类似的问题在http://stackoverflow.com/questions/30490893/how-can-i-utilize-the-same-credential-handler-configuration-for-my-applications – brantgurga

+0

如果您*实际*想要的是获取'CredentialHandler'实例,请参阅http://stackoverflow.com/a/41903791/7480998 –

回答

0

语境中的应用,我们不使用类(当量),即不 ic.lookup( “org.apache.catalina.realm.DataSourceRealm”)

但名称 IC .lookup(“JDBC /板”)

(这不是测试,只有解决办法)

0

这是一个老(ER)的问题,但它可能的,如果你愿意使用反射。下面的代码会从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和存储供以后使用的处理程序。

丑陋,但我不认为有另一种方式。

戴夫