使用基于适配器的身份验证实现时,无法实现基于用户订阅的推送通知

时间:2015-09-11 13:15:24

标签: authentication push-notification ibm-mobilefirst

我已经定义了基于适配器的身份验证。

执行可成功运行的自定义安全测试。

但是当我想实现基于用户订阅的推送通知并在authenticationConfig.xml中添加移动安全测试时,我面临很多问题。

因为我正在尝试在Android设备中部署应用程序和测试。我还在application-descriptor.xml的android标签中包含了移动安全测试。但是在此之后面对很多问题来部署适配器本身。

请参阅以下我正在使用的代码段

authenticationConfig.xml

    <mobileSecurityTest name="MST1">
        <testUser realm="AdapterAuthRealm"/>
        <testDeviceId provisioningType="none"/>
    </mobileSecurityTest>

    <webSecurityTest name="WST1">
        <testUser realm="AdapterAuthRealm"/>
    </webSecurityTest>

    <customSecurityTest name="Master-Password">
        <test realm="AdapterAuthRealm" isInternalUserID="true"/>
    </customSecurityTest>

身份验证运行正常,直到我只定义了customSecurityTest。

添加网络和移动安全测试后,当我提供凭据并且既没有从GUI端也没有从控制台日志端点击登录时,没有响应。

我还在application-descriptor.xml中的android标签中添加了安全性测试,如下所示

<android securityTest="MST1" version="1.0"> 
    <worklightSettings include="false"/>        
    <pushSender key="xxxxxxxxxxx" senderId="xxxxxxxxxxxxxxx"/>

    <security>
        <encryptWebResources enabled="false"/>
        <testWebResourcesChecksum enabled="false" ignoreFileExtensions="png, jpg, jpeg, gif, mp4, mp3"/>
        <publicSigningKey/>
        <packageName/>
    </security>
</android>

更准确。让我添加以下代码片段,该代码片段来自IBM MobileFirst Platform Foundation示例。

PushAdapter-impl.js

function wlCommonInit() {
    WL.Client.connect({onSuccess: connectSuccess, onFailure: connectFailure});
}

function connectSuccess() {
    WL.Logger.debug ("Successfully connected to MobileFirst Server.");
}

function connectFailure() {
    WL.Logger.debug ("Failed connecting to MobileFirst Server.");
    WL.SimpleDialog.show("Push Notifications", "Failed connecting to MobileFirst Server. Try again later.", 
            [{
                text : 'Reload',
                handler : WL.Client.reloadapp
            },
            {
                text: 'Close',
                handler : function() {}
            }]
        );
}

function isPushSupported() {
    var isSupported = false;
    if (WL.Client.Push){
        isSupported = WL.Client.Push.isPushSupported();
    }   
    alert(isSupported);
}

function isPushSubscribed() {
    var isSubscribed = false;
    if (WL.Client.Push){
        isSubscribed = WL.Client.Push.isSubscribed('myPush');
    }
    alert(isSubscribed);
}

//---------------------------- Set up push notifications -------------------------------
if (WL.Client.Push) {   
    WL.Client.Push.onReadyToSubscribe = function() {
        alert("onReadyToSubscribe");

        $('#SubscribeButton').removeAttr('disabled');
        $('#UnsubscribeButton').removeAttr('disabled');

        WL.Client.Push.registerEventSourceCallback(
            "myPush", 
            "PushAdapter", 
            "PushEventSource", 
            pushNotificationReceived);
    };
}

// --------------------------------- Subscribe ------------------------------------
function doSubscribe() {
    WL.Client.Push.subscribe("myPush", {
        onSuccess: doSubscribeSuccess,
        onFailure: doSubscribeFailure
    });
}

function doSubscribeSuccess() {
    alert("doSubscribeSuccess");
}

function doSubscribeFailure() {
    alert("doSubscribeFailure");
}

//------------------------------- Unsubscribe ---------------------------------------
function doUnsubscribe() {
    WL.Client.Push.unsubscribe("myPush", {
        onSuccess: doUnsubscribeSuccess,
        onFailure: doUnsubscribeFailure
    });
}

function doUnsubscribeSuccess() {
    alert("doUnsubscribeSuccess");
}

function doUnsubscribeFailure() {
    alert("doUnsubscribeFailure");
}

//------------------------------- Handle received notification ---------------------------------------
function pushNotificationReceived(props, payload) {
    alert("pushNotificationReceived invoked");
    alert("props :: " + JSON.stringify(props));
    alert("payload :: " + JSON.stringify(payload));
}

authenticationConfig.xml

<securityTests>
    <webSecurityTest name="PushApplication-web-securityTest">
        <testUser realm="PushAppRealm"/>
    </webSecurityTest>
    <mobileSecurityTest name="PushApplication-strong-mobile-securityTest">
        <testUser realm="PushAppRealm"/>
        <testDeviceId provisioningType="none"/>
    </mobileSecurityTest>
    <customSecurityTest name="SubscribeServlet">
        <test realm="wl_directUpdateRealm" step="1"/>
        <test isInternalUserID="true" realm="SubscribeServlet"/>
    </customSecurityTest>
</securityTests>      

<realms>
    <realm loginModule="PushAppLoginModule" name="PushAppRealm">
         <className>
              com.worklight.core.auth.ext.FormBasedAuthenticator
         </className>                   
    </realm>
</realms>


<loginModule name="PushAppLoginModule">
        <className>com.worklight.core.auth.ext.NonValidatingLoginModule</className>
    </loginModule>

我们可以看到他们正在使用基于表单的Authenticator方法。如果可以使用基于适配器的身份验证来实现,请告诉我这个概念。如果您为上述推送通知实现提供基于适配器的身份验证,那将非常有用。

1 个答案:

答案 0 :(得分:2)

您可以使用基于适配器的身份验证器实现事件源推送通知。我采用了事件源推送通知示例,并将基于适配器的身份验证示例集成到其中。 您需要做的就是添加以下更改以调整样本:

<强> authenticationConfig.xml

添加安全测试,领域和登录模块:

<mobileSecurityTest name="PushSecurityTest">
    <testUser realm="AuthRealm" />
    <testDeviceId provisioningType="none" />
</mobileSecurityTest>

<realm loginModule="AuthLoginModule" name="AuthRealm">
    <className>com.worklight.integration.auth.AdapterAuthenticator</className>
    <parameter name="login-function" value="PushAdapter.onAuthRequired" />
    <parameter name="logout-function" value="PushAdapter.onLogout" />
</realm>

<loginModule name="AuthLoginModule">
    <className>com.worklight.core.auth.ext.NonValidatingLoginModule</className>
</loginModule>

<强> PushAppRealmChallengeHandler.js

更改质询处理程序方法:

var pushAppRealmChallengeHandler = WL.Client.createChallengeHandler("AuthRealm");

pushAppRealmChallengeHandler.isCustomResponse = function(response) {
    if (!response || !response.responseJSON || response.responseText === null) {
        return false;
    }
    if (typeof(response.responseJSON.authRequired) !== 'undefined'){
        return true;
    } else {
        return false;
    }
};

pushAppRealmChallengeHandler.handleChallenge = function(response) {
    var authRequired = response.responseJSON.authRequired;

    if (authRequired == true){
        $("#AppBody").hide();
        $("#AuthBody").show();
        $('#passwordInputField').val('');

        if (response.responseJSON.errorMessage)
            alert(response.responseJSON.errorMessage);

    } else if (authRequired == false){
        $("#AppBody").show();
        $("#AuthBody").hide();
        pushAppRealmChallengeHandler.submitSuccess();
    }

};



$('#loginButton').bind('click', function () {
    var username = $("#usernameInputField").val();
    var password = $("#passwordInputField").val();

    var invocationData = {
        adapter : "PushAdapter",
        procedure : "submitAuthentication",
        parameters : [ username, password ]
    };

    pushAppRealmChallengeHandler.submitAdapterAuthentication(invocationData, {});

});

我选择将适配器程序添加到现有程序中(您还可以添加另一个程序):

<强> PushAdapter.xml

添加submitAuthentication过程:

<procedure name="submitAuthentication" securityTest="wl_unprotected" />

<强> PushAdapter-impl.js

添加以下程序:

function onAuthRequired(headers, errorMessage){
    errorMessage = errorMessage ? errorMessage : null;

    return {
        authRequired: true,
        errorMessage: errorMessage
    };
}

function submitAuthentication(username, password){
    if (username==="user" && password === "password"){

        var userIdentity = {
                userId: username,
                displayName: username, 
                attributes: {
                    foo: "bar"
                }
        };

        WL.Server.setActiveUser("AuthRealm", userIdentity);

        return { 
            authRequired: false 
        };
    }

    return onAuthRequired(null, "Invalid login credentials");
}

function getSecretData(){
    return {
        secretData: "Very very very very secret data"
    };
}

function onLogout(){
    WL.Logger.debug("Logged out");
}

注意:我的代码示例基于Getting Started 7.1示例。如果您使用其他MobileFirst版本,只需相应更改名称即可。