Facing issues while integrating Mobilefirst CLI 7.1 with ldap - authentication

I am using mobile first CLI 7.1 and trying to integrate with the LDAP.
I am following this document to implement. I am getting 401 error (Failed to load resource: the server responded with a status of 401 (Unauthorized)) when loading the application for first time in the browser. I am getting 500 error(POST http://localhost:10080/Project/apps/services/j_security_check 500 (Internal Server Error)) when I try to logging in. I have uncommented wl.client.connect and gone through the following conversations at stackoverflow. Link1, link2 and link3
Server Logs
[ERROR ] SESN0008E: A user authenticated as anonymous has attempted to access a session owned by user:BasicRegistry/admin.
[ERROR ] SESN0008E: A user authenticated as anonymous has attempted to access a session owned by user:BasicRegistry/admin.
[ERROR ] SESN0008E: A user authenticated as anonymous has attempted to access a session owned by user:BasicRegistry/admin.
[ERROR ] SESN0008E: A user authenticated as anonymous has attempted to access a session owned by user:BasicRegistry/admin.
What is my scenario?
User is initially taken to login page and later when he clicks on login I will collect the details and automatically set to j_secutity_form when it throws challenge and submit. I am getting 401 when I open the application and getting 500 when I click on login. which calls
var reqURL = '/j_security_check';
var options = {};
options.parameters = {
j_username : loginData.email,
j_password : loginData.password
};
options.headers = {};
ldapRealmChallengeHandler.submitLoginForm(reqURL, options,ldapRealmChallengeHandler.submitLoginFormCallback);
I have following questions:
1) Is the documentation that I am following is complete or it needs some additions thing that need to be done ?
2) What is the cause for getting blocked with the above errors
And here is my code:
var ldapRealmChallengeHandler = WL.Client.createChallengeHandler("LDAPRealm");
ldapRealmChallengeHandler.isCustomResponse = function(response) {
if (!response || response.responseText === null) {
return false;
}
var indicatorIdx = response.responseText.search('j_security_check');
if (indicatorIdx >= 0){
return true;
}
return false;
};
ldapRealmChallengeHandler.handleChallenge = function(response){
};
ldapRealmChallengeHandler.submitLoginFormCallback = function(response) {
var isLoginFormResponse = ldapRealmChallengeHandler.isCustomResponse(response);
if (isLoginFormResponse){
ldapRealmChallengeHandler.handleChallenge(response);
}
else {
ldapRealmChallengeHandler.submitSuccess();
}
};
logout = function(){
WL.Client.logout('LDAPRealm',{});
}

I think this might be related to session independence mode which is turned ON by default as of MFP 7.1. I think this might explain why you are getting the SESN0008E error. Here is a link to an article that explains how to disable session independence.
There is more information on the SESN0008E error here.
Please let me know how you get on.

Related

Invalid CSRF when logging in to keystone

I'm entirely new to coding. I've looked around a bit, but not found anything relevant.
When logging into keystone to view our mongoDB database I get an error message saying:
Something went wrong; please refresh your browser and try again.
Doing that does not help. Neither does deleting the browser history or attempting from another lap top.
Looking at the javascript console in the browser, the error states invalid csrf.
I think this is the relevant source code in the keystone folder:
handleSubmit (e) {
e.preventDefault();
// If either password or mail are missing, show an error
if (!this.state.email || !this.state.password) {
return this.displayError('Please enter an email address and password to sign in.');
}
xhr({
url: `${Keystone.adminPath}/api/session/signin`,
method: 'post',
json: {
email: this.state.email,
password: this.state.password,
},
headers: assign({}, Keystone.csrf.header),
}, (err, resp, body) => {
if (err || body && body.error) {
return body.error === 'invalid csrf'
? this.displayError('Something went wrong; please refresh your browser and try again.')
: this.displayError('The email and password you entered are not valid.');
} else {
// Redirect to where we came from or to the default admin path
if (Keystone.redirect) {
top.location.href = Keystone.redirect;
} else {
top.location.href = this.props.from ? this.props.from : Keystone.adminPath;
}
}
});
},
How can I go about solving this / debugging the error? Thanks for any help!
This usually happens when session affinity fails. Are you using default in-memory session management? Maybe, try using a database for maintaining session state.
If you use MongoDB, Try the following config setting
'session store': 'mongo',
See 'session store' section under http://keystonejs.com/docs/configuration/#options-database for more details.

MFPPush.registerDevice wrapped by obtainAccessToken failed

I'm trying to run MFP8's push sample app of GitHub. But MFPPush.registerDevice method failed and error message "Failed to register device:" was shown.
function registerDevice() {
WLAuthorizationManager.obtainAccessToken("push.mobileclient").then(
MFPPush.registerDevice(
null,
function(successResponse) {
navigator.notification.alert("Successfully registered");
enableButtons();
},
function(failureResponse) {
navigator.notification.alert("Failed to register");
console.log("Failed to register device:" +
JSON.stringify(failureResponse));
}
)
);
}
I read the MFP8 document and found the note below.
Note: Authenticated notifications are currently not supported in Cordova applications due to a defect. However a workaround is provided: each MFPPush API call can be wrapped by WLAuthorizationManager.obtainAccessToken("push.mobileclient").then( ... );. The provided sample application uses this workround.
The sample code is wrapped by WLAuthorizationManager.obtainAccessToken indeed. But I think MFPPush.registerDevice may be called before 'obtainAccessToken' completes because return value of MFPPush.registerDevice's method is specified as Promise.then() parameter instead of function that call MFPPush.registerDevice.
So I think the sample should be written as bellow,
function registerDevice() {
WLAuthorizationManager.obtainAccessToken("push.mobileclient").then(
function() {
MFPPush.registerDevice(
null,
function(successResponse) {
navigator.notification.alert("Successfully registered");
enableButtons();
},
function(failureResponse) {
navigator.notification.alert("Failed to register");
console.log("Failed to register device:" +
JSON.stringify(failureResponse));
}
)
);
}
}
Could anyone give me some advice about that?
There is additional information. In device log these messages were logged.
Of course, I registered UserLogin security check to MobileFirst Server and UserLogin challengeHandler is created in UserLoginChallengeHandler.js
(I have not changed except bundleId)
2018-02-10 19:42:47.271015+0900 PushNotificationsCordova[1273:1500711] Failed to register device:"Error Domain=com.ibm.mfp.push Code=5 \"Error authenticating client. Error is 'Challenge handler does not exist. There is no registered challenge handler with key UserLogin'.\" UserInfo={networkMetadata={\n \"$bytesSent\" = 120;\n \"$category\" = network;\n \"$outboundTimestamp\" = 1518259366869;\n \"$path\" = \"http://192.168.0.105:9080/mfp/api/preauth/v1/preauthorize\";\n \"$requestMethod\" = POST;\n \"$trackingid\" = \"F8FD4A96-B046-4DAD-87F6-7441E8426C2E\";\n}, NSLocalizedDescription=Error authenticating client. Error is 'Challenge handler does not exist. There is no registered challenge handler with key UserLogin'.}"

What should I consider when I am doing an authentication process with a titanium app?

Hello it's my first time doing a sign in process in a mobile app with Titanium and I wonder what information should I save and the best practice to do it?
My server is configured in this way:
The server requires I send a user and password and if the information match it will provide a token session.
This is the code I use for signing in:
function signIn(e) {
//function to use HTTP to connect to a web server and transfer the data.
var sendit = Ti.Network.createHTTPClient({
onerror : function(e) {
Ti.API.debug(e.error);
alert('There was an error during the connection');
},
timeout : 100000,
});
//Here you have to change it for your local ip
sendit.open('POST', 'http://myserver');
var params = {
user : $.txtUsuario.value,
password : $.txtPassword.value
};
sendit.send(params);
//Function to be called upon a successful response
sendit.onload = function() {
var json = this.responseText;
var response = JSON.parse(json);
if (response.success == "true")
{
var landing = Alloy.createController("menu").getView();
$.index.close();
landing.open();
}
else
{
alert(response);
}
};
};
the code above is working, however I do not know how to manage the sign out. I would like my application works like the most apps do, e.g:
You sign in once and after that if you do not close the app you are able to continues using it and even making a request.
Thank you for any explanation.
It depends on your app requirements. for exemple if you will use the token in your app later you can save it as an AppProperty :
Ti.App.Properties.setString('token',yourTokenGoHere);
and in the app starting you can get it back :
var myToken = Ti.App.Properties.getString('token');
and then you can make a test for example if the token is still valid or not :
if(myToken === 'invalidtoken')
youSholdLogin();
else
youCanGoFurther();
and when the user disconnect rest the token to be invalid :
Ti.App.Properties.setString('token', 'invalidtoken');

400 Bad Request when doing a Parse Unity cloud call to user.logIn in Parse.Cloud.Define

When trying to define a Parse Cloud Code server side function to handle login I get 400 Bad Request when I try to call it. When I look at the Parse logs it records the error "Failed with: ReferenceError: user is not defined". But the user is definitely defined!
Below is the definition of the cloud code for LogIn:
Parse.Cloud.define("LogIn", function(request, response)
{
user.logIn(request.params.username, request.params.password,
{
success: function(user)
{
response.success(
{
"success": "Log in successful."
});
},
error: function(user, error)
{
// We must respond with a success in order to access the
// result of the request inside Unity.
response.success(
{
"error": "Log in failed.",
"code": error.code,
"message": error.message
});
}
});
});
From Unity I make this call to the LogIn coud code function:
ParseCloud.CallFunctionAsync<Dictionary<string, object>> ("LogIn", userInfo).ContinueWith (t =>
{
etc.....
}
I get the following error logged in the server side Parse logs when I call the above from Unity using user sashas123 and also student123:
E2014-09-26T17:06:18.001Z] v8: Ran cloud function LogIn with: Input:
{"username":"sashas123","password":"test"} Failed with:
ReferenceError: user is not defined
at main.js:43:5
E2014-09-26T17:38:50.474Z] v10: Ran cloud function LogIn with:
Input: {"username":"student123","password":"test"} Failed with:
ReferenceError: user is not defined
at main.js:43:5
The following snapshot from the Data Browser shows that the above users are definitely defined:
![Parse User class][1]
Is there any issue with calling user.LogIn on the server side through Cloud Code or is this a Unity issue?
It looks like user.logIn should be request.user.logIn :)
I find it's best to handle the case where the function may be called without a logged in user too:
if (request.user.logIn != null)
{
...
}
else
{
response.error("This function must be called with a logged in user!");
}
Hope this help!

FB.login returns Invalid OAuth access token

I've been developing an app for the past few weeks and up until now there have been no issues. Just a couple days ago a strange bug has started occurring:
My application uses the PHP SDK and implements the Javascript SDK for user authorization. The user is allowed to roam the application freely, but when they click on a video, FB.login is called to request permissions from the user and get an access token.
jQuery Code
FB.login(function(response) {
if (response.authResponse) {
//Set global vars
fb_uid = response.authResponse.userID;
fb_token = response.authResponse.accessToken;
//If user has already authorized the app
if (response.status === 'connected') {
//Create the user record
$.ajax(site_url + '/facebook/create_fb_user', {
type: 'POST',
dataType: 'json',
data: {fb_uid: fb_uid, token: fb_token},
success: function (data) {
user = data.resp.fb_user;
viewVideo(item);
}
});
};
};
}, {scope: "publish_stream"});
PHP Code
try {
$this->_fb->setAccessToken($this->request->post('token'));
$data = $this->_fb->api("/me");
$model = new Model_Fbuser;
$model->data = array(
'fb_uid' => $data['id'],
'fb_token' => $extended_token
);
$resp = $model->update();
return $this->render_json(array(
'success' => TRUE,
'resp' => $resp
));
} catch (Exception $e) {
return $this->render_json(array(
'success' => FALSE,
'error' => $e->getMessage(),
'token' => $this->request->post('token')
));
}
The first time the user does this, the FB.login call returns a valid access token, the PHP SDK is able to set the token, and everything works as expected.
However, should the user revoke the application's access in their App Settings, and then return to the application, they are presented with the FB.login once more, but this time, the call returns the same access token they were previously given, which has already had its access revoked. Trying to set the access token with the PHP SDK throws the exception: "Invalid OAuth access token."
Yet if I then check the token in the Facebook debugger, is says it is valid.
Edit:
Further investigation reveals that the user is issues the same access token every time in the same session. If the user logs out, then logs back in, then they will receive a new valid token. But if they try to get a new token without logging out first, Facebook reissues them the same invalid one. When trying to use this access token to query information about the user, this is the response:
{"error":{"type":"OAuthException","message":"Error validating access token: The session was invalidated explicitly using an API call."}}
If you get the "Invalid OAuth access token" error in this way, I usually call FB.logout() and then immediately call FB.login() in the callback.
FB.logout(function(response) {
// user is now logged out
FB.login(...)
});
Not ideal, but the best way to fix such a use-case.