从Servlet获取DataSourceRealm的实例 [英] Get instance of DataSourceRealm from a servlet

查看:146
本文介绍了从Servlet获取DataSourceRealm的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用tomcat 8.0. 我在context.xml文件中配置了一个realm元素,该元素指定我将实现DataSourceRealm. 此外,按照tomcat 8领域配置说明( https://tomcat .apache.org/tomcat-8.0-doc/realm-howto.html ) 我将CredentialHandler元素嵌套在realm元素中,以便指定诸如盐长度和迭代之类的属性. context.xml文件的相关部分如下:

I am using tomcat 8.0. I configured a realm element in the context.xml file which specifies that I will be implementing the DataSourceRealm. In addition, as per the tomcat 8 realm configuration instructions (https://tomcat.apache.org/tomcat-8.0-doc/realm-howto.html) I nested a CredentialHandler element in the realm element in order to specify attributes such as salt length and iterations. The relevant portion of the context.xml file is as follows:

<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( ) 方法)). 我想调用已初始化领域对象的digest方法,因为该对象包含我指定的所有属性(盐长等). 如何从Servlet获得对DataSourceRealm对象的访问? (调用静态方法并手动指定哈希算法似乎不合逻辑,更不用说在静态方法中没有用于输入盐详细信息的事实了.

When I call a servlet in my web application, I would like to be able to reference the above realm object so that I can call non-static methods of the RealmBase class (eg: digest() (Not the static Digest() method)). I would like to call the digest method of the initialized realm object because that is the object that contains all of the attributes that I specified (salt length, etc.). How can I get access to the DataSourceRealm object from a servlet? (Calling the static method and manually specifying the hashing algorithm doesn't seem logical, not to mention the fact that there is no parameter for inputting the salt details in the static method).

我尝试在ServletContext和HttpServletRequest API的搜索中找到用于检索RealmBase对象或其容器对象的方法,但是没有找到任何相关内容.

I tried searching the ServletContext and HttpServletRequest API's for a method for retrieving the RealmBase Object or its Container Object but didn't find anything relevant.

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

Edit: I tried getting the InitialContext object and using the lookup method since this is what I use to get the resource element that's also located in the context.xml file:

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

但这也不起作用.

谢谢

推荐答案

这是一个较旧的问题,但是如果您愿意使用反射,则有可能 .以下代码将从ServletContext检索配置的CredentialHandler:

This is an old(er) question, but it is possible if you're willing to use reflection. The following code will retrieve the configured CredentialHandler from the 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中调用它,并存储处理程序以供以后使用.

You can call this early in the application, say in a ServletContextListener or ServletContainerInitializer and store the handler for later use.

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

Ugly, but I don't think there's another way.

戴夫

这篇关于从Servlet获取DataSourceRealm的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆