tomcat -jaas-如何检索主题



我正在研究jaas,我正在使用带有jaasrealm的tomcat在WebApp中使用一个简单的示例。

现在我的问题是我不知道如何检索主题,因为像 Subject subject = Subject.getSubject(AccessController.getContext());这样的代码总是返回null。

我正在使用tomcat 7.0.27。有我想念的东西吗?换句话说,如何使用JAAS在Java EE中管理授权?例如,我如何在JAAS的安全上下文中实施一个操作?

我知道这很有效,但是我需要检索主题才能获得roleprincipal

不幸的是,它在Java EE中无法正常工作。JAAS主题只是"校长袋",其中哪个代表用户/呼叫者校长和/或角色主体的角色根本不标准化。其他所有容器在这里做的事情都不同。Tomcat Jaasrealm的Javadoc描述了这一点,并解释了Tomcat的特定惯例(强调我的惯例):

JAAS规范将成功登录的结果描述为 javax.security.auth.subject实例,可以包含零或更多 java.security.principal对象的返回值 bucess.getPrincipals()方法。但是,它不提供指导 如何区分描述个别用户的校长(和 因此适合返回作为价值 Web应用程序中的request.getuserprincipal() 描述了该用户的授权角色。保持尽可能多 尽可能从基础登录 JAAS执行的实施,实施以下策略 通过这个领域:[...]

除此之外,从Java EE环境中,您甚至很少可以访问JAAS主题,甚至通常无法通过供应商特定的方法。JAAS远非您似乎认为是的通用标准,尤其是当它涉及Java EE时。

您唯一可以以便携式方式访问的东西是呼叫者主体及其关联的角色,但即使这些角色也不必是构建的JAAS登录模块的确切呼叫者主体。

jboss,例如,使用自己的类别复制了几次本金。因此,如果您的JAAS模块将kaz.zak.FooPrincipal存储在用户/呼叫者主体的主题中,则HttpServletRequest#getUserPrincipal()可能会返回org.jboss.security.SimplePrincipal。唯一保证的是该实例上的getName()将返回同一字符串。

有关此主题的更多背景:

  • 使用JASPIC在Java EE中实现容器身份验证
  • Jaas发生了什么事?
  • 将JAAS与Tomcat一起使用

最后一个来源基本上在不同的措辞中说了同一件事;

尽管可以在tomcat中使用JAAS作为身份验证 机构(Jaasrealm),JAAS框架的灵活性丢失了 一旦对用户进行身份验证。这是因为校长是 用来表示"用户"one_answers"角色"的概念,不再是 在执行WebApp的安全环境中可用。这 身份验证的结果仅通过 request.getRemoteuser()和request.isuserinrole()。

这将用于授权目的的JAAS框架减少到一个简单 失去与Java安全性连接的用户/角色系统 政策。

要检索主题,我们可以使用登录模块和阀的组合。在身份验证启动之前调用阀门的事实正在帮助我们在这里。调用阀门时,将会将会话放入threadLocal(类似于JBOSS在threadlocal中保存请求的方式),然后在调用looginmodule.commit()时,将主题保存到会话中。

要配置此添加以下类的添加编译的代码,并将其放在$ catalina_base/lib/plaber下

package my.test;
import java.io.IOException;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import javax.servlet.ServletException;
import org.apache.catalina.Session;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
/**
 * Use following class to retrieve subject in your HTTPServlet when using Tomcat.
 */
public class ContainerServices extends ValveBase implements LoginModule {
    // Key to revtieve subject from session.
    public static final String SUBJECT_KEY =
        "javax.security.auth.Subject.container";
    /**
     * Session for current thread.
     */
    static InheritableThreadLocal<Session> sessionHolder =
        new InheritableThreadLocal<Session>();
    // JAAS Subject being authenticated.
    private Subject subject;
    // Invoke the value.
    public void invoke(Request request, Response response) throws IOException,
            ServletException {
        sessionHolder.set(request.getSessionInternal(true));
        try {
            // Next in the invocation chain
            getNext().invoke(request, response);
        } finally {
            sessionHolder.remove();
        }
    }
    // Initialize the login module
    public void initialize(Subject subject, CallbackHandler callbackHandler,
        Map<String, ?> sharedState, Map<String, ?> options) {
        this.subject = subject;
    }
    // Store subject to session.
    public boolean commit() throws LoginException {
        Session session = sessionHolder.get();
        if (session != null) {
            session.getSession().setAttribute(ContainerServices.SUBJECT_KEY, subject);
        }
        return true;
    }
    // not used
    public boolean abort() throws LoginException {
        return false;
    }
    // not used
    public boolean login() throws LoginException {
        return true;
    }
    // not used
    public boolean logout() throws LoginException {
        return true;
    }
}

在$ catalina_base/conf/conf/conf/conf/server.xml添加以下阀门配置为元素的孩子。

<Valve className="my.test.ContainerServices" />

在jaas.config文件中添加与loginmodule相同的类。

DummyAppLogin {
    my.test.ContainerServices required debug=true;
    my.test.DummyAppLoginModule required debug=true;
};

现在登录后,可以使用以下验证的受试者进行以下验证。

session.getAttribute( ContainerServices.SUBJECT_KEY );

相关内容

  • 没有找到相关文章

最新更新