gpt4 book ai didi

jakarta-ee - Java Web 应用程序 : Using a custom realm

转载 作者:行者123 更新时间:2023-12-03 23:34:42 26 4
gpt4 key购买 nike

我正在编写一个需要通过 web 服务执行登录的 java web 应用程序。当然,我正在使用的应用程序服务器(glassfish v2)提供的任何领域都不能解决问题。因此我不得不自己写。然而,我编写的领域实现似乎完全与 glassfish 相关联,不能在任何其他应用程序服务器中使用。

是否有任何标准或广泛支持的方式来实现自定义领域?是否可以以任何方式从 .war 部署该领域,或者它是否总是需要从服务器自己的类路径中加载?

最佳答案

注意:下面的答案仅对 Java EE 5 有效。正如在其他答案之一中引起我注意的那样,Java EE 6 确实支持这一点。因此,如果您使用的是 Java EE 6,请不要阅读此答案,而应阅读其他相关答案。

根据我自己的研究和对这个问题的回答,我找到了以下答案:虽然 JAAS 是一个标准接口(interface),但在各种应用服务器中编写、部署和集成 JAAS Realm + LoginModule 并没有统一的方法。

Glassfish v2 要求您扩展它自己的一些实现 LoginModule 或 Realm 的内部类。但是,您不能自定义整个登录过程,因为 LoginModule 接口(interface)的许多方法在 Glassfish 的父类(super class)中都标记为 final。自定义 LoginModule 和 Realm 类必须放在 AS 类路径中(不是应用程序的),并且必须手动注册领域(不能从 .war 部署)。

Tomcat 的情况似乎要好一些,它可以让您完全编写自己的 Realm 和 LoginModule,然后使用自己的 JAASRealm 将它们配置到应用程序服务器中(这会将实际工作委托(delegate)给您的 Realm 和 LoginModule 的实现) .但是,即使是 tomcat 也不允许从您的 .war 部署您的自定义领域。

请注意,显示我的结果的应用程序服务器似乎都不能充分利用所有 JAAS 回调。它们似乎都只支持基本的用户名+密码方案。如果您需要比这更复杂的东西,那么您将需要找到一个不受 Java EE 容器管理的解决方案。

作为引用,并且因为在我的问题的评论中被要求,这是我为 GlassfishV2 编写的代码。

首先,这是 Realm 的实现:

public class WebserviceRealm extends AppservRealm {

private static final Logger log = Logger.getLogger(WebserviceRealm.class.getName());

private String jaasCtxName;
private String hostName;
private int port;
private String uri;

@Override
protected void init(Properties props) throws BadRealmException, NoSuchRealmException {
_logger.info("My Webservice Realm : init()");

// read the configuration properties from the user-supplied properties,
// use reasonable default values if not present
this.jaasCtxName = props.getProperty("jaas-context", "myWebserviceRealm");
this.hostName = props.getProperty("hostName", "localhost");
this.uri = props.getProperty("uri", "/myws/EPS");

this.port = 8181;
String configPort = props.getProperty("port");
if(configPort != null){
try{
this.port = Integer.parseInt(configPort);
}catch(NumberFormatException nfe){
log.warning("Illegal port number: " + configPort + ", using default port (8181) instead");
}
}
}

@Override
public String getJAASContext() {
return jaasCtxName;
}

public Enumeration getGroupNames(String string) throws InvalidOperationException, NoSuchUserException {
List groupNames = new LinkedList();
return (Enumeration) groupNames;
}

public String getAuthType() {
return "My Webservice Realm";
}

public String getHostName() {
return hostName;
}

public int getPort() {
return port;
}

public String getUri() {
return uri;
}
}

然后是 LoginModule 实现:
public class WebserviceLoginModule extends AppservPasswordLoginModule {

// all variables starting with _ are supplied by the superclass, and must be filled
// in appropriately

@Override
protected void authenticateUser() throws LoginException {
if (_username == null || _password == null) {
throw new LoginException("username and password cannot be null");
}

String[] groups = this.getWebserviceClient().login(_username, _password);

// must be called as last operation of the login method
this.commitUserAuthentication(groups);
}

@Override
public boolean commit() throws LoginException {
if (!_succeeded) {
return false;
}

// fetch some more information through the webservice...

return super.commit();
}

private WebserviceClient getWebserviceClient(){
return theWebserviceClient;
}
}

最后,在 Realm 中必须绑定(bind)到 LoginModule。这是在 JAAS 配置文件级别完成的,在 glassfish v2 中位于 yourDomain/config/login.conf 中。在该文件的末尾添加以下行:
myWebserviceRealm { // use whatever String is returned from you realm's getJAASContext() method
my.auth.login.WebserviceLoginModule required;
};

这就是让我在 glassfish 上工作的原因。同样,该解决方案不能跨应用服务器移植,但据我所知,没有现成的可移植解决方案。

关于jakarta-ee - Java Web 应用程序 : Using a custom realm,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/719708/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com