Undertow 是否具有相当于 Tomcat Web 身份验证的 Web 层身份验证?
Does Undertow have an equivalent to Tomcat WebAuthentication for authenticating in web tier?
这可能是一个 "XY problem" 问题的实例;如果是,请随时通过更正我的假设来回答。
更新:有一次,我曾尝试通过 loginRequest.login(username, password);
来使用 HttpServletRequest
,但这不会编译,产生有关 login(String, String)
not being found in HttpServletRequest
,所以我放弃了那个角度。然而,我刚刚找到了一个article which suggests that this is the correct change to make,所以我又回到了那条路上。
有人告诉我,也许我使用的是 class 的旧版本。我的编译时 class 路径上可能有旧的 HttpServletRequest
。我现在正在调查。
从Tomcat(在JBoss 5)切换到Undertow(在JBoss 7)后,我们的用户认证页面坏了。
我们有一个 HttpServlet
,它曾经在 Tomcat 网络服务器 JBoss 中 运行 5。因此,它使用 Tomcat 的 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);
// ...
}
}
使用 WebAuthentication
之前的评论,即关于使用 Web 层进行身份验证的评论,不是我添加的。那是在原始代码中,看起来是关于为什么选择 WebAuthentication
作为身份验证机制的解释。
我的理解是 Undertow/JBoss7 不再有 WebAuthentication
class 可用。
在 运行 时间,当用户提交他们的 name/password 条目时,有一个 ClassNotFoundException
和消息 org.jboss.web.tomcat.security.login.WebAuthentication from [module "deployment.myproject.ear.viewers.war" from Service Module Loader]
现在我们无法再访问 WebAuthentication
(我什至从 Tomcat 复制了包含必要 class 的 jar 文件到我的 .ear 文件的 lib/ 目录中,但是Undertow 似乎不理解这一点,我遇到了不同的错误),我正在寻找替代品。
我的理解是我只需要让用户通过网络层进行身份验证,本质上是 WebAuthentication.login
的替代品。 WebAuthentication
的唯一用途是上面代码示例中提到的两行。
我可以用什么替换 WebAuthentication
来完成这项工作?
显然,一个简单的 class 替换会很棒,但如果它必须比这更复杂,那么只要我们能够让它工作就可以了。
一般来说,用户管理被排除在 JEE 规范之外,因此每个供应商都以不同的方式进行管理。查看 JBoss/Wildfly 中内置的 DatabaseServerLoginModule 的文档。如果这还不够(而且我不喜欢它使用的 table 布局)另一种方法是编写您自己的布局:
...
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 安全性。如果不允许(基于 web.xml
中的 security-constraint
节),您的方法甚至不会被调用,并且您不必验证用户是否已登录。
起初有点令人生畏,但一旦开始工作就非常简单。
说了这么多,我已经删除了这样的代码并移至 Keycloak。这是一个单独的授权引擎,也与 Tomcat 集成。它具有大量功能,例如社交登录等。
这可能是一个 "XY problem" 问题的实例;如果是,请随时通过更正我的假设来回答。
更新:有一次,我曾尝试通过 loginRequest.login(username, password);
来使用 HttpServletRequest
,但这不会编译,产生有关 login(String, String)
not being found in HttpServletRequest
,所以我放弃了那个角度。然而,我刚刚找到了一个article which suggests that this is the correct change to make,所以我又回到了那条路上。
有人告诉我,也许我使用的是 class 的旧版本。我的编译时 class 路径上可能有旧的 HttpServletRequest
。我现在正在调查。
从Tomcat(在JBoss 5)切换到Undertow(在JBoss 7)后,我们的用户认证页面坏了。
我们有一个 HttpServlet
,它曾经在 Tomcat 网络服务器 JBoss 中 运行 5。因此,它使用 Tomcat 的 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);
// ...
}
}
使用 WebAuthentication
之前的评论,即关于使用 Web 层进行身份验证的评论,不是我添加的。那是在原始代码中,看起来是关于为什么选择 WebAuthentication
作为身份验证机制的解释。
我的理解是 Undertow/JBoss7 不再有 WebAuthentication
class 可用。
在 运行 时间,当用户提交他们的 name/password 条目时,有一个 ClassNotFoundException
和消息 org.jboss.web.tomcat.security.login.WebAuthentication from [module "deployment.myproject.ear.viewers.war" from Service Module Loader]
现在我们无法再访问 WebAuthentication
(我什至从 Tomcat 复制了包含必要 class 的 jar 文件到我的 .ear 文件的 lib/ 目录中,但是Undertow 似乎不理解这一点,我遇到了不同的错误),我正在寻找替代品。
我的理解是我只需要让用户通过网络层进行身份验证,本质上是 WebAuthentication.login
的替代品。 WebAuthentication
的唯一用途是上面代码示例中提到的两行。
我可以用什么替换 WebAuthentication
来完成这项工作?
显然,一个简单的 class 替换会很棒,但如果它必须比这更复杂,那么只要我们能够让它工作就可以了。
一般来说,用户管理被排除在 JEE 规范之外,因此每个供应商都以不同的方式进行管理。查看 JBoss/Wildfly 中内置的 DatabaseServerLoginModule 的文档。如果这还不够(而且我不喜欢它使用的 table 布局)另一种方法是编写您自己的布局:
...
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 安全性。如果不允许(基于 web.xml
中的 security-constraint
节),您的方法甚至不会被调用,并且您不必验证用户是否已登录。
起初有点令人生畏,但一旦开始工作就非常简单。
说了这么多,我已经删除了这样的代码并移至 Keycloak。这是一个单独的授权引擎,也与 Tomcat 集成。它具有大量功能,例如社交登录等。