Undertow是否具有等效于Tomcat WebAuthentication的Web层身份验证功能?

时间:2018-08-17 20:04:24

标签: tomcat servlets undertow

这可能是“ XY问题”问题的一个实例;如果是这样,请随时通过纠正我的假设来回答。


更新:曾经有一次,我尝试通过执行HttpServletRequest来使用loginRequest.login(username, password);,但这无法编译,产生{{1}中找不到login(String, String)的编译错误}},所以我放弃了这个角度。但是,我刚刚找到了article which suggests that this is the correct change to make,所以我又回到了那条足迹。

我让某人告诉我,也许我正在使用该课程的旧版本。我的编译时类路径上可能有旧的HttpServletRequest。我现在正在调查。


从Tomcat(在JBoss 5中)切换到Undertow(在JBoss 7中)之后,我们的用户身份验证页面已损坏。

我们有一个HttpServletRequest,它曾经在JBoss 5的Tomcat Web服务器中运行。因此,它像下面这样使用Tomcat的HttpServlet

WebAuthentication

我没有添加立即使用import org.jboss.web.tomcat.security.login.WebAuthentication; import java.io.IOException; import javax.servlet.http.*; // ... import etc. public class MyHttpServlet extends HttpServlet { private void loginCase( HttpServletRequest loginRequest, HttpServletResponse loginResponse ) throws ServletException, IOException, RemoteException { String username; String password; // ... other stuff // Authenticate with the web tier. This invokes the MyLoginModule, // which uses the user database tables to authenticate and establish // the user's role(s). This servlet does role checking, but this step // is necessary to get the user's credentials into the container, which // secures remote EJBs. If this is not done, the servlets and JSPs will // not be able to properly access secured EJBs. WebAuthentication webAuth = new WebAuthentication(); boolean loginResult = webAuth.login(username, password); // ... } } 的评论,这是有关通过Web层进行身份验证的评论。这就是原始代码中的内容,似乎是对为什么选择WebAuthentication作为身份验证机制的解释。

我的理解是Undertow / JBoss7不再具有WebAuthentication类。

在运行时,当用户提交其名称/密码条目时,会出现WebAuthentication,消息为ClassNotFoundException

现在我们不再具有访问org.jboss.web.tomcat.security.login.WebAuthentication from [module "deployment.myproject.ear.viewers.war" from Service Module Loader]的权限(我什至从Tomcat复制了包含必需类的jar文件到我的.ear文件的lib /目录中,但是Undertow似乎并没有意识到这一点,因此我有所不同错误),我正在寻找替代产品。

我的理解是,我只需要使用户通过Web层进行身份验证即可,本质上可以替代WebAuthenticationWebAuthentication.login的唯一用途是上述代码示例中提到的两行。

我可以用WebAuthentication代替什么来完成这项工作?

很显然,简单的类替换会很棒,但是如果它必须比这更复杂,那么只要我们能够使它起作用,就这样吧。

1 个答案:

答案 0 :(得分:0)

通常,用户管理不受JEE规范的限制,因此每个供应商都以不同的方式进行操作。查看JBoss / Wildfly内置的DatabaseServerLoginModule文档。如果这还不够(我不喜欢它使用的表布局),那么另一种方法是编写自己的代码:

...

import org.jboss.security.SimpleGroup;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.auth.spi.UsernamePasswordLoginModule;

...

/**
 * Extends a WildFly specific class to implement a custom login module.
 * 
 * Note that this class is referenced in the standalone.xml in a 
 * security-domain/authentication/login-module section.  If the package or name
 * changes then that needs to be updated too.
 * 
 */
public class MyLoginModule extends UsernamePasswordLoginModule {
    private MyPrincipal principal;

    @Override
    public void initialize(Subject subject, CallbackHandler callbackHandler,
            Map<String, ?> sharedState, Map<String, ?> options) {

        super.initialize(subject, callbackHandler, sharedState, options);
    }

    /**
     * While we have to override this method the validatePassword method ignores
     * the value.
     */
    @Override
    protected String getUsersPassword() throws LoginException {
        return null;
    }

    /**
     * Validates the password passed in (inputPassword) for the given username.
     */
    @Override
    protected boolean validatePassword(String inputPassword, String expectedPassword) {
        // validate as you do today - IGNORE "expectedPassword"
    }

    /**
     * Get the roles that are tied to the user.
     */
    @Override
    protected Group[] getRoleSets() throws LoginException {
        SimpleGroup group = new SimpleGroup("Roles");

        List<String> userRoles = // get roles for a user the way you do currently

        for( String nextRoleName: userRoles ) {
            group.addMember(new SimplePrincipal(nextRoleName));
        }

        return new Group[] { group };
    }

    /**
     * This method is what ends up triggering the other methods.
     */
    @Override
    public boolean login() throws LoginException {
        boolean login;

        login = super.login();
        if (login) {
            principal = // populate the principal

        return login;
    }

    @Override
    protected Principal getIdentity() {
        return principal != null ? principal : super.getIdentity();
    }
}

这使您更接近标准JEE安全性。如果不允许您的方法,甚至不会被调用(基于security-constraint中的web.xml节),并且您不必验证用户是否已登录。

起初有点令人生畏,但一旦奏效就很简单。

说了这么多,我此后就删除了这样的代码并移至Keycloak。这是一个单独的授权引擎,也与Tomcat集成在一起。它具有社交登录等众多功能。