2015-05-19 53 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和存儲供以後使用的處理程序。

醜陋,但我不認爲有另一種方式。

戴夫