我正在尝试从AdapterAuthentication迁移到使用LTPA将userRegistry推迟到Websphere容器。
我已按照入门配置here,Stack Overflow here进行操作。我认为选项2是来自this documentation的正确方法。
我已经建立了一个独立的基于Liberty配置文件的工作灯实例(使用6.2)。我已经修改了authenticationConfig.xml以使用LTPA:
<customSecurityTest name="LTPASecurityTest">
<test realm="wl_directUpdateRealm" step="1" />
<test realm="WASLTPARealm" isInternalUserID="true" />
</customSecurityTest>
<realm name="WASLTPARealm" loginModule="WASLTPAModule">
<className>
com.worklight.core.auth.ext.WebSphereFormBasedAuthenticator</className>
<parameter name="login-page" value="conf/login.html" />
<parameter name="error-page" value="conf/loginError.html" />
</realm>
<loginModule name="WASLTPAModule">
<className>
com.worklight.core.auth.ext.WebSphereLoginModule</className>
</loginModule>
我已经确认(并重建).war,在根级别和conf /目录下都有login.html和loginError.html。 (文档here“必须将这些HTML文件添加到Worklight Server WAR文件的根目录中”真的需要告诉用户如何在Worklight Studio中执行此操作“
我已经修改了适配器以使用LTPA领域:
<procedure name="profile" securityTest="LTPASecurityTest"> </procedure>
我根据文档修改了Liberty Profile的server.xml以添加appSecurity(截图仅描述了如何从Websphere Console执行此操作),以及绑定到ldapRegistry
<feature>appSecurity-2.0</feature>
<feature>ldapRegistry-3.0</feature>
但是,从服务器日志开始,当客户端启动应用程序时,会报告40多个堆栈跟踪实例。从客户端看,好像连接到Worklight的初始调用被拒绝了。我认为这是因为他们没有LTPA令牌。
我的期望是,一旦服务器确定用户正在请求安全资源,就会发出挑战。看来,不是发出挑战,而是抛出WorkLightAuthenticationException。
我是否需要添加其他静态资源?是否有其他配置更改? Login.html永远不会返回给最终用户。
的console.log:
[ERROR ] FWLSE0059E: Login into realm 'WASLTPAModule' failed. null. [project postal]
com.worklight.server.auth.api.WorkLightAuthenticationException
[ERROR ] FWLSE0117E: Error code: 4, error description: AUTHENTICATION_ERROR, error message: An error occurred while performing authentication using loginModule WASLTPAModule, User Identity {wl_directUpdateRealm=null, SubscribeServlet=null, wl_authenticityRealm=null, AdapterAuthRealm=null, wl_remoteDisableRealm=null, wl_antiXSRFRealm=(name:q0a052t5g02f833ocv0o48e4sv, loginModule:WLAntiXSRFLoginModule), wl_deviceAutoProvisioningRealm=null, wl_deviceNoProvisioningRealm=null, myserver=(name:df680b07-3057-4339-8d94-96a050ff99ed, loginModule:WeakDummy), WASLTPARealm=null, wl_anonymousUserRealm=(name:df680b07-3057-4339-8d94-96a050ff99ed, loginModule:WeakDummy)}. [project XYZ] [project XYZ]
[ERROR ] SRVE0777E: Exception thrown by application class 'com.worklight.core.auth.impl.AuthenticationContext.checkAuthentication:548'
com.worklight.server.auth.api.WorkLightAuthenticationException
at com.worklight.core.auth.impl.AuthenticationContext.checkAuthentication(AuthenticationContext.java:548)
at com.worklight.core.auth.impl.AuthenticationContext.login(AuthenticationContext.java:701)
at com.worklight.core.auth.impl.AuthenticationServiceBean.login(AuthenticationServiceBean.java:120)
at com.worklight.gadgets.serving.handler.LoginOnDemandHandler.doPost(LoginOnDemandHandler.java:68)
at com.worklight.gadgets.serving.GadgetAPIServlet.doGetOrPost(GadgetAPIServlet.java:144)
at com.worklight.gadgets.serving.GadgetAPIServlet.doPost(GadgetAPIServlet.java:107)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1240)
at [internal classes]
at com.worklight.core.auth.impl.AuthenticationFilter$1.execute(AuthenticationFilter.java:204)
at com.worklight.core.auth.impl.AuthenticationServiceBean.accessResource(AuthenticationServiceBean.java:76)
at com.worklight.core.auth.impl.AuthenticationFilter.doFilter(AuthenticationFilter.java:208)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:194)
at [internal classes]
[ERROR ] FWLSE0020E: Ajax request exception: Environment identity is null or not proven for realm WASLTPARealm [project XYZ]
[ERROR ] FWLSE0117E: Error code: 1, error description: INTERNAL_ERROR, error message: FWLSE0069E: An internal error occurred during gadget request [project XYZ]Environment identity is null or not proven for realm WASLTPARealm, User Identity Not available. [project XYZ]
回答David / Simon提出的问题:
我正在显式调用wl.client.connect,因为应用程序正在加载(不使用connectOnStartup)但是截至目前我还没有等待onSuccess / onFailure。它在我积压的东西上补救;但我怀疑这适用于AdapterAuth,它应该适用于LTPA。
我开始使用AdapterAuth(它可以工作),切换到LDAPLoginModule(它可以工作);为了外化LDAP端点,我们正在切换LTPA。基于此;预先警告客户端代码比我想要的复杂一点。
这是客户端挑战处理程序。假设在应用程序启动后几乎立即触发worklight工厂代码;然后是适配器调用,后面会触发质询处理程序代码。
...
angular.module(
'XYZ',
[ 'ionic', 'XYZ.controllers', 'XYZ.services', 'worklight' ])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if (window.StatusBar) {
window.StatusBar.styleDefault();
}
});
})
.constant("authenticationRealm" , "WASLTPARealm");
// .constant("authenticationRealm" , "AdapterAuthRealm");
...
// Provide the Worklight object as an Angular service.
angular.module('worklight', [])
.factory('worklight', ['$window', function($window) {
//for unit testing, these aren't defined. only attempt to connect if we're in a worklight container
if (($window.WL)&& ($window.WL.Client)&&($window.WL.Client.connect)){
$window.WL.Client.connect();
}
return $window.WL;
}])
.factory('worklightAuthenticator', ['worklight', 'authenticationRealm', function(worklight, authenticationRealm){
var authenticator = {};
/* public apis */
authenticator.initLogin = function(){
worklight.Client.login(authenticationRealm);
};
authenticator.setAuthRequiredCallback = function(callback){
this.authRequiredCallback = callback;
};
authenticator.setLoginCompleteCallback = function(callback){
this.loginCompleteCallback = callback;
};
authenticator.setLoginCompleteCallback = function(callback){
this.loginCompleteCallback = callback;
};
// This will need to change as we get closer to USA
authenticator.getFriendlyRealmName= function(){
return (authenticationRealm !== "AdapterAuthRealm")? "Active Directory" : "local";
};
//Failing real abstraction going to assign functions based on what realm is defined
authenticator.submitLogin = (authenticationRealm !== "AdapterAuthRealm") ? function(username, password) {
var reqURL = '/j_security_check';
var options = {};
options.parameters = {
j_username : username,
j_password : password
};
options.headers = {};
authenticator.realmChallengeHandler.submitLoginForm(reqURL, options, authenticator.realmChallengeHandler.handleChallenge);
} : function(username, password) {
var options = {
parameters : [username, password],
adapter : "Security",
procedure : "submitAuthentication"
};
authenticator.realmChallengeHandler
.submitAdapterAuthentication(options, {onSuccess: function(r){window.alert(r);}, onFailure: function(z){console.log(z);}});
}
this._realmChallengeHandler = worklight.Client.createChallengeHandler(authenticationRealm);
this._submitLoginFormCallback = function(response){
var isLoginFormResponse = this._isCustomResponse(response);
if (isLoginFormResponse){
authenticator.handleChallenge(response);
} else {
authenticator.realmChallengeHandler.submitSuccess();
authenticator.loginCompleteCallback();
}
}
//Failing real abstraction going to assign functions based on what realm is defined
this._isCustomResponse = (authenticationRealm !== "AdapterAuthRealm") ? function(response) {
console.log("Challenge Required...", response);
var idx =response.responseText.indexOf("j_security_check") >= 0;
return idx;
} : function(response) {
console.log("Challenge Required...", response);
if (!response || !response.responseJSON || response.responseText === null) {
return false;
}
if (typeof (response.responseJSON.authRequired) !== 'undefined') {
return true;
} else {
return false;
}
} ;
//Failing real abstraction going to assign functions based on what realm is defined
this._handleChallenge = (authenticationRealm !== "AdapterAuthRealm") ? function(response) {
console.log("Handle Challenge", response);
var authRequired = response.responseText.indexOf("j_security_check") >= 0;
if (authRequired === true) {
authenticator.authRequiredCallback(response.responseText);
} else if (authRequired === false) {
console.log("Challenge Not Required");
authenticator.realmChallengeHandler.submitSuccess();
authenticator.loginCompleteCallback();
return false;
}
} : function(response) {
console.log("Handle Challenge", response);
var authRequired = response.responseJSON.authRequired;
if (authRequired === true) {
authenticator.authRequiredCallback(response.responseJSON);
} else if (authRequired === false) {
console.log("Challenge Not Required");
authenticator.realmChallengeHandler.submitSuccess();
authenticator.loginCompleteCallback();
return false;
}
};
this._realmChallengeHandler.isCustomResponse = this._isCustomResponse;
this._realmChallengeHandler.handleChallenge = this._handleChallenge;
this._realmChallengeHandler.submitLoginFormCallback = this._submitLoginFormCallback;
authenticator.realmChallengeHandler = this._realmChallengeHandler;
return authenticator;
}])
答案 0 :(得分:0)
您是否在客户端声明了ChallengeHandler?你使用connectOnStartup:true? WL.Client.connect?您能分享一下客户正在做什么的更多信息吗?
此网页https://pic.dhe.ibm.com/infocenter/wrklight/v6r1m0/index.jsp?topic=%2Fcom.ibm.worklight.deploy.doc%2Fadmin%2Fc_security_ltpa_overview.html描述了此处的流程,第二步“服务器要求用户登录,因为资源受到保护”是您在控制台日志中获取HTTP 401的位置。你能告诉我们这个阶段究竟是什么穿过电线吗?
有人想到,我注意到在您的安全测试的定义中,您将wl_directUpdateRealm标记为步骤1,但没有标记为WASLTPARealm的步骤。我不确定在这种情况下会发生什么,但您可以尝试在直接更新检查后将WASLTPARealm标记为一步:
<customSecurityTest name="LTPASecurityTest">
<test realm="wl_directUpdateRealm" step="1" />
<test realm="WASLTPARealm" isInternalUserID="true" step="2" />
</customSecurityTest>
或完全删除这些步骤(以便一切都在一步中完成),甚至在LTPA端工作之前甚至不使用直接更新。
-simon