从servlet

时间:2015-05-19 15:59:40

标签: tomcat jdbcrealm

我正在使用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");

但这也没有用。

谢谢

2 个答案:

答案 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中,并存储处理程序以供以后使用。

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

戴夫