使用Worklight进行LTPA身份验证

时间:2014-09-02 16:34:16

标签: ibm-mobilefirst worklight-server worklight-security ltpa

我正在尝试从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:

Browser 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;
}])

1 个答案:

答案 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